Skip to content

sadjow/aith

Repository files navigation

aith

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.

Supported Surfaces

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 through CURSOR_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.

Status

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.

Quick Start

Use devenv to enter the pinned Rust development environment:

devenv shell
cargo run -- status
cargo run -- status codex-desktop

Installation

While the repository is private, install from GitHub with SSH access:

cargo install --git git@github.com:sadjow/aith.git --locked

After 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/aith

Release process details live in docs/releasing.md.

Save the current Codex CLI login as a profile:

cargo run -- save codex-cli personal

Inspect 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 personal

Inspect backups created by profile switches:

cargo run -- backups codex-cli
cargo run -- restore codex-cli auth-1778702155-74626.json

Run one command with a saved Codex CLI profile without switching your active login:

cargo run -- exec codex-cli personal -- codex

Start a shell with a saved Codex CLI profile without switching your active login:

cargo run -- shell codex-cli personal

Save 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 -- claude

Save 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-agent

Remove a saved Codex CLI profile:

cargo run -- remove codex-cli old-client

Commands

Tools

List supported tools:

aith tools

Status

Show 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-desktop

Doctor

Show 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-desktop

For 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

Save the current auth state as a named profile.

aith save codex-cli personal

add is an alias for save:

aith add codex-cli work

Profiles can be overwritten explicitly:

aith save codex-cli personal --force

Claude 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_WORK

Non-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 \
  --force

aith refuses literal values for sensitive names such as ANTHROPIC_API_KEY; use --from-env for secrets.

List

List saved profiles for a tool:

aith list codex-cli
aith list claude-code
aith list cursor-agent

Desktop app targets do not support saved profiles yet.

Current

Detect which saved profile matches the active auth state:

aith current codex-cli
aith current claude-code
aith current cursor-agent

Possible 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.

Use

Switch a tool to a saved profile:

aith use codex-cli personal

For Codex CLI, this replaces the active auth.json with the saved profile snapshot. The previous active auth.json is backed up first.

Remove

Remove a saved profile:

aith remove codex-cli old-client
aith remove claude-code old-client
aith remove cursor-agent old-client

By 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 --force

This removes only the saved profile directory. It does not touch active Codex CLI auth and does not delete backups.

Backups

List backups created before profile switches or restores:

aith backups codex-cli
aith backups claude-code
aith backups cursor-agent

Env 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

Restore a backup into the active auth location:

aith restore codex-cli auth-1778702155-74626.json

For 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.

Exec

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-agent

For 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.

Shell

Start a shell with a temporary profile-scoped auth environment:

aith shell codex-cli personal
aith shell claude-code work
aith shell cursor-agent work

For 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.

Storage

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.

Claude Code Discovery and Env Profiles

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_DIR or ~/.claude
  • User settings: settings.json
  • User state: ~/.claude.json
  • Project settings: .claude/settings.json and 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:

Cursor Agent Env Profiles

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.

Desktop App Discovery

aith tracks desktop apps separately from CLI and terminal agent targets:

  • codex-desktop
  • claude-desktop
  • cursor-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.

Safety Model

  • Credential file contents are never printed by status/doctor/current/list commands.
  • Profile names are limited to ASCII letters, numbers, -, and _.
  • use and restore create a backup before replacing active Codex CLI auth.
  • exec runs with a temporary CODEX_HOME and does not modify active Codex CLI auth.
  • shell starts a temporary CODEX_HOME session 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 exec or shell starts.
  • 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.
  • remove refuses to delete the active matching profile unless --force is passed.
  • restore only accepts generated backup IDs in the form auth-<timestamp>-<pid>.json.
  • Claude Code, Cursor Agent, and desktop global login switching intentionally return “not implemented yet” until their auth models are handled explicitly.

Development

This project uses devenv to provide a pinned Rust toolchain matching rust-version in Cargo.toml.

devenv shell
cargo check
cargo test
cargo run -- status

Common 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 ci

Integration 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.

Continuous Integration

GitHub Actions runs the same checks as the local CI script on pushes to main and pull requests:

devenv shell ci

The workflow installs Nix and devenv, then runs the pinned Rust toolchain from devenv.nix.

Release automation uses cargo-dist through dist-workspace.toml.

Project Structure

  • 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.

Design Direction

  • 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.

About

Native CLI for profile-scoped AI coding tool auth across Codex CLI, Claude Code, and Cursor Agent.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors