Skip to main content

Crate swapdex

Crate swapdex 

Source

Modules§

adapters
One AuthTool per supported CLI. An adapter knows where a tool keeps its login on disk and how to capture/apply/inspect it. Secrets live only inside Snapshot (as Secret); Account is the redacted, serializable identity.
atomic
All credential writes go through here: 0600 at creation, temp in the dest’s own directory, atomic same-fs rename, symlink/ownership refusal. A write that cannot be done atomically fails loudly rather than falling back to a non-atomic (and mode-racy) copy.
banner
The ASCII wordmark the CLI prints when run with no subcommand. It is the same art shown in the README banner, so the banner is literally what you see in your own terminal. ANSI colour is used only when stdout is a TTY and NO_COLOR is unset, so a piped invocation stays plain text.
codex_limits
Codex’s own rate limits, read from its session logs - no network at all.
codex_usage
Codex usage, asked of the account itself.
commands
The subcommand handlers. Each returns an exit code; a hard error propagates and main prints a redacted message + exits 1. Output is identity-based and never prints a credential byte (the A11 egress guarantee) - the only reader of a Secret is inside the adapters/store.
mcp
A read-only stdio MCP server: an agent can SEE which account is active but can NEVER switch it. Hand-rolled newline-delimited JSON-RPC 2.0 (mirrors the sessionwiki MCP). Two tools, both readOnlyHint: whoami, list_accounts. Field allowlist + secret-free errors (A13); no switch/add/use tool exists.
native_sessions
Recent sessions read STRAIGHT from each tool’s own on-disk store - no sessionwiki required. Claude Code: ~/.claude/projects/**/<uuid>.jsonl (line objects carry cwd and the user messages). Codex: ~/.codex/sessions/**/rollout-<ts>-<uuid>.jsonl. Resume uses each tool’s native mechanism (claude --resume <id> in the session’s cwd, codex resume <id>), the same semantics sessionwiki uses.
paths
One override-first path resolver per tool. Every canonical credential path goes through here so tests can redirect to a temp tree and never touch a real login. Precedence: explicit root (tests) > tool env var > home dir.
portable
Move an account SETUP to another machine - never the logins.
proc
Best-effort detection of a running claude / codex process, used to warn before a switch that could disrupt a live session (a running session holds the old token and can overwrite the just-switched login on its next refresh).
proxy
Proxy mode: a loopback HTTP server that forwards Claude Code’s API traffic upstream, choosing the account per request so a running conversation can change accounts. Credentials are read from slots and never copied, and neither prompt content nor any token value is ever logged.
quota
swapdex quota - the ONE network path in swapdex.
quota_cache
Last-known usage per account, so a busy endpoint does not blank the display.
refresh
Renewing a slot’s access token.
secret
Credential bytes wrapper: never prints, zeroizes on drop. The ONLY way to read the bytes is expose(), which is easy to grep for in review. No #[derive(Debug)] in the credential path relies on this type.
service
Run the proxy as a managed service, so it outlives a terminal and comes back by itself.
session_link
Attribute sessions to the account that was active when they ran, by joining the switch timeline with session start times. Attribution is best-effort: a session with no prior switch event is unattributed (a first-class bucket), and a missing/older sessionwiki degrades gracefully (A14).
settings
Persisted preferences: <store_dir>/settings.json. Deliberately tiny - one flat file, every field optional, an unreadable or half-written file falling back to defaults rather than failing a command. Nothing here is a credential.
shim
The claude shim: a tiny launcher placed on the user’s PATH (ahead of the real claude) that reads swapdex’s default-account pointer and runs the real claude in that account’s slot. This is what makes a plain claude follow swapdex use. No credential is ever moved - the shim only sets CLAUDE_CONFIG_DIR.
slots
The permanent-slot registry: a name -> slot mapping persisted to <store_dir>/slots.json. Each slot is a directory under <store_dir>/slots/<id>/ handed to the tool as its own home - Claude’s CLAUDE_CONFIG_DIR, Codex’s CODEX_HOME. swapdex never writes a credential into a slot; the tool’s own login does. The id is opaque and name-independent so a rename never changes the directory (and therefore never changes the Keychain service, which is derived from the dir string).
store
The profile store at ~/.local/share/swapdex: named snapshots, a switch timeline, an active-name hint, a cross-process lock, and bounded backups. Everything is 0600, the store dir 0700; it holds plaintext refresh tokens and is single-machine, single-user - never sync it.
tui
The persistent full-screen UI (swapdex ui on a real terminal), ccusage- style by user request: the screen clears, the UI stays up, and everything happens inside it. Switching shows its result in the status line and REFRESHES the list in place; landing in a conversation (resume or new) is the one action that leaves - by design, that is the goal of a switch.
usage
Local, no-network usage read. Sums tokens from each tool’s on-disk session transcripts over recent windows (5h / 7d) so you can tell how heavily you have been using an account and when to switch. Reads ~/.claude/projects and ~/.codex/sessions only - never the network.
util
Small helpers. redact_path replaces the home dir with ~ so no error or status line leaks a username.
whereis
Which account holds a conversation.