npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@lngdao/claude-switch

v2026.410.9

Published

TUI + CLI to manage Claude Code auth profiles (OAuth tokens, API keys, proxies) and headless setup

Readme

@lngdao/claude-switch

CI npm version license

A TUI + CLI to manage multiple Claude Code auth profiles in ~/.claude/settings.json. Supports OAuth tokens, API keys, third-party proxies, and headless setup workflows for VPSes.

Install

# Run once with npx
npx @lngdao/claude-switch

# Or install globally
npm i -g @lngdao/claude-switch
claude-switch

# Optional: install a 'cs' alias into your shell rc
claude-switch alias install

Features

  • Profile CRUD: add, edit, rename, delete, clone, import, export.
  • Fast switching: claude-switch use <name> swaps the .env block while preserving every other top-level key in settings.json.
  • Auto re-activate after edit: if you edit the currently active profile, the new env is applied to settings.json immediately so it stays active.
  • Auto scheme detection: oauth / api-key / auth-token / proxy / mixed / empty.
  • Conflict guard: blocks saving a profile that contains both CLAUDE_CODE_OAUTH_TOKEN and ANTHROPIC_API_KEY (per Claude Code's own warning).
  • Token format validation: enforces the sk-ant-oat01- / sk-ant-api03- prefixes.
  • Doctor: checks config health (broken files, conflicts, file perms, onboarding bypass, version drift between claude --version and lastOnboardingVersion). Supports --probe to validate tokens against the API and --fix to auto-chmod 600. The probe distinguishes OAuth tokens (POST /v1/messages with anthropic-beta: oauth-2025-04-20 and the Claude Code system prompt — exactly the protocol Claude Code itself uses) from API keys (free /v1/messages/count_tokens). Each OAuth probe burns ~22 input + 1 output token (≈$0.00003).
  • Persistent probe results: every probe is recorded into the profile (meta.lastProbe) with severity, message, and timestamp; ls, current, and the TUI display "✓ 5m ago" / "✗ 2h ago" indicators.
  • Headless init: writes ~/.claude.json (onboarding bypass) plus a default profile, following the workflow in this gist. Includes --print-script (bash) and --ansible (YAML) generators for VPS provisioning.
  • Shell alias installer: auto-detects bash/zsh/fish and adds alias cs='/path/to/claude-switch' to the rc file. Idempotent and easy to uninstall.
  • Full-featured TUI: every command above is reachable through Ink TUI hotkeys — you never have to drop back to the CLI.
  • Atomic writes + backups: rotates 3 .bak copies of settings.json, holds an advisory lockfile to prevent races.
  • Secret masking: tokens are masked in displays. Use --unmask to reveal them, or hotkey c in the TUI to copy the unmasked value to the clipboard.
  • Hybrid invocation: with no arguments → opens the Ink TUI; with a sub-command → runs headless (script-friendly for Ansible/CI).

Usage

Profile management

claude-switch                    # open the TUI (requires a TTY)
claude-switch ls                 # list profiles
claude-switch ls --json          # JSON output for jq
claude-switch current            # show the active profile + env (masked)
claude-switch current --unmask   # show full values (requires confirmation)

claude-switch use official           # quick switch
claude-switch use official --dry-run # show diff without writing
claude-switch use bad --force    # bypass the conflict guard

claude-switch add                                                # interactive wizard
claude-switch add work --scheme oauth --token sk-ant-oat01-...   # non-interactive
claude-switch add proxy1 --scheme proxy --token sk-... --base-url https://anyrouter.top

claude-switch edit official                              # interactive menu
claude-switch edit official --set ENABLE_TOOL_SEARCH=true
claude-switch edit official --unset ENABLE_TOOL_SEARCH
claude-switch edit official --raw                        # open the env JSON in $EDITOR

claude-switch rename "Official backup" official-backup
claude-switch clone official official-test
claude-switch delete official-test
claude-switch delete official-test -y                # skip confirmation

claude-switch import ./shared.json --name shared
claude-switch export official --out ./official.json
claude-switch export official --mask                     # masked stdout output

Doctor

claude-switch doctor                # run all checks
claude-switch doctor --fix          # auto chmod 600 on profile files
claude-switch doctor --probe        # call the Anthropic API to test each token
claude-switch doctor --json         # structured output

Exit code: 0 for ✓/⚠ only, 10 if any ✗ are present.

Headless init (gist workflow)

Writes ~/.claude.json (onboarding bypass) plus a default profile:

# Interactive
claude-switch init

# Reuse oauthAccount from the local ~/.claude.json
claude-switch init --from-local --token sk-ant-oat01-...

# Non-interactive (Ansible / CI)
claude-switch init -y \
  --token sk-ant-oat01-... \
  --account-uuid 11111... \
  --email [email protected] \
  --org-uuid 22222... \
  --profile-name myhost

# Print a bash one-liner you can paste on a remote VPS
claude-switch init --print-script --token sk-ant-oat01-... \
  --account-uuid ... --email ... --org-uuid ... > setup-claude.sh

# Print an Ansible YAML snippet
claude-switch init --ansible --token sk-ant-oat01-... \
  --account-uuid ... --email ... --org-uuid ... > tasks/claude.yml

Self-update

claude-switch checks the npm registry once per day in the background and prompts you on the next interactive run if a newer version is available — same flow as oh-my-zsh:

Update available (patch)
  2026.410.3 → 2026.410.4
  package: @lngdao/claude-switch

? Update now? (Y/n)

Saying yes spawns the install command (npm i -g @lngdao/claude-switch@latest, auto-detected from npm/pnpm/yarn/bun) and exits with a re-run hint.

You can also drive it explicitly:

claude-switch update --check        # report cached status only
claude-switch update                # interactive: confirm + install
claude-switch update -y             # non-interactive
claude-switch update --pm pnpm      # force a specific package manager
claude-switch update --force        # reinstall latest even if up to date

Disable the auto prompt with CLAUDE_SWITCH_NO_UPDATE_CHECK=1 or the standard NO_UPDATE_NOTIFIER=1. The auto prompt is also skipped automatically for --json, -y, the update command itself, when CI=true, and when stdin is not a TTY.

Shell alias installer

claude-switch alias status                # show what's currently installed
claude-switch alias install               # interactive: detect shells & confirm
claude-switch alias install -y            # non-interactive
claude-switch alias install --name cw     # custom alias name (default: cs)
claude-switch alias install --shell zsh   # restrict to one shell
claude-switch alias install --dry-run     # show diff without writing
claude-switch alias uninstall             # remove the marker block

The installer writes a marker block to ~/.bashrc / ~/.zshrc / ~/.config/fish/config.fish, so re-running it is idempotent and uninstall reverts cleanly.

Global flags

| Flag | Default | Purpose | |---|---|---| | --profiles-dir <path> | ~/.claude/profiles | Override profiles directory | | --settings <path> | ~/.claude/settings.json | Override settings file | | --claude-json <path> | ~/.claude.json | Override onboarding bypass file | | --json | off | JSON output (ls, current, doctor, alias) | | --no-color | off | Disable color output | | -y, --yes | off | Skip confirmation prompts | | -v, --verbose | off | Verbose logging |

Auth scheme detection

| Scheme | Condition | |---|---| | oauth | has CLAUDE_CODE_OAUTH_TOKEN, no other auth keys, no ANTHROPIC_BASE_URL | | api-key | has ANTHROPIC_API_KEY, no other auth keys | | auth-token | has ANTHROPIC_AUTH_TOKEN, no base URL | | proxy | has ANTHROPIC_AUTH_TOKEN + ANTHROPIC_BASE_URL | | custom-base | has ANTHROPIC_BASE_URL, no token | | mixed | has 2 or more token keys (rejected by the conflict guard) | | empty / unknown | empty env / no matching branch |

TUI hotkeys

| Key | Action | |---|---| | ↑↓ / jk | Move profile cursor | | ←→ / hl | Move env-key cursor (for copy/probe) | | Enter / s | Switch to selected profile | | n | New profile (in-place form) | | e | Edit selected profile | | R | Rename selected profile | | C | Clone selected profile | | d | Delete selected profile (confirm) | | I | Import a profile from a JSON file | | E | Export selected profile to a JSON file | | D | Open the doctor screen (re-probe with p, auto-fix perms with f) | | i | Init wizard (~/.claude.json + first profile, prefilled from local if available) | | p | Probe selected profile against api.anthropic.com | | c | Copy selected env value to clipboard (unmasked) | | A | Shell alias installer (bash/zsh/fish) | | r | Refresh from disk | | ? | Toggle help | | q / Esc | Quit |

Develop locally

git clone https://github.com/lngdao/claude-switch.git
cd claude-switch
npm install
npm run build
npm link            # makes `claude-switch` available globally

Tests:

npm test            # vitest run
npm run test:watch  # watch mode
npm run typecheck   # tsc --noEmit

The current suite has 83 test cases covering scheme detection, profile CRUD, settings merge, doctor checks, headless init, the shell alias installer (round-trip + fish syntax + custom name), and the time-ago formatter.

Release flow

Releases use date-based versioning: YYYY.MDD.N (e.g. 2026.410.1). Run:

npm run release           # interactive: bumps, commits, tags, pushes
npm run release:dry       # show what would happen, no changes

The script (scripts/release.sh):

  1. Aborts if the working tree is dirty or you're not on main.
  2. Computes the next version from today's date plus an auto-incremented patch (collisions detected from existing v* tags).
  3. Runs npm run typecheck && npm test && npm run build as a safety net.
  4. Bumps package.json (and package-lock.json), commits with release: <version>, tags vYYYY.MDD.N, pushes branch + tag.
  5. The .github/workflows/publish.yml workflow picks up the tag and publishes via npm publish --provenance --access public (provenance attestation via OIDC, auth via the NPM_TOKEN repo secret).

Override the auto-computed version:

./scripts/release.sh 2026.410.5

Manual workflow trigger is also available through the GitHub Actions "workflow_dispatch" UI with two inputs: dry-run (full pipeline without publishing) and no-provenance (escape hatch for the first-publish-of-a-new-package edge case).

Notes

  • Locking: uses proper-lockfile over the profiles directory; falls back to a no-op handle if locking fails (e.g. when the directory is being created).
  • Version drift check: spawns claude --version with a 2-second timeout; if the CLI is not on $PATH the check is silently skipped.
  • TUI init wizard pre-fill: account info is loaded from the local ~/.claude.json if it exists, so creating a new profile with a fresh token doesn't require re-typing UUID / email / orgUuid.
  • In-TUI edit: only env keys are editable from the edit screen — use hotkey R for rename and C for clone.

License

MIT © Long Dao