A couple of months ago I wrote about the surprisingly persistent annoyance of switching between multiple accounts in Claude Code, Codex CLI, and Gemini CLI . That post was half technical note, half frustration log, and half, “why am I manually moving credential files around like this is a normal thing to do in 2026?” Yes, that is three halves. That is also what the workflow felt like.

Since then, the tools have improved, the models have improved, and the coding-agent workflow has become more serious. The one piece that still felt too messy was account context. I have work accounts, personal accounts, client accounts, API-key profiles, OAuth profiles, and different tools for different jobs. I do not want to log out, log in, reauthorize in a browser, copy hidden files around, or keep a mental map of which terminal tab is currently burning which quota.

So I built the first version of AI Switcher, or simply:

aisw

aisw is a named profile and context manager for AI coding agents. In its first usable release, it supports Claude Code, Codex CLI, and Gemini CLI. The basic idea is simple: store accounts as named profiles, map them into reusable contexts when needed, and switch deliberately. The real payoff is not saving a few keystrokes. It is making account context explicit, repeatable, inspectable, and much less ridiculous.

The real problem is not one account, it is the credential zoo

Most coding-agent CLIs still feel designed around the simplest possible user: one developer, one account, one machine, one happy path. That model falls apart quickly in real work.

Maybe your employer has a team account. Maybe you have a personal Claude subscription. Maybe you use Codex with one workspace and API keys for another. Maybe you are doing client work where the client’s credentials and your own credentials must not mix. Maybe you just want to compare Claude Code, Codex CLI, and Gemini CLI on the same repository without turning your shell profile into a crime scene.

The pain is not theoretical. Claude Code users have been asking for named account profiles so they do not have to go through a full browser login flow every time or keep swapping ~/.claude.json by hand. Codex users are asking for essentially the same thing, including first-class multi-account auth via --auth-profile and a cleaner way to isolate personal, work, and client state without juggling CODEX_HOME or repeatedly logging in and out. That same theme shows up again in a newer request for account and workspace switching in Codex , and Gemini CLI users are asking for profile support or a configurable config path so switching between a personal account and an API-key setup stops being a pile of local scripting.

That is exactly the gap aisw tries to fill. Not by replacing these tools, not by proxying prompts, and not by becoming some giant AI operating system. Just by handling the one practical workflow that keeps showing up across all of them: I have more than one account. Please let me switch safely.

Implementation note

The core design choice is that aisw does not invent a fake universal auth layer. Profiles store managed per-tool state under ~/.aisw/profiles/<tool>/<name>/, while ~/.aisw/config.json keeps only metadata and active selections. Contexts are deliberately thinner: they are just named mappings across existing profiles. If you want the storage and boundary details, the best places to look are the security notes and the profile/context sections in the aisw repository .

What shipped in the first release

aisw lets me create named profiles for each supported tool and activate them later. A profile can represent a work account, a personal account, a client account, a CI profile, or any other context I care about.

aisw init

aisw add claude work --api-key "$ANTHROPIC_API_KEY"
aisw add claude personal

aisw add codex work --api-key "$OPENAI_API_KEY"
aisw add codex personal

aisw add gemini work --api-key "$GEMINI_API_KEY"
aisw add gemini personal

Switching one tool is explicit:

aisw use claude work
aisw use codex personal
aisw use gemini work

Switching all tools that share the same profile name is one command:

aisw use --all --profile work

That works when the profile names line up. The more interesting feature is contexts. Real setups often do not line up neatly across tools, so aisw lets me map mixed profiles into one saved work mode:

aisw context create client-acme \
  --claude acme-claude \
  --codex acme-codex \
  --gemini acme-gemini

aisw context use client-acme

That is a much better model than pretending every vendor tool will naturally share the same profile names forever. I do not use one coding agent. I switch between them depending on the task, the repository, the model, the quota, the provider, and sometimes simple curiosity. Account switching should not be solved three different ways for three different CLIs. It should be a normal developer workflow.

Implementation note

The tricky part is that each upstream CLI behaves differently. Claude can split auth across a credential file, macOS Keychain, and OAuth account metadata in ~/.claude.json. Codex leans on CODEX_HOME. Gemini can mix config files and API-key flows. aisw does not normalize that away. It captures each tool’s real live state, stores it in a managed profile, and then lets contexts compose those profiles into something closer to an actual work mode.

Here is a short demo of a few of the workflows that matter most in practice:

A short demo of aisw handling profile and context-oriented account switching workflows across supported AI coding CLIs.

Switching from work mode to personal mode without logging out of everything

The most obvious case is the daily work and personal switch. During the day I may want Claude Code, Codex CLI, and Gemini CLI attached to work credentials. Later, I might be hacking on an open-source project or a personal app and I do not want those sessions mixed with company credentials, company billing, company policy, or company history.

The manual version of this is depressing. You inspect environment variables. You inspect hidden directories. You run login commands. You open a browser. You hope OAuth picks the right account. You maybe delete a file. You maybe copy it back. You definitely say something impolite about the state of developer tooling.

The aisw version is this:

aisw use --all --profile work
aisw status

Then later:

aisw use --all --profile personal
aisw status

That is not magic. It is just the right kind of boring. The command says what I mean. The status command tells me what is active. If I have Claude, Codex, and Gemini profiles with the same name, I can move the whole AI coding environment from one context to another instead of babysitting each tool separately.

And if the names do not line up, contexts give me the same one-command switch without forcing fake symmetry into the profile naming.

Keeping client credentials from turning into soup

The second problem is client work. If you are consulting, contracting, advising, or moving between organizations, account separation is not just convenience. It is hygiene.

It is easy for “I will just quickly switch accounts” to become “why is this project using my personal quota?” or, worse, “why did this tool load state, instructions, or credentials from the wrong environment?”

With aisw, I can name the context directly:

aisw add claude client-acme --api-key "$ANTHROPIC_API_KEY"
aisw add codex client-acme --api-key "$OPENAI_API_KEY"
aisw add gemini client-acme --api-key "$GEMINI_API_KEY"

aisw use --all --profile client-acme

Now client-acme is not a folder I need to remember, not a shell alias buried in .zshrc, and not a credential file I renamed manually. It is a first-class profile name. When I am done, I can leave the context just as explicitly:

aisw use --all --profile personal

This is where the cross-agent angle matters. The future of AI coding is not one blessed CLI forever. Developers already mix tools. Teams already compare tools. Some tasks feel better in Claude Code, some in Codex, some in Gemini, and whatever comes next will add another credential directory to the pile. aisw treats account context as the thing I am switching, not just the individual vendor tool.

Knowing what is active before I burn the wrong quota

The third problem is visibility. When account state is implicit, I eventually stop trusting my own terminal.

Am I in work Claude or personal Claude? Did Codex pick up the right CODEX_HOME? Is Gemini using the API-key profile or the OAuth profile? Did I switch this shell or only another shell? Did I just spend ten minutes debugging a permissions issue that was really just the wrong account?

That is why aisw status exists.

aisw status

The goal is simple: one place to inspect the current state across supported tools. I want to see what is installed, what profile is active, and whether live credentials match what aisw thinks should be active.

That sounds small, but it is the difference between “probably fine” and “I can actually see what is going on.”

There is also JSON output for scripting:

aisw status --json
aisw list --json

That makes the same profile model useful in automation and CI. I do not want one fragile setup for my laptop and a different pile of special-case shell scripts for non-interactive usage. If I can name a profile locally, I should be able to use the same concept in scripts.

One detail I cared about from the start is that aisw should work with the state people already have. aisw init and profile creation can import accounts you are already logged into. That matters because the most annoying version of profile management is building a tool whose first step is “please log into everything again from scratch.” aisw can capture live state and turn it into named profiles instead of pretending your current setup does not exist.

Implementation note

Importing existing state is more subtle than it sounds. For Claude OAuth capture, aisw intentionally does not set CLAUDE_CONFIG_DIR during login because that changes Claude’s own behavior. Instead it lets Claude run natively, then polls the live credential file and the OS keychain for changes and snapshots the result. Gemini takes almost the opposite approach: it can run OAuth in a temporary GEMINI_CLI_HOME scratch directory so the flow does not pollute the live account. Those are the kinds of boring edge cases that determine whether a tool feels trustworthy.

The safety features matter more than the switch itself

One thing the first round of feedback made very clear is that a profile switcher is only useful if it behaves predictably when something goes wrong. That is why switching in aisw is transactional. It snapshots current state, applies the new profile or context, and keeps rollback and backup behavior available if something fails or if I want to restore a previous state later.

That sounds operationally dull, which is exactly why it is useful. Tools that mutate credential state should fail predictably. They should not leave me halfway between accounts because one tool switched cleanly and another did not.

That same design shows up in the rest of the tool:

  • Profiles are one tool’s saved auth state.
  • Contexts are a named multi-tool work mode built from profiles.
  • Backups and restore commands make reversibility explicit.
  • doctor and status commands exist because hidden auth state eventually drifts.

That is the kind of design I want around credentials: less magic, more inspectability.

Implementation note

The rollback path is one of the more important parts of the project. aisw stages file writes into temporary .aisw-stage-* files, snapshots original live state before mutation, refuses to touch symlinks, preserves file modes, and only renames staged files into place on commit. If a multi-file switch fails halfway through, it walks the snapshot in reverse and restores the previous state. That matters most for Claude, where a correct switch can mean keeping the credential payload and ~/.claude.json metadata in sync rather than updating one and silently breaking the other.

The project is already moving beyond profile swapping

A profile switcher is already helpful, but the real failure mode is often using the wrong account in the wrong repository. That is why the project has already started moving toward workspace binding and guardrails.

aisw has commands to bind a workspace or git-remote pattern to a saved context and then check or guard that mapping. In practice, that means I can make “this repo should use client-acme context” an explicit rule instead of a memory exercise.

That is a more serious answer than a handful of shell aliases because it acknowledges the actual problem: not just switching accounts, but keeping account context aligned with the repository I am in.

This is also the part that feels most like an evolution from the original post. The first frustration was “switching accounts is annoying.” The next, more important realization was “the active account should follow the work.” Once you start moving between employers, clients, personal projects, and different agent tools, profile switching alone is not enough. The tool needs to help keep context attached to the repo and workflow where it belongs.

Implementation note

Workspace guardrails are more than a single “current repo” flag. Resolution is layered: repo-local binding in .git/info/aisw.json wins first, then longest path-prefix rules, then git-remote glob matches like github.com/acme/*, then the default context. The shell hook wraps claude, codex, and gemini, checks the resolved expectation before launch, and can either warn or block in strict mode. If you care about the mechanics, the workspace docs are worth a look because this is where the project starts becoming more than a profile copier.

This is not a prompt router, and that is on purpose

It would be easy to make this sound bigger than it is. I could call it an “AI agent context orchestration layer” and immediately ruin the project. I am not doing that.

aisw does not proxy model traffic. It does not inspect prompts. It does not choose models. It does not hide vendors behind another abstraction. It does not manage quotas. It does not try to refresh OAuth tokens itself. It does not upload credentials to a service. It does not run a daemon in the background. It is a local CLI that manages named profiles for tools I already use.

That boundary matters because this tool touches credentials. The correct posture is boring, local, explicit, and auditable. Credentials stay on the machine. Where possible, aisw uses the native secure storage of the operating system: macOS Keychain, Linux Secret Service, or Windows Credential Manager. File-backed profile material is stored locally with owner-only permissions. Switching snapshots current state before it mutates anything, then rolls back if applying the new profile fails.

In other words, the tool should make account switching safer, not become a new place where credentials go to disappear.

Why I care about this now

AI coding agents are no longer toys I open once a week. They are becoming part of the normal development loop. That raises the quality bar for the surrounding tooling. When a tool becomes daily infrastructure, rough edges around authentication, profiles, project context, and account boundaries become expensive. They interrupt flow, create billing confusion, and make it too easy to use the wrong account in the wrong repository.

The issue trackers show the same pattern from different angles. Claude users want named profiles and account labels. Codex users want --auth-profile, workspace switching, and environment isolation. Gemini users want profile or config-path switching and clearer active-account visibility. The implementation details differ per vendor, but the underlying user problem is the same: modern developers work across multiple accounts and multiple agent tools, and the tooling should acknowledge that.

aisw is my attempt to solve that problem from the outside in a simple way. I do not need every vendor to agree on a profile standard before I can stop manually swapping auth files. I can put a small, local, explicit switcher in front of the tools and make my workflow sane today.

Install

You can install aisw with Homebrew:

brew tap burakdede/tap
brew install aisw

Or with the shell installer:

curl -fsSL https://raw.githubusercontent.com/burakdede/aisw/main/install.sh | sh

Or with Cargo:

cargo install aisw

Then run:

aisw init

init creates the local ~/.aisw/ directory, offers shell integration, and can import accounts you are already logged into so you do not have to start from scratch.

A small complete example

Here is the whole workflow in one place:

# Bootstrap aisw
aisw init

# Capture or create profiles
aisw add claude work --api-key "$ANTHROPIC_API_KEY"
aisw add claude personal

aisw add codex work --api-key "$OPENAI_API_KEY"
aisw add codex personal

aisw add gemini work --api-key "$GEMINI_API_KEY"
aisw add gemini personal

# Or define a mixed-account context when names differ
aisw context create client-acme \
  --claude acme-claude \
  --codex acme-codex \
  --gemini acme-gemini

# Start the work day
aisw use --all --profile work
aisw status

# Switch to personal projects later
aisw use --all --profile personal
aisw status

# Or activate the mixed client setup directly
aisw context use client-acme

That is the spirit of the first release. Make the hidden state visible. Give accounts names. Support real mixed-account setups. Switch deliberately. Stop treating credential directories as something developers should manually juggle forever.

Try it

The project is here:

burakdede/aisw on GitHub

This is not trying to be a grand platform. It is the first useful cut of a tool I wanted in my own day-to-day work, shaped both by the original pain and by the feature requests that keep surfacing around these CLIs: one sane way to switch accounts across the AI coding agents I actually use.

A GitHub issue comment thanking Burak for building aisw and helping make multi-account Claude and Codex workflows less painful.

This kind of feedback is still my favorite part of open source and developer tooling. You find an itch, scratch it hard enough, and if you are lucky it turns into something genuinely useful for other people too.