From ops
Manages multi-account Claude Max rotation with keychain token swapping and CRS relay-pool auto-prioritization. Useful when running multiple Claude accounts with rotation enabled.
How this skill is triggered — by the user, by Claude, or both
Slash command
/ops:ops-rotate [status|rotate-now|list|add-account|crs|crs-tick][status|rotate-now|list|add-account|crs|crs-tick]This skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Manage the optional multi-account Claude Max rotator. Off by default — flip
Manage the optional multi-account Claude Max rotator. Off by default — flip
account_rotation_enabled in plugin settings to use it.
$ARGUMENTS | Action |
|---|---|
(none) or status | Show current account, 5h%/7d%, total rotations, daemon health |
rotate-now | Force rotation to the most-cooled candidate (or --to <email>) |
list | List every configured account with token state + last util |
add-account | Interactive wizard: collect email, OAuth into rotator vault |
crs | Show the CRS relay-pool schedulable state + priority-daemon health |
crs-tick | Run one CRS priority tick now (append --dry-run to preview, no writes) |
This skill manages two complementary account-management systems:
status/rotate-now/list/add-account) — for direct-auth
sessions. One active claude.ai OAuth token in the keychain at a time; the daemon swaps
to the coolest account when the active one heats up.crs/crs-tick) — for a claude-relay-service pool, which
load-balances across many accounts simultaneously. Instead of swapping one token, it
toggles each account's schedulable flag from live utilization so the relay avoids
near-maxed accounts and re-enables them on recovery. Off by default; see
ops-rotate-setup to configure + install.account_rotation_enabled from plugin preferences. If false, tell the user how to enable and exit.ROT_DIR=${CLAUDE_PLUGIN_DATA_DIR:-$HOME/.claude/plugins/data/ops}/account-rotationROT_SRC=${CLAUDE_PLUGIN_ROOT}/scripts/account-rotation$ROT_DIR doesn't exist yet, mirror the runtime layout:
mkdir -p "$ROT_DIR"
cp "$ROT_SRC/config.example.json" "$ROT_DIR/config.json" # only if missing
node --version. If missing, fail fast with install hint.Run:
node "$ROT_SRC/rotate.mjs" --status
node "$ROT_SRC/rotate.mjs" --utilization 2>/dev/null | head -40
launchctl list 2>/dev/null | grep com.claude-ops.account-rotation || echo "daemon: not loaded"
Render a compact panel:
ROTATOR STATUS
Active account : <email>
5h utilization : 42% (resets in 1h 23m)
7d utilization : 18%
Total rotations: 14
Daemon : ✓ running (PID 12345) | ✗ not loaded
Configured : 4 accounts (3 with valid tokens, 1 expired)
If user passed an explicit target email (/ops:rotate rotate-now [email protected]), pass --to "<email>". Otherwise let rotate.mjs pick the most-cooled.
bash "$ROT_SRC/force-rotate.sh" "${TARGET_EMAIL:-}"
Show the trailing status output. Remind the user that running Claude Code sessions hold their own access token until next /login or until they exit and re-enter.
node "$ROT_SRC/rotate.mjs" --status 2>/dev/null
Then for each account in $ROT_DIR/config.json, render one row:
[✓] [email protected] 5h 12% token valid 6.4h (active)
[✓] [email protected] 5h 87% token valid 3.1h
[✗] [email protected] ── ── token expired 2d ago
[○] [email protected] ── ── no token captured
If any row is [○] or [✗], suggest running /ops:rotate add-account for that email.
This is the only mutating subcommand. Walk the user through:
AskUserQuestion: "Email of the Claude Max account to add?" (free text via Edit to config — the skill must NOT capture sensitive data through chat options; just ask for the email).AskUserQuestion: [Personal], [Workspace], [Skip]). If Workspace, prompt for orgName (free text) — orgUuid is auto-discovered later.$ROT_DIR/config.json, append the new account entry to accounts[], write back. Use the schema from config.example.json._account_schema_example.AskUserQuestion:
[Use current Claude Code login] — runs node "$ROT_SRC/rotate.mjs" --capture --to <email> to copy the live Claude Code-credentials token into the rotator vault.[Run OAuth in browser now] — runs node "$ROT_SRC/rotate.mjs" --setup --only=<email> (background-friendly; opens Chrome).[Skip — I'll capture later].com.claude-ops.account-rotation, ask [Install + start daemon] / [Skip]. On install:
sed "s|\${HOME}|$HOME|g" "${CLAUDE_PLUGIN_ROOT}/templates/com.claude-ops.account-rotation.plist" > ~/Library/LaunchAgents/com.claude-ops.account-rotation.plist
launchctl load ~/Library/LaunchAgents/com.claude-ops.account-rotation.plist
Mirror daemon.mjs + friends to $ROT_DIR if not already symlinked:
for f in rotate.mjs daemon.mjs ai-brain.mjs force-rotate.sh; do
[ -e "$ROT_DIR/$f" ] || ln -s "$ROT_SRC/$f" "$ROT_DIR/$f"
done
status subcommand inline.Show the claude-relay-service pool's per-account schedulable state + the priority daemon's health, plus the three optional reconcilers (429-cooldown, 401-refresher, magic-link-autoloop) if enabled. Read-only.
WRAP="$ROT_SRC/crs-priority-daemon.sh"
bash "$WRAP" --status 2>&1 | head -40 # prints "● name sched=true 5h=NN% <status>"
launchctl list 2>/dev/null | grep com.claude-ops.crs-priority || echo "crs-priority daemon: not loaded"
tail -n 5 "${CLAUDE_PLUGIN_DATA_DIR:-$HOME/.claude/plugins/data/ops-ops-marketplace}/logs/crs-priority.log" 2>/dev/null
# Only if crs.cooldownEnabled / crs.tokenRefreshEnabled / crs.enableMagicLinkRecovery are true in config:
node "$ROT_SRC/crs-429-cooldown.mjs" --status 2>&1
launchctl list 2>/dev/null | grep com.claude-ops.crs-429-cooldown || echo "crs-429-cooldown: not loaded"
node "$ROT_SRC/crs-401-refresher.mjs" --status 2>&1
launchctl list 2>/dev/null | grep com.claude-ops.crs-401-refresher || echo "crs-401-refresher: not loaded"
node "$ROT_SRC/magic-link-autoloop.mjs" --status 2>&1
launchctl list 2>/dev/null | grep com.claude-ops.magic-link-autoloop || echo "magic-link-autoloop: not loaded"
Render a compact panel:
CRS POOL (http://127.0.0.1:3000)
schedulable : 7 / 10
off : canary-sponsors (rate-limited), pool-chairman (warning), pool-foundation (warning)
daemon : ✓ running (every 120s) | ✗ not loaded — run /ops:rotate-setup
429-cooldown: ✓ running (every 60s) | ✗ not loaded | – not enabled (crs.cooldownEnabled=false)
401-refresher: ✓ running (every 300s) | ✗ not loaded | – not enabled (crs.tokenRefreshEnabled=false)
magic-link : ✓ running (every 600s) | ✗ not loaded | – not enabled (crs.enableMagicLinkRecovery=false)
If CRS /health is unreachable, say so and point to ops-rotate-setup. If the daemon
isn't loaded but crs.enabled is true, suggest /ops:rotate-setup. Show the two
reconciler lines only if their config flag is true — if false, show – not enabled
rather than treating it as a failure (it's an opt-in feature). If a flag is true but
its daemon isn't loaded, suggest /ops:rotate-setup --reconcilers.
Apply (or, with --dry-run, preview) one prioritization pass immediately — useful
right after changing thresholds or to confirm the policy.
bash "$ROT_SRC/crs-priority-daemon.sh" ${ARGS:-} # ARGS="--dry-run" to preview
This is the same code the launchd timer runs; the daemon only ever toggles
schedulable (fully reversible) and never deletes or mutates account credentials.
rotate.mjs uses Playwright only for the browser fallback. It is declared as
an optional dep in the plugin's package.json. If a browser fallback is needed
and Playwright is missing, the skill should offer:
npm install --prefix "$CLAUDE_PLUGIN_ROOT" --no-save playwright
npx --prefix "$CLAUDE_PLUGIN_ROOT" playwright install chromium
add-account mutates config.json, and only after the user explicitly confirmed the email.config.json outside add-account — token rotation is the daemon's job, not the skill's.account_rotation_enabled is false, refuse to run subcommands and instead explain the toggle.CLAUDE_ROTATOR_KEYCHAIN_ACCOUNT as the override env var.npx claudepluginhub lifecycle-innovations-limited/claude-ops --plugin opsWalks through each account in the rotation config, runs OAuth magic-link flow for accounts missing valid tokens, and writes verified tokens to the keychain.
Automates ChatGPT Team account rotation, batch free account generation, and Codex OAuth sync. Includes a web dashboard and Docker deployment.
Switches a caller-selected coding-agent account and reports the observed identity through the target runtime. For credential rotation sessions.