aith is a native CLI for managing account profiles for AI coding tools.
The goal is to make work, personal, and client identities explicit across tools like Codex CLI, Codex Desktop, Claude Code, Claude Desktop, Cursor Agent, and Cursor Desktop without repeated logout/login flows.
aith treats each auth surface separately. A terminal tool and a desktop app can
be logged into different accounts, so they should not share one profile target.
Current command keys:
codex-cli: Codex CLI. Legacy alias:codex.codex-desktop: Codex desktop app.claude-code: Claude Code. Legacy alias:claude.claude-desktop: Claude desktop app.cursor-agent: Cursor Agent or terminal Cursor auth throughCURSOR_API_KEY. Legacy alias:cursor.cursor-desktop: Cursor desktop app.
Desktop app targets are read-only today. They support status and doctor
discovery, but profile switching is intentionally not implemented until their
auth stores are understood well enough to mutate safely.
aith is early. Codex CLI profile management is implemented first because
Codex CLI stores its active auth state in a local auth.json file.
Implemented:
- Tool status checks for Codex CLI, Claude Code, and Cursor Agent.
- Read-only desktop app status checks for Codex Desktop, Claude Desktop, and Cursor Desktop.
- Read-only doctor diagnostics for auth/profile readiness.
- Claude Code auth/config discovery.
- Claude Code env-profile save/list/remove.
- Claude Code one-command and shell-scoped env-profile sessions.
- Cursor Agent env-profile save/list/remove.
- Cursor Agent one-command and shell-scoped env-profile sessions.
- Codex CLI profile save/list/current/use/remove.
- Codex CLI backup list/restore.
- Codex CLI one-command temporary profile execution.
- Codex CLI shell-scoped temporary profile sessions.
- Automatic backup before replacing active Codex CLI auth.
- Private Unix permissions for stored profile directories, auth files, and env profile files.
Not implemented yet:
- Claude Code global login switching, including subscription/Keychain account switching.
- Cursor Agent global login switching beyond terminal API-key sessions.
- Desktop app profile switching for Codex, Claude, or Cursor.
Use devenv to enter the pinned Rust development environment:
devenv shell
cargo run -- status
cargo run -- status codex-desktopWhile the repository is private, install from GitHub with SSH access:
cargo install --git git@github.com:sadjow/aith.git --lockedAfter public releases are available:
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/sadjow/aith/releases/download/v0.1.0/aith-installer.sh | sh
brew install sadjow/tap/aith
npm install @sadjow/aith@0.1.0
cargo install aith --locked
nix run github:sadjow/aithRelease process details live in docs/releasing.md.
Save the current Codex CLI login as a profile:
cargo run -- save codex-cli personalInspect and switch Codex CLI profiles:
cargo run -- list codex-cli
cargo run -- current codex-cli
cargo run -- doctor codex-cli
cargo run -- use codex-cli personalInspect backups created by profile switches:
cargo run -- backups codex-cli
cargo run -- restore codex-cli auth-1778702155-74626.jsonRun one command with a saved Codex CLI profile without switching your active login:
cargo run -- exec codex-cli personal -- codexStart a shell with a saved Codex CLI profile without switching your active login:
cargo run -- shell codex-cli personalSave a Claude Code env profile without storing the secret value:
export ANTHROPIC_API_KEY_WORK=sk-ant-...
cargo run -- save claude-code work --from-env ANTHROPIC_API_KEY=ANTHROPIC_API_KEY_WORK
cargo run -- exec claude-code work -- claudeSave a Cursor Agent env profile without storing the secret value:
export CURSOR_API_KEY_WORK=...
cargo run -- save cursor-agent work --from-env CURSOR_API_KEY=CURSOR_API_KEY_WORK
cargo run -- exec cursor-agent work -- cursor-agentRemove a saved Codex CLI profile:
cargo run -- remove codex-cli old-clientList supported tools:
aith toolsShow safe auth/config status. This checks whether expected files and environment variables exist, but does not print credential values.
aith status
aith status codex-cli
aith status codex-desktop
aith status claude-code
aith status claude-desktop
aith status cursor-agent
aith status cursor-desktopShow a read-only diagnostic report for tool auth paths, relevant environment variables, saved profile counts, backup counts, and current profile detection. Credential file contents are never printed.
aith doctor
aith doctor codex-cli
aith doctor codex-desktop
aith doctor claude-code
aith doctor claude-desktop
aith doctor cursor-agent
aith doctor cursor-desktopFor Claude Code and Cursor Agent, doctor reports both safe path/env status and
saved env profiles. It still warns that global login switching is not
implemented for those tools.
For desktop app targets, doctor reports known app/data paths as read-only and
marks profiles, backups, and current profile detection as unsupported.
Save the current auth state as a named profile.
aith save codex-cli personaladd is an alias for save:
aith add codex-cli workProfiles can be overwritten explicitly:
aith save codex-cli personal --forceClaude Code and Cursor Agent profiles are env-based. aith stores references to
source environment variables, not their values:
export ANTHROPIC_API_KEY_WORK=sk-ant-...
aith save claude-code work --from-env ANTHROPIC_API_KEY=ANTHROPIC_API_KEY_WORK
aith save cursor-agent work --from-env CURSOR_API_KEY=CURSOR_API_KEY_WORKNon-secret settings can be stored as literals:
aith save claude-code work \
--from-env ANTHROPIC_API_KEY=ANTHROPIC_API_KEY_WORK \
--set-env ANTHROPIC_BASE_URL=https://api.anthropic.com \
--forceaith refuses literal values for sensitive names such as ANTHROPIC_API_KEY;
use --from-env for secrets.
List saved profiles for a tool:
aith list codex-cli
aith list claude-code
aith list cursor-agentDesktop app targets do not support saved profiles yet.
Detect which saved profile matches the active auth state:
aith current codex-cli
aith current claude-code
aith current cursor-agentPossible outputs:
codex-cli: personal
codex-cli: unknown
codex-cli: ambiguous
matches personal, duplicate
ambiguous means more than one saved profile has the same auth snapshot. Env
profiles are session-scoped, so aith current claude-code and
aith current cursor-agent report unknown instead of trying to infer a global
active account.
Desktop app targets do not support current profile detection yet.
Switch a tool to a saved profile:
aith use codex-cli personalFor Codex CLI, this replaces the active auth.json with the saved profile
snapshot. The previous active auth.json is backed up first.
Remove a saved profile:
aith remove codex-cli old-client
aith remove claude-code old-client
aith remove cursor-agent old-clientBy default, remove refuses to delete a profile that matches the active auth
state:
Error: profile 'personal' is currently active for codex-cli; pass --force to remove it
Force removal when you intentionally want to delete the saved profile:
aith remove codex-cli personal --forceThis removes only the saved profile directory. It does not touch active Codex CLI auth and does not delete backups.
List backups created before profile switches or restores:
aith backups codex-cli
aith backups claude-code
aith backups cursor-agentEnv profiles do not replace active auth files, so there are no Claude Code or Cursor Agent backups to list.
Example output:
auth-1778702155-74626.json /Users/sadjow/Library/Application Support/aith/backups/codex/auth-1778702155-74626.json
Backup IDs use this generated form:
auth-<timestamp>-<pid>.json
Restore a backup into the active auth location:
aith restore codex-cli auth-1778702155-74626.jsonFor Codex CLI, this copies the selected backup to the active auth.json. The
current active auth.json is backed up first, so restore is reversible.
Run a command with a temporary profile-scoped auth environment:
aith exec codex-cli personal -- codex
aith exec codex-cli work -- codex exec "review this repo"
aith exec claude-code work -- claude
aith exec cursor-agent work -- cursor-agentFor Codex CLI, exec creates a temporary CODEX_HOME, copies the selected
profile's auth.json into it, copies the current Codex CLI config.toml when
one exists, and runs the command with that temporary CODEX_HOME.
The active Codex CLI auth file is not modified, and the temporary directory is
removed after the command exits. aith exec exits with the same status code as
the child command.
For Claude Code and Cursor Agent, exec resolves saved env references at runtime and
starts the child command with those target variables set. Config files, login
state, and Keychain entries are not modified.
Start a shell with a temporary profile-scoped auth environment:
aith shell codex-cli personal
aith shell claude-code work
aith shell cursor-agent workFor Codex CLI, shell stages the selected profile exactly like exec, then
starts your configured shell with CODEX_HOME pointing at the temporary profile
home. This lets separate terminal tabs use different Codex CLI profiles at the
same time.
The active Codex CLI auth file is not modified, and the temporary directory is
removed when the shell exits. aith shell exits with the same status code as
the shell.
For Claude Code and Cursor Agent, shell resolves saved env references and starts your
configured shell with those variables set. This lets separate terminal tabs use
different API-key profiles at the same time when the upstream command honors
terminal auth env vars.
Profiles are stored under AITH_HOME when it is set. Otherwise, aith uses the
platform data directory:
- macOS:
~/Library/Application Support/aith - Linux:
${XDG_DATA_HOME:-~/.local/share}/aith - Windows:
%LOCALAPPDATA%\aith
Codex CLI profiles are stored as:
profiles/codex/<profile>/auth.json
Codex CLI backups are stored as:
backups/codex/auth-<timestamp>-<pid>.json
Env profiles for Claude Code and Cursor Agent are stored as:
profiles/<storage-key>/<profile>/profile.toml
Storage keys remain the short legacy names for compatibility with existing
profiles: codex, claude, and cursor.
Example Claude Code profile:
[env]
ANTHROPIC_API_KEY = { from_env = "ANTHROPIC_API_KEY_WORK" }
ANTHROPIC_BASE_URL = "https://api.anthropic.com"Example Cursor Agent profile:
[env]
CURSOR_API_KEY = { from_env = "CURSOR_API_KEY_WORK" }On Unix, profile directories are created with 0700 permissions and auth files
or profile files are written with 0600 permissions.
aith status claude-code and aith doctor claude-code check known Claude Code
settings and auth surfaces without reading credential contents.
Claude Code discovery checks:
- User config directory:
CLAUDE_CONFIG_DIRor~/.claude - User settings:
settings.json - User state:
~/.claude.json - Project settings:
.claude/settings.jsonand local.claude/settings.local.json - Managed settings path for the current platform
- Terminal auth environment variables such as
ANTHROPIC_API_KEY,ANTHROPIC_AUTH_TOKEN,CLAUDE_CODE_OAUTH_TOKEN, and cloud-provider mode variables
Credential storage differs by platform. On macOS, Claude Code subscription
credentials are stored in Keychain and aith does not inspect Keychain. On
Linux and Windows, Claude Code uses .credentials.json under the Claude config
directory, including CLAUDE_CONFIG_DIR when set.
Claude Code env profiles are intentionally narrower than Codex CLI file-backed
profiles. They do not switch the logged-in Claude Code subscription account.
They only set terminal auth environment variables for
aith exec claude-code ... and aith shell claude-code ... sessions.
References:
aith status cursor-agent and aith doctor cursor-agent check the Cursor user
data path and terminal auth environment without printing credential values.
Cursor Agent env profiles set terminal auth environment variables for
aith exec cursor-agent ... and aith shell cursor-agent ... sessions. They do
not modify Cursor user data or any global login state.
aith tracks desktop apps separately from CLI and terminal agent targets:
codex-desktopclaude-desktopcursor-desktop
Desktop targets are read-only today. aith status <desktop-target> and
aith doctor <desktop-target> check known app bundle, app support, settings,
browser storage, and user-data paths without opening credential-bearing files or
printing credential values.
Desktop discovery intentionally does not inspect macOS Keychain, cookies, LevelDB, IndexedDB, SQLite databases, or app-managed session stores. Those stores may contain sensitive or app-version-specific auth state, so switching is blocked until each desktop auth model has a dedicated, reversible implementation.
- Credential file contents are never printed by status/doctor/current/list commands.
- Profile names are limited to ASCII letters, numbers,
-, and_. useandrestorecreate a backup before replacing active Codex CLI auth.execruns with a temporaryCODEX_HOMEand does not modify active Codex CLI auth.shellstarts a temporaryCODEX_HOMEsession and does not modify active Codex CLI auth.- Env profiles store source env variable names for secrets, not secret values.
Secret values are resolved only when
execorshellstarts. - Claude Code and Cursor Agent env sessions do not modify config files, credential files, user data, or macOS Keychain entries.
- Desktop app auth stores are read-only in current profile operations.
removerefuses to delete the active matching profile unless--forceis passed.restoreonly accepts generated backup IDs in the formauth-<timestamp>-<pid>.json.- Claude Code, Cursor Agent, and desktop global login switching intentionally return “not implemented yet” until their auth models are handled explicitly.
This project uses devenv to provide a pinned Rust
toolchain matching rust-version in Cargo.toml.
devenv shell
cargo check
cargo test
cargo run -- statusCommon one-off checks can run without entering an interactive shell:
devenv shell cargo check
devenv shell cargo fmt -- --check
devenv shell cargo clippy --all-targets -- -D warnings
devenv shell cargo test
devenv shell ciIntegration tests run the real aith binary against temporary fake AITH_HOME,
CODEX_HOME, CLAUDE_CONFIG_DIR, and HOME directories. They do not read or
modify real tool credentials.
GitHub Actions runs the same checks as the local CI script on pushes to main
and pull requests:
devenv shell ciThe workflow installs Nix and devenv, then runs the pinned Rust toolchain from
devenv.nix.
Release automation uses cargo-dist through dist-workspace.toml.
src/cli.rs: command parsing and user-facing output.src/doctor.rs: read-only diagnostic report generation.src/profiles/: shared profile storage, result types, validation, backups, and filesystem safety helpers.src/tools/: tool metadata and tool-specific adapters.src/tools/claude.rs: Claude Code auth/config discovery and env-profile sessions.src/tools/codex.rs: Codex CLI auth/profile behavior.src/tools/cursor.rs: Cursor Agent auth discovery and env-profile sessions.src/tools/desktop.rs: read-only desktop app discovery.src/tools/env_session.rs: shared env-profile session behavior.
- Local-first: credentials never leave the machine.
- Tool-native: use each upstream tool's supported auth and config mechanisms.
- Explicit: profile switches should be visible and reversible.
- Session-friendly: support one-command and shell-scoped temporary identities.