{"id":49331901,"url":"https://github.com/countzero/windows_switch_claude_account","last_synced_at":"2026-05-03T14:00:39.847Z","repository":{"id":353320514,"uuid":"1218890963","full_name":"countzero/windows_switch_claude_account","owner":"countzero","description":"A simple PowerShell script to switch between multiple Anthropic Claude accounts.","archived":false,"fork":false,"pushed_at":"2026-04-26T21:05:46.000Z","size":626,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-26T23:03:46.042Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"PowerShell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/countzero.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-23T10:12:24.000Z","updated_at":"2026-04-26T21:04:49.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/countzero/windows_switch_claude_account","commit_stats":null,"previous_names":["countzero/windows_switch_claude_account"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/countzero/windows_switch_claude_account","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/countzero%2Fwindows_switch_claude_account","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/countzero%2Fwindows_switch_claude_account/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/countzero%2Fwindows_switch_claude_account/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/countzero%2Fwindows_switch_claude_account/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/countzero","download_url":"https://codeload.github.com/countzero/windows_switch_claude_account/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/countzero%2Fwindows_switch_claude_account/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32571456,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T06:36:36.687Z","status":"ssl_error","status_checked_at":"2026-05-03T06:36:09.306Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-04-26T23:00:26.463Z","updated_at":"2026-05-03T14:00:39.840Z","avatar_url":"https://github.com/countzero.png","language":"PowerShell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Claude Account Switcher\n\nA zero-dependency PowerShell tool for managing multiple Claude Code accounts on Windows. Save, switch, and watch live plan usage across all your slots; single self-contained `.ps1`, no companion files.\n\n## Features\n\n- **Live plan-usage dashboard**: `sca usage -Watch` polls Anthropic's `/api/oauth/usage` and renders a flicker-free, auto-refreshing view of Session (5h) and Week (7d) limits across every slot; the terminal-tab title is updated each poll so a backgrounded watch is glanceable from the taskbar / Alt-Tab\n- **Identity-aware slots**: each slot's OAuth email is captured at save time, baked into the filename, and locked in a sidecar; what you see in `list` is guaranteed to be who the tokens actually belong to\n- **Auto-reconcile**: silently captures Claude Code's hourly token refreshes into the tracked slot; auto-saves cross-account swaps under a timestamped name so you never lose state\n- **Transparent token refresh**: expired access tokens are refreshed before usage queries and mirrored back into the active credentials file\n- **Atomic-safe writes**: slot-file updates survive a running Claude Code via `MoveFileEx` with retry; `save` / `switch` still refuse to run while it's open (single source of truth on `~/.claude.json`)\n- **Named slots with rotation**: unlimited accounts under any name (Windows-invalid characters auto-sanitized); `sca switch` with no name cycles through them alphabetically\n- **Zero dependencies**: pure PowerShell 7.2+, no external packages, no companion assets\n\n## What `sca usage -Watch` looks like\n\n```\n[Usage] Plan usage\n\n  Session [█████████████                                                ]  22%\n\n  Week    [██████████████████████████████████████                       ]  62%\n\n    Slot         Account                Session        Week         Status\n    -----------  ---------------------  -------------  -----------  ------\n *  work         alex@acme.io            18% (2h 11m)   42% (102h)  ok\n    personal     alex.dev@gmail.com       3% (4h 02m)    7% (146h)  ok\n    dev          alex@startup.dev         9% (3h 41m)   34% (118h)  ok\n    client-acme  ada.lovelace@arpa.net   71% (1h 04m)   92% (41h)   near limit\n    legacy       team@example.com        12% (3h 18m)  100% (12h)   limited 7d\n\n[Watch] Last poll: 14:32:07\n```\n\nThe terminal-tab title is updated on every poll so the watch is useful even when the window is in the background:\n\n    22% | 62% | Switch Claude Account\n\nThe numbers come from the **active** slot (or the slot named in `sca usage \u003cname\u003e -Watch`); a non-`ok` row falls back to the bare brand suffix. A `[~]` prefix appears when a bucket is ≥90%, `[!]` when ≥100%. Pre-watch title is restored on Ctrl-C.\n\n\u003e Bar color: green \u0026lt;50%, yellow ≥50%, red ≥90%. Row color tracks slot status: green for the active+`ok` slot (including the `*` marker), gray for healthy inactive slots, yellow for `near limit` (≥90%), red for `limited 5h` / `limited 7d` (≥100%).\n\n## Installation\n\n\u003e **Requires PowerShell 7.2+.** Stock Windows ships PowerShell 5.1, which is not supported. Install PS 7 via `winget install Microsoft.PowerShell`, then run from `pwsh`.\n\n### Download\n\n[Download `switch_claude_account.ps1`](https://github.com/countzero/windows_switch_claude_account/releases/latest/download/switch_claude_account.ps1)\n(latest release; single self-contained file, no companion assets).\nPlace it anywhere on disk.\n\nFor older versions or release notes, see the\n[releases page](https://github.com/countzero/windows_switch_claude_account/releases).\n\n### Manual (run once)\n\n```powershell\n.\\switch_claude_account.ps1 install\n```\n\nThis adds `sca` (short) and `switch-claude-account` (long) aliases to your PowerShell profile. Close and reopen your terminal to activate them.\n\n### Without alias\n\n```powershell\n.\\switch_claude_account.ps1 \u003caction\u003e [name]\n```\n\n## Usage\n\n### Save an account\n\nLog into an account in Claude Code, **close Claude Code**, then save:\n\n```powershell\nsca save work\nsca save personal\nsca save test-project\n```\n\n`save` refuses to run while Claude Code is open and refuses to save a slot whose identity it cannot resolve from `~/.claude.json` (primary) or `/api/oauth/profile` (fallback). There are no unlabeled-no-identity slots. To rename a slot: `sca switch old-name; sca save new-name; sca remove old-name`.\n\n### List saved slots\n\n```powershell\nsca list\n```\n\nThe active slot is marked with `*` (sourced from `~/.claude/.sca-state.json`). Slots whose identity sidecar is missing or invalid are hidden from the list, from rotation, and from `switch`; re-running `sca save \u003cname\u003e` while that slot is active recaptures the sidecar.\n\n### Switch to a slot\n\n```powershell\nsca switch work\n```\n\n`switch` refuses to run while Claude Code is open. It atomically writes the slot's bytes into `.credentials.json` AND restores the slot's captured `oauthAccount` block into `~/.claude.json` so Claude Code's `/status` shows the matching email.\n\n### Rotate to the next slot\n\n```powershell\nsca switch\n```\n\nWithout a name, `switch` activates the next slot in alphabetical order and wraps from the last back to the first. The current position comes from `state.active_slot`.\n\n### Remove a slot\n\n```powershell\nsca remove test-project\n```\n\n`remove` refuses to delete the slot tracked as currently active.\n\n### Identity capture: who is each slot actually logged in as?\n\nSlot names are user-assigned labels; nothing stops you from naming a slot `work` and later overwriting it with credentials for a completely different account. At `sca save` time the tool pulls the OAuth email from `~/.claude.json`'s `oauthAccount` block (Claude Code's own cache) and embeds it in the slot filename:\n\n```\n%USERPROFILE%\\.claude\\.credentials.work(ada.lovelace@arpa.net).json\n```\n\nA paired sidecar `.credentials.work(ada.lovelace@arpa.net).account.json` holds the full whitelisted identity (`accountUuid`, `emailAddress`, `organizationUuid`, `displayName`, `organizationName`) so `sca switch` can restore the matching `oauthAccount` block to `~/.claude.json`. Because the email is captured at save time and carried in both the filename and sidecar, it cannot drift from the OAuth tokens; the only way to update a slot's email label is to re-run `sca save`.\n\nWhen the slot name already equals the OAuth email, the filename is deduplicated to `.credentials.alice@example.com.json` and the `Account` column shows `—`.\n\n### Check plan usage\n\n```powershell\nsca usage                         # one-shot table for every slot\nsca usage work                    # verbose single-slot block (opus / sonnet / overage)\nsca usage -Watch                  # live, self-refreshing view; Ctrl-C to quit\nsca usage -Watch -Interval 300    # slower poll cadence (60s floor)\nsca usage -Json                   # machine-readable per-slot output\nsca usage -NoColor                # strip ANSI color (also: $env:NO_COLOR='1')\n```\n\n`-NoColor` works under `-Watch` too; body color is stripped while the alt-buffer / synchronized-output rendering remains flicker-free. The output shows the 5-hour session limit (`Session` column, \"Current session\" in Claude Code's `/usage`) and the 7-day weekly all-models limit (`Week` column, \"Current week (all models)\") as percentages of each account's Claude.ai subscription:\n\n```\n[Usage] Plan usage\n\n  Session [█████                                              ]  10%\n\n  Week    [████████████                                       ]  24%\n\n    Slot      Account             Session        Week         Status\n    --------  ------------------  -------------  -----------  ------\n *  work      alex@acme.io         18% (2h 11m)   42% (102h)  ok\n    personal  alex.dev@gmail.com    3% (4h 02m)    7% (146h)  ok\n```\n\nDecoding the output:\n\n- **Pool-aggregate bars**: sum utilization across HTTP-ok slots over `N × 100%`. Bar color: green \u0026lt;50%, yellow ≥50%, red ≥90%.\n- **Active marker (`*`)**: sourced from `~/.claude/.sca-state.json`; appears at the start of the row and inherits the row's color.\n- **`Account` column**: the OAuth email captured at save time. Shows `—` when the email equals the slot name (deduped filename), the actual email otherwise.\n- **`Session` / `Week` cells**: `\u003cpct\u003e% \u003cdelta\u003e`. The delta is `(2h 11m)` under 24h with minute precision, `(102h)` at 24h+ with integer hours, `now` if the reset is past, or `—` when no data is available.\n- **`Status` column**: one of `ok`, `near limit` (≥90%), `limited 5h` / `limited 7d` (≥100%), `error`, `expired`, `unauthorized`, `rate-limited`, or `no-oauth`. Status drives the entire row's color.\n\nDrill into a single slot for absolute reset times in your local timezone:\n\n```powershell\nsca usage work\n```\n\n```\n[Usage] Slot 'work' (active)\n  Account: alex@acme.io\n  Status:  ok\n  Session     18%  Resets 7:50pm Europe/Berlin\n  Week        42%  Resets Apr 28, 9am Europe/Berlin\n```\n\n`list`, `switch`, and `usage` run a quiet **reconcile** pass before doing their work: if `.credentials.json` has changed since the last sync (Claude Code refreshed a token, or you logged into a different account inside Claude Code), the new bytes are captured into the tracked slot, or auto-saved under `auto-\u003cUTC-timestamp\u003e(\u003cemail\u003e).json` if the email differs.\n\n\u003e **Unofficial API.** `sca usage` calls `api.anthropic.com/api/oauth/usage`, the same endpoint Claude Code's `/usage` uses internally. Undocumented by Anthropic and may break on Claude Code upgrades; when that happens, see the extraction recipe at the top of `switch_claude_account.ps1` to re-pin the constants.\n\n\u003e **Token refresh.** If a slot's access token has expired (default TTL ~1h), `sca usage` transparently refreshes it against `platform.claude.com/v1/oauth/token` and mirrors the new tokens back into both the slot file and `.credentials.json` via atomic rename so the active session keeps working.\n\n### Install / uninstall alias\n\n```powershell\nsca install      # Add aliases to your PowerShell profile\nsca uninstall    # Remove aliases from your PowerShell profile\nsca help         # Show usage info\n```\n\n## Workflow\n\n### Saving accounts\n\n1. Open Claude Code and log in with your first account\n2. **Close Claude Code**\n3. Run `sca save work`\n4. Open Claude Code, log out, log in with a different account\n5. **Close Claude Code**\n6. Run `sca save personal`\n\nIf Claude Code is running when you invoke `save` or `switch`, the action exits immediately with a clear message; no partial writes occur.\n\n### Switching between accounts\n\n1. **Close Claude Code**\n2. Run `sca switch work`\n3. Open Claude Code: it now uses the `work` credentials and `/status` shows the matching email\n\n### Why close Claude Code first?\n\n`sca save` and `sca switch` read and write `~/.claude.json`'s `oauthAccount` block. Claude Code keeps that block in an in-memory cache that may flush back and clobber the update. Closing the app eliminates the race. (Slot-file updates done by `sca usage`'s token refresh use `MoveFileEx` with retry, so they survive an open Claude Code on `.credentials.json` itself; but the `~/.claude.json` cache race means you still need to close it for the two write actions.)\n\n## Windows Notes\n\n### Name sanitization\nSpaces, Windows-invalid filename characters (`\\ / : * ? \" \u003c \u003e |` and control chars), and PowerShell wildcard brackets (`[` `]`) are automatically replaced with `_`. Trailing dots are stripped. Reserved Windows device names (`CON`, `PRN`, `AUX`, `NUL`, `COM1`-`COM9`, `LPT1`-`LPT9`) are rejected.\n\n- `my personal` → `my_personal`\n- `foo/bar` → `foo_bar`\n- `foo[bar]` → `foo_bar_`\n- `foo.` → `foo`\n- `CON` → error (reserved device name)\n\n### Profile encoding\n`sca install` and `sca uninstall` preserve your PowerShell profile's existing encoding (UTF-8 with or without BOM, UTF-16 LE/BE). ANSI-encoded profiles are treated as UTF-8 no-BOM (indistinguishable without a BOM).\n\n### State file\nThe active-slot tracker lives at `%USERPROFILE%\\.claude\\.sca-state.json`; plain JSON, safe to inspect. Schema: `{ schema, active_slot, last_sync_hash }`.\n\n### Execution policy\nIf you get a security warning on first run, press `Y` or run once as:\n\n```powershell\nSet-ExecutionPolicy -Scope CurrentUser RemoteSigned\n```\n\n## Testing\n\n```powershell\npwsh -NoProfile -File tests/Invoke-Tests.ps1\n```\n\nPester 5 is auto-installed to `CurrentUser` scope on first use. PSScriptAnalyzer runs in advisory mode if installed. Each test sandboxes `$env:USERPROFILE` and `$PROFILE.CurrentUserAllHosts` to Pester's `$TestDrive` so your real `.claude\\` directory and PowerShell profile are never touched. Exit code follows Pester: `0` on pass, non-zero on any failure.\n\n---\n\nFor the architecture (state file, sidecar invariants, `~/.claude.json` ownership, unofficial API constants), see [`CLAUDE.md`](./CLAUDE.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcountzero%2Fwindows_switch_claude_account","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcountzero%2Fwindows_switch_claude_account","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcountzero%2Fwindows_switch_claude_account/lists"}