AI Usage Toggle
One status bar item per AI tool — Claude Code, Claude CLI, Gemini CLI, Cline, Gemini Code Assist,
and (optionally) Codex CLI — so you can switch each between account/subscription login and an API
key independently, as far as each tool actually allows.
A tool is what shows up in the status bar. A lever is the actual control surface this
extension can pull. Most tools map to one lever; not every tool has an independent one, because
most of these extensions don't expose a per-extension key setting — they just read
ANTHROPIC_API_KEY / GEMINI_API_KEY from the process environment, same as a CLI would:
| Tool |
Lever |
How it's set |
| Claude Code |
claude-code (independent) |
Claude Code's own claudeCode.environmentVariables setting |
| Claude CLI |
claude-shared |
ANTHROPIC_API_KEY in the environment |
| Gemini CLI |
gemini-shared |
GEMINI_API_KEY in the environment |
| Gemini Code Assist |
gemini-shared |
GEMINI_API_KEY in the environment |
| Cline |
claude-shared and gemini-shared |
ANTHROPIC_API_KEY / GEMINI_API_KEY, used only when Cline's own in-app key field for that provider is left blank |
| Codex CLI (hidden by default) |
openai-shared |
OPENAI_API_KEY in the environment |
Because Claude CLI, Gemini CLI, Gemini Code Assist, and Cline's fallback all read the same process
environment, switching one of the *-shared levers switches every tool on it at once — there's no
way around that without each extension exposing its own setting. Claude Code is the one exception:
it has claudeCode.environmentVariables, so its lever is fully independent of everything else.
Cline shows up with two lever states (Claude: Max / Account, for example) and always opens a
picker on click, since it straddles two levers.
| Built-in mode id |
Status bar |
Effect |
claude-code-max / claude-code-api |
Claude Code item |
no key / writes claudeCode.environmentVariables (independent) |
claude-max / claude-api |
Claude CLI, Cline items |
no key / ANTHROPIC_API_KEY in the environment (shared) |
gemini-account / gemini-api |
Gemini CLI, Gemini Code Assist, Cline items |
no key / GEMINI_API_KEY in the environment (shared) |
openai-account / openai-api |
Codex CLI item |
no key / OPENAI_API_KEY in the environment (shared) |
- Keys live in VS Code
SecretStorage (Windows Credential Manager / macOS Keychain), one per mode.
- Shared-lever env vars are injected via
environmentVariableCollection (non-persistent, so keys are never written to VS Code state files; re-applied at startup) and mirrored onto process.env so extensions that spawn their own processes (like Gemini Code Assist) see them too.
- The Claude Code lever instead writes
claudeCode.environmentVariables directly, since Claude Code does not read process.env for its key.
- Each lever's active mode survives restarts (
globalState).
AI Chat Sync
The AI Chat Sync view (Explorer sidebar) lists recent Claude Code, Gemini, Codex (OpenAI), and Cline chats, each with project, branch, and time. Click the arrow button on a chat (or right-click, Pick Up in Other Tool) to bring it to any of the other three.
Move, Copy, or Summarize
Picking up a chat first asks how:
- Move (default): the full conversation, written as a native session the target tool can resume. This is the original one-click behavior.
- Copy: copies the full conversation to the clipboard as plain text. Nothing tool-specific is written and the original chat is untouched — paste it anywhere.
- Summarize & start new: condenses the conversation to one recap turn (the original request, the deduped list of actions taken like
edited a.ts / ran: npm test, and the most recent exchange verbatim), then starts that fresh in the target tool. This is a deterministic text digest, not an AI-generated summary — cheap and reproducible, at the cost of losing the reasoning in between. Useful for a chat that's gotten too long to move wholesale.
Then pick the target tool and confirm the folder/branch:
- Checks git first: if the folder is on a different branch than the chat, it offers the worktree that has the branch, or lets you stay.
- Keeps your messages, the replies, and one-line notes like
edited a.ts or ran: npm test. Drops tool output and thinking. Capped by aiUsageToggle.sync.maxChars.
- To Gemini: writes a Gemini checkpoint. Launch in terminal opens
gemini in the folder and copies /chat resume sync-<id> to your clipboard.
- To Claude Code: writes a Claude session and launches
claude --resume <id>.
- To Codex: writes a rollout under
~/.codex/sessions/ and launches codex resume <id>. Reading Codex chats is checked against real rollout files; writing one is untested, so please report problems.
- To Cline: Cline has no "resume an existing session" API, only a "start a new task" URI (
vscode://saoudrizwan.claude-dev/task?prompt=...). So picking up into Cline always starts a fresh task seeded with the conversation as a single prompt — there's no native Cline session file to write. Move and Summarize both go through this path; only Copy avoids it.
- Reading from Cline: scans
~/.cline/data/sessions/ (or CLINE_DATA_DIR/CLINE_DIR if set), Cline's actual on-disk session format as of v4.1.25. Unwraps the <user_input>/<mode_notice> tags Cline adds around your prompts and drops its internal tool-result feedback blocks. Reading has been checked against real session files; writing (Move/Summarize into Cline) is less tested than the terminal-based tools since it goes through a URI launch rather than a file this extension controls end to end — please report problems.
- The launched terminal (or Cline task) inherits the current usage mode's API key, so toggle first, then pick up.
- A plain-text copy of the full original conversation is always written to your temp folder as a fallback, even when you chose Summarize.
Settings
aiUsageToggle.sync.sessionLimit (default 30 per tool) and aiUsageToggle.sync.maxChars (default 60000).
aiUsageToggle.visibleTools: which tools get a status bar item. Default: Claude Code, Claude CLI, Gemini CLI, Cline, Gemini Code Assist (Codex CLI is hidden). Use AI Usage: Choose Tools to tick them on and off.
aiUsageToggle.leverOrder: per-lever mode cycle order, e.g. { "claude-shared": ["claude-max", "claude-api"] }. A mode not listed for its lever is disabled on that lever. Edit in Settings, or use AI Usage: Choose Modes (pick the lever, then tick modes).
aiUsageToggle.clickBehavior: cycle (default; single-lever tools cycle, Cline always opens the picker since it has two levers) or menu (always open a pick list).
aiUsageToggle.profiles: your own named modes, as many as you like. Easiest way to add one: AI Usage: Add Profile (pick provider, type, and — for Claude — scope). Each profile appears in Choose Modes and in leverOrder as p:<name>. The name is what the status bar shows.
account: a subscription login. Give it a configDir to keep a second account. It is set as CLAUDE_CONFIG_DIR (Claude), CODEX_HOME (OpenAI), or GEMINI_CLI_HOME (Gemini) — skipped for a claude-code scoped profile, since that lever uses Claude Code's own setting instead. Run the tool once in that mode (the wizard offers Open login terminal) to log in.
api: a key. Each profile has its own key in the credential vault, so you can have two Claude keys. Use AI Usage: Set API Key to change one.
local: an OpenAI-compatible server, always on the openai-shared lever. Sets OPENAI_BASE_URL and OPENAI_API_KEY (placeholder local).
scope (Claude profiles only): shared (default) targets claude-shared (Claude CLI, Cline); claude-code targets the independent Claude Code lever instead.
- Optional
env map and icon (codicon name) on any profile.
"aiUsageToggle.profiles": [
{ "name": "Work Max", "type": "account", "provider": "claude", "scope": "claude-code", "icon": "briefcase" },
{ "name": "Personal key", "type": "api", "provider": "claude" },
{ "name": "Ollama", "type": "local", "baseUrl": "http://localhost:11434/v1" }
],
"aiUsageToggle.leverOrder": {
"claude-code": ["claude-code-max", "p:Work Max"],
"claude-shared": ["claude-max", "p:Personal key"],
"openai-shared": ["openai-account", "p:Ollama"]
}
Chats from a second Claude or Codex account's config folder also show up in the AI Chat Sync view. A chat picked up into Claude or Codex is always written to the default login folder.
The apiKey field on local profiles is plain text in settings; use only a placeholder.
Commands
| Command |
Action |
aiUsageToggle.tool.<id> (e.g. aiUsageToggle.tool.claude-code) |
Click target for each tool's status bar item: cycle (or open the picker, per clickBehavior/multi-lever) |
aiUsageToggle.chooseModes |
Pick a lever, then enable or disable its modes |
aiUsageToggle.chooseTools |
Enable or disable which tools show a status bar item |
aiUsageToggle.addProfile |
Add a named account, API key, or local server |
aiUsageToggle.setApiKey |
Set or update a mode's key (masked input) |
aiUsageToggle.clearApiKey |
Delete a mode's key |
If the active API mode's key is cleared, the extension falls back to an enabled account mode on that lever.
Build and run
npm install
npm run compile
Press F5 to open the Extension Development Host.
Package and install
npx vsce package
code --install-extension ai-usage-toggle-0.0.1.vsix
(Or in VS Code: Extensions view → ... → Install from VSIX.)
Claude Remote Control
With an Anthropic API key active, Claude Code warns "Remote Control requires claude.ai subscription auth". Switching the Claude Code item to claude-code-api shows a warning about this, and the tooltip notes it. Switch back to claude-code-max to use Remote Control.
Caveats
- Claude Code needs a reload. Writing
claudeCode.environmentVariables doesn't hot-reload the running Claude Code process; reload the window (or restart its panel) after switching the Claude Code item.
environmentVariableCollection only affects integrated terminals opened after the change — it does not reach the extension host directly. This extension also mirrors shared-lever values onto process.env in memory so extensions that spawn their own child processes from the host (like Gemini Code Assist's agent) pick them up without a terminal.
- Cline and Gemini Code Assist have no per-extension key setting. The
*-shared env vars are a fallback: Cline only uses them when its own in-app key field for that provider is blank, and Gemini Code Assist uses whatever its own sign-in/key UI resolves first. If you've signed into either tool directly, switching the shared lever here won't override that; clear the tool's own key/account first.
- Switching a
*-shared lever affects every tool on it at once (see the table above) — that's the actual platform limit, not a bug in this extension.