Skip to content

uuuser-name/caam-account-switching

caam-account-switching - CAAM-based Codex account switcher

Release Go Version License Build Status

A maintained CAAM fork focused on reliable account switching for AI coding tools, with Codex/GPT Pro as the primary target. When usage pressure hits, switch accounts instead of waiting for re-auth or accepting broken continuity.

This repository keeps the upstream-compatible caam binary name, but it is not the canonical upstream CAAM repository. This fork is tuned for agent-flywheel users who need deterministic Codex handoff, explicit audit artifacts, and safer behavior around rate-limit recovery.

Use this repo if you want:

  • fast release-build account switching
  • Codex-specific config repair and prompt suppression
  • SmartRunner-based resume and handoff behavior
  • machine-readable status and audit outputs for agents

If you are using Codex, read docs/AGENT_INSTALL.md before first use.

curl -fsSL "https://raw.githubusercontent.com/uuuser-name/caam-account-switching/main/install.sh?$(date +%s)" | bash

Usage:

caam backup claude alice@gmail.com      # Save current auth
caam activate claude bob@gmail.com      # Switch instantly

🤖 Agent Quickstart (JSON)

Use --json in agent contexts. stdout = data, stderr = diagnostics, exit 0 = success.

# List available profiles (machine-readable)
caam ls --json

# Show current status for all tools
caam status --json

# Switch accounts
caam activate claude alice@gmail.com --json

Output conventions

  • stdout: machine-readable JSON only
  • stderr: diagnostics/logging
  • exit code 0: success

caam run currently does not expose --json; use it for runtime failover behavior, and use status/list/activate for machine-readable control flow.


📚 Documentation Map


The Problem

You're paying $200-275/month for fixed-cost AI coding subscriptions (Claude Max, GPT Pro, Gemini Ultra). These plans have usage limits—not billing caps, but rate limits that reset over time. When you hit them mid-flow, the official way to switch accounts:

/login → browser opens → sign out of Google → sign into different Google →
authorize app → wait for redirect → back to terminal

That's 30-60 seconds of friction. Multiply by 5+ switches per day across multiple tools.

The Solution

Each AI CLI stores OAuth tokens in plain files. caam backs them up and restores them:

caam activate claude bob@gmail.com   # ~50ms, done

No browser. No OAuth dance. No interruption to your flow state.


How It Works

flowchart LR
    subgraph System["Your System"]
        A["~/.claude.json"]
        B["~/.codex/auth.json"]
        C["~/.gemini/settings.json"]
    end

    subgraph Vault["~/.local/share/caam/vault/"]
        D["claude/alice@gmail.com/"]
        E["claude/bob@gmail.com/"]
        F["codex/work@company.com/"]
    end

    A <-->|"backup / activate"| D
    A <-->|"backup / activate"| E
    B <-->|"backup / activate"| F

    style System fill:#1a1a2e,stroke:#4a4a6a,color:#fff
    style Vault fill:#16213e,stroke:#4a4a6a,color:#fff
Loading

That's it. No external database servers (uses embedded SQLite), no required daemons (optional background service available). Just cp with extra steps.

Why This Works

OAuth tokens are bearer tokens—possession equals access. The CLI tools don't fingerprint your machine beyond what's already in the token file. Swapping files is equivalent to "being" that authenticated session.

Profile Detection

caam status uses content hashing to detect the active profile:

  1. SHA-256 hash current auth files
  2. Compare against all vault profiles
  3. Match = that's what's active

This means:

  • Profiles are detected even if you switched manually
  • No hidden state files that can desync
  • Works correctly after reboots

Two Operating Modes

1. Vault Profiles (Simple Switching)

Swap auth files in place. One account active at a time per tool. Instant switching.

caam backup claude work@company.com
caam activate claude personal@gmail.com

Use when: You want to switch between accounts sequentially (most common use case).

2. Isolated Profiles (Parallel Sessions)

Run multiple accounts simultaneously with full directory isolation.

caam profile add codex work@company.com
caam profile add codex personal@gmail.com
caam exec codex work@company.com -- "implement feature X"
caam exec codex personal@gmail.com -- "review code"

Each profile gets its own $HOME and $CODEX_HOME with symlinks to your real .ssh, .gitconfig, etc.

Use when: You need two accounts running at the same time in different terminals.


Supported Tools

Tool Auth Location Login Command
Claude Code OAuth: ~/.claude.json + ~/.config/claude-code/auth.json • API key: ~/.claude/settings.json /login in CLI
Codex CLI ~/.codex/auth.json (file store enforced) codex login (or --device-auth)
Gemini CLI OAuth: ~/.gemini/settings.json (+ oauth_credentials.json) • API key: ~/.gemini/.env gemini interactive

Claude Code (Claude Max)

Subscription: Claude Max ($200/month)

Auth Files:

  • ~/.claude.json — Main authentication token
  • ~/.config/claude-code/auth.json — Secondary auth data
  • ~/.claude/settings.json — API key mode via apiKeyHelper

Login Command: Inside Claude Code, type /login

Notes: Claude Max has a 5-hour rolling usage window. When you hit it, you'll see rate limit messages. Switch accounts to continue.

Codex CLI (GPT Pro)

Subscription: GPT Pro ($200/month unlimited)

Auth Files:

  • ~/.codex/auth.json (or $CODEX_HOME/auth.json)

Login Command: codex login (or codex login --device-auth for headless)

Notes: Respects CODEX_HOME. CAAM repairs Codex's managed config in ~/.codex/config.toml by enforcing cli_auth_credentials_store = "file", [features] multi_agent = true, and [notice] hide_rate_limit_model_nudge = true so the soft "Approaching rate limits" model-switch popup stays disabled at the config level.

Reliability: The popup suppression lives in the user's Codex config, not in a binary patch, so normal Codex upgrades should keep it. If config drift reappears, run caam doctor --fix to repair the managed defaults. For pane-heavy workflows where preserving scrollback matters more than fullscreen TUI behavior, consider Codex's current TUI setting [tui] alternate_screen = "never" as an optional local preference.

Required for seamless switching: keep the lower-model / cheaper-model nudge disabled. That interactive prompt interrupts wrapper-driven handoff and is one of the main ways Codex switching becomes unreliable. The exact managed config is:

cli_auth_credentials_store = "file"

[features]
multi_agent = true

[notice]
hide_rate_limit_model_nudge = true

Agent-oriented first-run guide: docs/AGENT_INSTALL.md

Gemini CLI (Google One AI Premium)

Subscription: Gemini Ultra ($275/month)

Auth Files:

  • ~/.gemini/settings.json
  • ~/.gemini/oauth_credentials.json (OAuth cache)
  • ~/.gemini/.env (API key mode)

Login Command: Start gemini, select "Login with Google" or use /auth to switch modes

Notes: For CAAM, Gemini Ultra behaves like Claude Max and GPT Pro: OAuth tokens are stored locally and can be swapped instantly.


Quick Start

1. Backup Your Current Account

# After logging into Claude normally
caam backup claude alice@gmail.com

2. Add Another Account

caam clear claude                        # Remove current auth
claude                                   # Login as bob@gmail.com via /login
caam backup claude bob@gmail.com         # Save it

3. Switch Instantly

caam activate claude alice@gmail.com     # Back to Alice
caam activate claude bob@gmail.com       # Back to Bob

4. Check Status

$ caam status
claude: alice@gmail.com (active)
codex:  work@company.com (active)
gemini: (no auth files)

$ caam ls claude
alice@gmail.com
bob@gmail.com
carol@gmail.com

Command Reference

Auth File Swapping (Primary Use Case)

Command Description
caam backup <tool> <email> Save current auth files to vault
caam activate <tool> <email> Restore auth files from vault (instant switch!)
caam status [tool] Show which profile is currently active
caam ls [tool] List all saved profiles in vault
caam delete <tool> <email> Remove a saved profile
caam paths [tool] Show auth file locations for each tool
caam clear <tool> Remove auth files (logout state)
caam uninstall Restore originals from _original and remove caam data/config

Aliases: caam switch and caam use work like caam activate

Quick Switch: pick + aliases

Use caam pick when you want the fastest possible profile swap:

caam pick claude           # fzf if installed; numbered prompt otherwise
caam pick                  # uses your default_provider if set

Set a default provider so you can omit the tool name:

caam config set default_provider claude

Aliases make long emails painless (works for pick and activate):

caam alias claude work-account-1 work
caam pick claude            # type "work" at the prompt
caam activate claude work   # alias resolution works here too

SSH-safe fallback (no fzf, no TTY): use direct activation:

caam activate claude work-account-1

fzf one-liner (if you prefer piping):

sel=$(caam ls claude | fzf --prompt 'claude> ') && [ -n "$sel" ] && caam activate claude "$sel"

Smart Profile Management

Command Description
caam activate <tool> --auto Auto-select the best profile using rotation algorithm
caam next <tool> Preview which profile rotation would select (dry-run)
caam run <tool> [-- args] Wrap CLI execution with automatic failover on rate limits
caam cooldown set <provider/profile> Mark profile as rate-limited (default: 60min cooldown)
caam cooldown list List active cooldowns with remaining time
caam cooldown clear <provider/profile> Clear cooldown for a specific profile
caam cooldown clear --all Clear all active cooldowns
caam project set <tool> <profile> Associate current directory with a profile
caam project get [tool] Show project associations for current directory

Options for caam run:

  • --max-retries N — Maximum retry attempts on rate limit (default: 1)
  • --cooldown DURATION — Cooldown duration after rate limit (default: 60m)
  • --algorithm NAME — Rotation algorithm: smart, round_robin, random
  • --quiet — Suppress profile switch notifications

Options for caam activate:

  • --auto — Use rotation algorithm to pick best profile
  • --backup-current — Backup current auth before switching
  • --force — Activate even if profile is in cooldown

When stealth.cooldown.enabled is true in config, caam activate warns if the target profile is in cooldown and prompts for confirmation. Use --force to bypass.

When stealth.rotation.enabled is true, caam activate <tool> automatically falls back to rotation if the default profile is in cooldown.

Uninstall Notes

caam uninstall restores auth from any available _original backups first, then removes caam’s data/config. Useful flags:

  • --dry-run shows what would be restored/removed
  • --keep-backups keeps the vault after restoring originals
  • --force skips the confirmation prompt

Profile Isolation (Advanced)

Command Description
caam profile add <tool> <email> Create isolated profile directory
caam profile ls [tool] List isolated profiles
caam profile delete <tool> <email> Delete isolated profile
caam profile status <tool> <email> Show isolated profile status
caam login <tool> <email> Run login flow for isolated profile
caam exec <tool> <email> [-- args] Run CLI with isolated profile

Smart Profile Management

When you have multiple accounts across multiple providers, manually tracking which account has headroom, which one just hit a limit, and which one you used recently becomes tedious. Smart Profile Management automates this decision-making so you can focus on coding instead of account juggling.

Profile Health Scoring

Each profile displays a health indicator showing its current state at a glance:

Icon Status Meaning
🟢 Healthy Token valid for >1 hour, no recent errors
🟡 Warning Token expiring within 1 hour, or minor issues
🔴 Critical Token expired, or repeated errors in the last hour
Unknown No health data available yet

Health scoring combines multiple factors:

  • Token expiry: How long until the OAuth token expires
  • Error history: Recent authentication or rate limit errors
  • Penalty score: Accumulated issues with automatic decay over time
  • Plan type: Enterprise/Pro plans get slight scoring boosts

The penalty system uses exponential decay (20% reduction every 5 minutes) so temporary issues don't permanently mark a profile as unhealthy. After about 30 minutes of no errors, a profile's penalty score returns to near zero.

Smart Rotation Algorithms

When you run caam activate claude --auto, the rotation system picks the best profile for you. Three algorithms are available:

Smart (Default): Multi-factor scoring that considers:

  • Cooldown state (profiles in cooldown are excluded)
  • Health status (prefers healthy profiles)
  • Recency (avoids profiles used in the last 30 minutes)
  • Plan type (slight preference for higher-tier plans)
  • Random jitter (breaks ties unpredictably)

Round Robin: Simple sequential rotation through profiles, skipping any in cooldown. Predictable and even distribution.

Random: Purely random selection among non-cooldown profiles. Least predictable but may cluster usage.

Configure the algorithm in ~/.caam/config.yaml:

stealth:
  rotation:
    enabled: true
    algorithm: smart  # smart | round_robin | random

Cooldown Tracking

When an account hits a rate limit, you can mark it as "in cooldown" so rotation algorithms skip it:

# Mark current Claude profile as rate-limited (default: 60 min cooldown)
caam cooldown set claude

# Or specify a profile and duration
caam cooldown set claude/work@company.com --minutes 120

# View active cooldowns
caam cooldown list

# Clear a cooldown early
caam cooldown clear claude/work@company.com

When cooldown enforcement is enabled (stealth.cooldown.enabled: true), attempting to activate a profile in cooldown will warn you and prompt for confirmation. This prevents accidentally switching back to an account that just hit limits.

Automatic Failover with caam run

The caam run command wraps your AI CLI execution and automatically handles rate limits:

# Instead of running claude directly:
caam run claude -- "explain this code"

# If Claude hits a rate limit mid-session:
# 1. Current profile goes into cooldown
# 2. Next best profile is automatically selected
# 3. Command is re-executed with new account

For seamless integration, add shell aliases:

alias claude='caam run claude --'
alias codex='caam run codex --'
alias gemini='caam run gemini --'

Now you can use claude "explain this code" and rate limits are handled transparently.

Configuration options:

caam run claude --max-retries 2 --cooldown 90m --algorithm smart -- "your prompt"

Project-Profile Associations

Link specific profiles to project directories so you don't have to remember which account to use where:

# In your work project directory
cd ~/projects/work-app
caam project set claude work@company.com

# Now whenever you're in this directory (or subdirectories)
caam activate claude  # Automatically uses work@company.com

# The TUI also shows the project association
caam tui
# Status bar shows: Project: ~/projects/work-app → work@company.com

Associations cascade: if you set an association on /home/user/projects, it applies to all subdirectories unless a more specific association exists.

In the TUI, press p to set the current profile as the default for your current directory.

Preview Rotation Selection

Before committing to a rotation selection, preview what the algorithm would pick:

$ caam next claude
Recommended: bob@gmail.com
  + Healthy token (expires in 4h 32m)
  + Not used recently (2h ago)

Alternatives:
  alice@gmail.com - Used recently (15m ago)

In cooldown:
  carol@gmail.com - In cooldown (45m remaining)

This is useful for understanding why rotation is making certain choices, or for scripting conditional logic around account selection.


Workflow Examples

Daily Workflow

# Morning: Check what's active
caam status
# claude: alice@gmail.com (active)
# codex:  work@company.com (active)
# gemini: personal@gmail.com (active)

# Afternoon: Hit Claude usage limit
caam activate claude bob@gmail.com
# Activated claude profile 'bob@gmail.com'

claude  # Continue working immediately with new account

Initial Multi-Account Setup

# 1. Login to first account using normal flow
claude
# Inside Claude: /login → authenticate with alice@gmail.com

# 2. Backup the auth using the email as the profile name
caam backup claude alice@gmail.com

# 3. Clear and login to second account
caam clear claude
claude
# Inside Claude: /login → authenticate with bob@gmail.com

# 4. Backup that too
caam backup claude bob@gmail.com

# 5. Now you can switch instantly forever!
caam activate claude alice@gmail.com   # < 100ms
caam activate claude bob@gmail.com     # < 100ms

Parallel Sessions Setup

# Create isolated profiles
caam profile add codex work@company.com
caam profile add codex personal@gmail.com

# Login to each (one-time, uses browser)
caam login codex work@company.com      # Opens browser for work account
caam login codex personal@gmail.com    # Opens browser for personal account

# Run simultaneously in different terminals
caam exec codex work@company.com -- "implement auth system"
caam exec codex personal@gmail.com -- "review PR #123"

Smart Rotation Workflow

# Let rotation pick the best profile automatically
caam activate claude --auto
# Using rotation: claude/bob@gmail.com
# Recommended: bob@gmail.com
#   + Healthy token (expires in 4h 32m)
#   + Not used recently (2h ago)

# Hit a rate limit during your session? Mark it
caam cooldown set claude
# Recorded cooldown for claude/bob@gmail.com until 14:30 (58m remaining)

# Next activation automatically picks another profile
caam activate claude --auto
# Using rotation: claude/alice@gmail.com
# Recommended: alice@gmail.com
#   + Healthy status
# In cooldown:
#   bob@gmail.com - In cooldown (57m remaining)

Zero-Friction Mode with caam run

# Add aliases to your .bashrc/.zshrc
alias claude='caam run claude --'
alias codex='caam run codex --'

# Now just use the tool normally
claude "explain this authentication flow"

# If you hit a rate limit mid-session, caam automatically:
# 1. Marks current profile as in cooldown
# 2. Selects next best profile via rotation
# 3. Re-runs your command with the new profile
# All transparent - you just see the output

Vault Structure

~/.local/share/caam/
├── vault/                          # Saved auth profiles
│   ├── claude/
│   │   ├── alice@gmail.com/
│   │   │   ├── .claude.json        # Backed up auth
│   │   │   ├── auth.json           # From ~/.config/claude-code/
│   │   │   └── meta.json           # Timestamp, original paths
│   │   └── bob@gmail.com/
│   │       └── ...
│   ├── codex/
│   │   └── work@company.com/
│   │       └── auth.json
│   └── gemini/
│       └── personal@gmail.com/
│           └── settings.json
│
└── profiles/                       # Isolated profiles (advanced)
    └── codex/
        └── work@company.com/
            ├── profile.json        # Profile metadata
            ├── codex_home/         # Isolated CODEX_HOME
            │   └── auth.json
            └── home/               # Pseudo-HOME with symlinks
                ├── .ssh -> ~/.ssh
                └── .gitconfig -> ~/.gitconfig

TUI Configuration

Customize the TUI appearance and behavior through ~/.caam/config.yaml:

tui:
  theme: auto          # auto | dark | light
  high_contrast: false # Enable high-contrast colors for accessibility
  reduced_motion: false # Disable animated UI effects (spinners)
  toasts: true         # Show transient notification messages
  mouse: true          # Enable mouse support
  show_key_hints: true # Show keyboard shortcuts in status bar
  density: cozy        # cozy | compact
  no_tui: false        # Disable TUI, use CLI-only mode

Environment Variable Overrides

Environment variables take precedence over config file settings:

Variable Values Description
CAAM_TUI_THEME auto, dark, light Color scheme
CAAM_TUI_CONTRAST high, hc, 1, true High contrast mode
CAAM_TUI_REDUCED_MOTION true, false Disable animations
REDUCED_MOTION 1 Standard accessibility env var
CAAM_TUI_TOASTS true, false Toast notifications
CAAM_TUI_MOUSE true, false Mouse support
CAAM_TUI_KEY_HINTS true, false Keyboard hints
CAAM_TUI_DENSITY cozy, compact UI spacing
CAAM_NO_TUI or NO_TUI true, 1 Disable TUI entirely

Managing TUI Config via CLI

# View all TUI settings
caam config tui

# View a specific setting
caam config tui theme
caam config tui density

# Change settings
caam config tui theme dark
caam config tui density compact
caam config tui high_contrast true

FAQ

Q: Does this work with API keys / pay-per-token plans?

No. This tool is specifically designed for fixed-cost subscription plans like Claude Max ($200/month), GPT Pro ($200/month), and Gemini Ultra ($275/month). These plans authenticate via OAuth browser flows and store tokens locally. If you're using API keys with usage-based billing, you don't need account switching—you'd just use different API keys.

Q: Is this against terms of service?

No. You're using your own legitimately-purchased subscriptions. caam just manages local auth files—it doesn't share accounts, bypass rate limits, or modify API traffic. Each account still respects its individual usage limits.

Q: What if the tool updates and changes auth file locations?

Run caam paths to see current locations. If they change in a tool update, we'll update caam. File an issue if you notice a discrepancy.

Q: Can I sync the vault across machines?

Don't. Auth tokens often contain machine-specific identifiers (device IDs, etc.). Backup and restore on each machine separately. Don't copy vault directories between machines.

Q: What's the difference between vault profiles and isolated profiles?

  • Vault profiles (backup/activate): Swap auth files in place. Simple, instant, one account active at a time per tool.
  • Isolated profiles (profile add/exec): Full directory isolation with pseudo-HOME. Run multiple accounts simultaneously in parallel terminals.

Q: Will this break my existing sessions?

Switching profiles while a CLI is running may cause auth errors in the running session. Best practice: switch accounts before starting a new session, not during.

Q: How do I know which account I'm currently using?

Run caam status. It shows the active profile (email) for each tool based on content hash matching.


Installation

Agent-flywheel / Codex users: start here

Before using this fork with Codex, follow docs/AGENT_INSTALL.md. It covers:

  • release install commands
  • first-run verification
  • the required Codex TOML settings
  • why hide_rate_limit_model_nudge = true matters for automatic handoff
  • the quickest repair command when Codex config drifts: caam doctor --fix

Recommended: Homebrew (macOS/Linux)

brew install dicklesworthstone/tap/caam

This method provides:

  • Automatic updates via brew upgrade
  • Dependency management
  • Easy uninstall via brew uninstall

Windows: Scoop

scoop bucket add dicklesworthstone https://github.com/Dicklesworthstone/scoop-bucket
scoop install dicklesworthstone/caam

Alternative: Direct Download

Download from the latest release page and choose the archive that matches your platform:

  • Linux x86_64: caam_<version>_linux_amd64.tar.gz
  • Linux ARM64: caam_<version>_linux_arm64.tar.gz
  • macOS Intel: caam_<version>_darwin_amd64.tar.gz
  • macOS ARM: caam_<version>_darwin_arm64.tar.gz
  • Windows x86_64: caam_<version>_windows_amd64.zip

Verify Release Artifacts

Each release ships with signed checksums:

cosign verify-blob \
  --bundle SHA256SUMS.sig \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  --certificate-identity "https://github.com/uuuser-name/caam-account-switching/.github/workflows/release.yml@refs/tags/vX.Y.Z" \
  SHA256SUMS

sha256sum -c SHA256SUMS
# macOS fallback:
# shasum -a 256 -c SHA256SUMS

Alternative: Install Script

curl -fsSL "https://raw.githubusercontent.com/uuuser-name/caam-account-switching/main/install.sh?$(date +%s)" | bash

From Source

git clone https://github.com/uuuser-name/caam-account-switching
cd caam-account-switching
go build -o caam ./cmd/caam
sudo mv caam /usr/local/bin/

Go Install

go install is intentionally not documented for this repository yet. The published binary/install-script path is the supported installation route for the current GitHub-hosted release.


Tips

  1. Use the actual email address as the profile name — it's self-documenting and you'll never forget which account is which
  2. Backup before clearing: caam backup claude current@email.com && caam clear claude
  3. Check status often: caam status shows what's active across all tools
  4. Use --backup-current flag: caam activate claude new@email.com --backup-current auto-saves current state before switching

Acknowledgments

Special thanks to @darvell for inspiring this project and for the feature ideas behind Smart Profile Management. His work on codex-pool—a sophisticated proxy that load-balances requests across multiple AI accounts with automatic failover—demonstrated how much intelligence can be added to account management.

While codex-pool answers "which account should handle THIS request?" (real-time proxy), caam answers "which account should I USE for my work session?" (profile manager). The Smart Profile Management features adapt codex-pool's intelligence to caam's architecture:

  • Proactive Token Refresh — Automatically refreshes OAuth tokens before they expire, preventing mid-session auth failures
  • Profile Health Scoring — Visual indicators (🟢🟡🔴) showing token status, error history, penalty decay, and plan type
  • Smart Rotation — Multi-factor algorithm picks the best available profile based on health, cooldown, recency, and usage patterns
  • Cooldown Tracking — Database-backed tracking of rate limit hits with configurable cooldown windows
  • Automatic Failover — The caam run wrapper detects rate limits and seamlessly switches to another account
  • Usage Analytics — Track activation patterns and session durations across profiles
  • Hot Reload — TUI auto-refreshes when profiles are added/modified in another terminal
  • Project-Profile Associations — Remember which profile to use for each project directory

See docs/SMART_PROFILE_MANAGEMENT.md for the full design document.


Contributions

Issues and focused pull requests are welcome, especially for reproducible bugs, docs fixes, and narrowly scoped test improvements.

CAAM is still maintained in a maintainer-driven style:

  • I may rework or re-implement proposed changes instead of merging patches as-is.
  • Reviews are prioritized for bugs, reliability fixes, and release blockers.
  • If you want the fastest path to a fix, open an issue with a clear reproduction and validation notes.

See CONTRIBUTING.md for the practical contribution workflow.


License

MIT

About

No description, website, or topics provided.

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors