account-rotation

star 392

Switch coding-agent accounts on a usage/rate limit or to spread swarm lanes. Routes by host+agent: macOS+Claude via claude-acct; Codex/Gemini and Linux/WSL via caam.

boshu2 By boshu2 schedule Updated 6/15/2026

name: account-rotation user-invocable: false skill_api_version: 1 hexagonal_role: supporting metadata: tier: execution description: "Switch coding-agent accounts on a usage/rate limit or to spread swarm lanes. Routes by host+agent: macOS+Claude via claude-acct; Codex/Gemini and Linux/WSL via caam." practices:

  • pragmatic-programmer

account-rotation — switch coding-agent accounts on a rate limit

The moment: you hit a usage limit on a Claude Max / Codex Pro / Gemini subscription and want to keep working on a fresh account, or you're spreading swarm lanes across accounts for parallel quota. The tool depends on the host — because the credential layer differs by OS+agent. This skill routes; the tools do the swap.

Quick Start — route first

macOS + Claude            → claude-acct  (Keychain layer)
macOS + Codex/Gemini      → caam         (file layer)
Linux / WSL  + anything   → caam         (file layer)

Why the route exists (the load-bearing fact)

caam swaps the auth file (~/.claude/.credentials.json, codex/gemini auth files). Correct for file-based auth — Codex, Gemini, and Claude-on-Linux. But current Claude Code on macOS stores its token in the login Keychain (security service Claude Code-credentials) and ignores that file. So caam activate/next for Claude on Mac are no-ops — they swap a file Claude doesn't read. That one exception is the whole reason this router exists.

macOS + Claude → claude-acct (Keychain swap)

A full Claude account on Mac = two pieces, both swapped together: the Keychain token + the ~/.claude.json .oauthAccount identity block (claude auth status reads the email from the latter; a token-only swap leaves the identity pinned to the last login → "only the current account works"). claude-acct swaps both via security add/delete-generic-password -A (-A = no GUI prompt, so headless workers don't stall) + a JSON splice of .oauthAccount.

claude-acct list                 # captured accounts → real email each maps to
claude-acct current              # which account a NEW claude starts on
claude-acct use <name>           # swap (token + identity)
claude-acct login <name> [email] # one-time capture (see Capture Discipline)

Tool: dotfiles/bin/claude-acct.

macOS+Codex/Gemini & all Linux/WSL → caam (file swap)

caam is the adopted file-based rotator and is correct here. It self-documents (there is intentionally no caam skill — the CLI is the doc):

caam status <tool>            # vault + health
caam next <tool>              # rotate to next non-cooldown account
caam use <tool> <profile>
caam --help                   # full surface

On bushido (Ubuntu) this is the only rotator you need — file-based auth means caam's swap actually takes.

Capture Discipline (the two traps — apply to both tools)

  1. Distinct token bytes ≠ distinct accounts. OAuth re-issues a fresh token each login, so N logins to the same account produce N different hashes. Verify by account email, not token hash. (claude-acct warns on collision.)
  2. The browser captures whichever account the provider is signed into. Email login-hints are ignored when a session exists. Log out (or use a Private/Incognito window) before each capture login, or it re-grabs the current account.

Live-Session Caveat

A running agent process holds its token in memory; rotation changes what a new process picks up, not the live session. To move the session you're in: rotate, then relaunch the CLI. Exactly right for spawning swarm lanes.

Swarm Lanes (the real unlock)

Parallel quota = put each lane on a different account before launching it:

# Mac (Claude)
claude-acct use acct-a && <spawn lane A>;  claude-acct use acct-b && <spawn lane B>
# Linux / Codex
caam use codex acct-a   && <spawn lane A>;  caam next codex      && <spawn lane B>

A dispatcher's limit-hit hook calls claude-acct use on Mac / caam next on Linux, then re-dispatches the lane's work.

Navi-rotate (the cross-model helper rotates a peer — trilateral)

In the trilateral (2 Claude builders + 1 Codex Navi), the Navi runs on a DIFFERENT runtime/account, so it is UNAFFECTED by a builder's Claude rate limit — making it the right agent to rotate a limited builder. navi-rotate (dotfiles/bin/navi-rotate) wraps claude-acct with rotation-order + peer-relaunch signaling, so the move is one repeatable command:

navi-rotate <peer-tmux-session> [--to <account>] [--dry-run]
# Navi: next account (claude-acct list order) -> claude-acct use <next>
#       -> am + atm signal the peer to relaunch.

Per the Live-Session Caveat: the swap lands on the peer's NEXT launch, not its live session — continuity rides the durable substrate (worktree + bead + handoff), so the peer resumes from its last bead on the fresh account. This is the repeatable, cross-model-driven form of the dispatcher limit-hit hook above. Routed correctly: the swap is always claude-acct for Mac+Claude (NEVER caam).

Install via CLI
npx skills add https://github.com/boshu2/agentops --skill account-rotation
Repository Details
star Stars 392
call_split Forks 40
navigation Branch main
article Path SKILL.md
More from Creator