# Claude Code Account Switcher Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use run-plan-codex.js task execution. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Add Claude Code account storage/selection/launch behavior beside the existing Codex account switcher, with independent registries/defaults and a two-column tray menu.

**Architecture:** Keep Codex paths backward-compatible. Add a tool-kind aware account system for Claude, a `cld` wrapper, and dual-system tray rendering. Claude account defaults use live symlinks for both `~/.claude/.credentials.json` and `~/.claude.json` so credential rotation and account metadata/cache writes are not copied stale.

**Tech Stack:** Python 3, pytest, GTK3 fake-test doubles, local `claude` CLI probes, existing `run-plan-codex.js` orchestrator.

---

## Wave Plan

| Wave | Tasks | Files touched | Safe to parallelize? |
|------|-------|---------------|----------------------|
| 1 | Task 1, Task 2 | `account_registry.py`, `tests/test_account_registry.py`, `cld.py`, `tests/test_cld.py` | yes, no file overlap |
| 2 | Task 3 | `indicator.py`, `tests/test_indicator.py` | single task |
| 3 | Task 4 | `systray_codex_switcher.py`, `tests/test_systray_codex_switcher.py`, routing fixtures | single task |
| 4 | Task 5 | verification only | human/manual; prevents auto-ship |

## File Structure

- `account_registry.py` owns both Codex and Claude account registry layouts through `AccountRegistryKind`.
- `cld.py` mirrors `cdx.py` wrapper UX for Claude Code.
- `indicator.py` renders two account columns and scopes all default changes by account system.
- `systray_codex_switcher.py` seeds both routing files and constructs both registries.
- `tests/test_cld.py` covers Claude wrapper routing/override behavior.

## Task 1: AccountRegistryKind + Claude Storage

**Wave:** 1
**Blocks:** Task 2, Task 3, Task 4
**Blocked by:** —

**Files:**
- Modify: `account_registry.py`
- Modify: `tests/test_account_registry.py`

- [ ] Write failing tests for `AccountRegistryKind.CLAUDE`: separate `claude-accounts`, `claude_accounts.json`, `claude_default_slug`, account home `CLAUDE_HOME`, account files `.credentials.json` and `claude.json`, live default symlink `~/.claude/.credentials.json`, and live default symlink `~/.claude.json`.
- [ ] Preserve every existing Codex test. Existing constructor defaults must still mean Codex.
- [ ] Implement `AccountRegistryKind` and path/auth-file selection without duplicating the registry class.
- [ ] Make `set_default()` use atomic symlink replacement for both Claude active files and existing Codex behavior for Codex.
- [ ] Run `python3 -m pytest tests/test_account_registry.py -q`.

## Task 2: `cld` Wrapper

**Wave:** 1
**Blocks:** Task 4
**Blocked by:** Task 1

**Files:**
- Create: `cld.py`
- Create: `tests/test_cld.py`

- [ ] Write failing tests for `cld --account=<slug>`, `cld --account <slug>`, project routing via `claude_routing_rules.json`, stale/missing health warning text, unknown account rejection, and exec target `claude`.
- [ ] Probe local Claude config isolation. If a proven env var exists, use it with both account-state files. If not, route by updating both Claude default symlinks before launch and document that per-invocation routing is default-symlink based.
- [ ] Implement `cld.py` using `cdx.py` parsing/routing style and Claude-specific paths/messages.
- [ ] Run `python3 -m pytest tests/test_cld.py tests/test_cdx.py -q`.

## Task 3: Two-Column Indicator

**Wave:** 2
**Blocks:** Task 4
**Blocked by:** Task 1

**Files:**
- Modify: `indicator.py`
- Modify: `tests/test_indicator.py`

- [ ] Add focused tests for two columns: `Codex` and `Claude Code`, independent checked defaults, independent selection callbacks, slug collision safety, and title `Codex: ... · Claude: ...`.
- [ ] Refactor `Indicator` around small account-system records instead of a single registry while preserving single-registry compatibility for existing tests where possible.
- [ ] Keep Codex repair/add flows scoped to Codex. For Claude, omit or disable Add/Refresh until Claude login mutation behavior is verified.
- [ ] Store snapshots per account system so same slug in Codex and Claude cannot collide.
- [ ] Run `python3 -m pytest tests/test_indicator.py -q`.

## Task 4: Startup Wiring + Routing Seeds

**Wave:** 3
**Blocks:** Task 5
**Blocked by:** Task 1, Task 2, Task 3

**Files:**
- Modify: `systray_codex_switcher.py`
- Modify: `tests/test_systray_codex_switcher.py`
- Optionally modify: `routing_resolver.py`

- [ ] Add tests proving startup seeds both `routing_rules.json` and `claude_routing_rules.json`.
- [ ] Construct both registries: Codex default registry and Claude registry with `AccountRegistryKind.CLAUDE`.
- [ ] Pass both registries into `Indicator`.
- [ ] Keep Codex migration unchanged; do not auto-import Claude backup credentials.
- [ ] Run `python3 -m pytest tests/test_systray_codex_switcher.py tests/test_routing_resolver.py -q`.

## Task 5: Manual Verification Gate

**Wave:** 4
**Blocks:** —
**Blocked by:** Task 4

**Files:**
- Manual only.

- [ ] Run full tests: `python3 -m pytest -q`.
- [ ] Run `python3 -m py_compile account_registry.py cdx.py cld.py indicator.py systray_codex_switcher.py`.
- [ ] Verify `cld --account <known-test-slug> --help` does not print token contents.
- [ ] Inspect `git status --short` and confirm no user-owned dirty source edits were overwritten.
- [ ] Decide separately whether to land/commit/PR. This task intentionally stays human/manual so `run-plan-codex.js` does not auto-ship.

## Self-Review

- Spec coverage: storage, `cld`, two columns, startup wiring, and safety verification each have tasks.
- Placeholder scan: no TBD/TODO placeholders.
- Wave check: Wave 1 has no file overlap. Later waves are sequential where files overlap.
- Dirty-worktree handling: task agents must not revert primary dirty files. Final manual gate requires explicit status inspection before landing.
