@praeviso/code-env-switch
v0.1.10
Published
Switch between Claude Code and Codex profiles from a single CLI
Downloads
320
Readme
code-env-switch
A tiny CLI to switch between Claude Code and Codex profiles.
Features
- Manage multiple profiles and switch by name or type
codenv useprints shell commands for the current terminal- Interactive profile creation and selection
- Optional cleanup via
removeFilesand post-switchcommands - Config auto-discovery and type-based default
unsetkeys
Quick start
- Install:
npm install -g @praeviso/code-env-switch- Add profiles interactively (this creates
~/.config/code-env/config.jsonif missing):
codenv add
# run it again to add the second type
codenv addExample session:
$ codenv add
Select type (1=codex, 2=claude): 1
Profile name (default: default): primary
Base URL (required): https://api.example.com/v1
API key (required): YOUR_API_KEY- Set defaults per type:
codenv default codex primary
codenv default claude default- Enable auto-apply in your shell:
codenv initOpen a new terminal (or source ~/.bashrc / source ~/.zshrc) to auto-apply the defaults.
For local development install:
npm install -g .
# or
npm linkUsage
By default,
codenv useonly outputs shell commands. After runningcodenv init, the shell wrapper applies them automatically. The snippet also wrapscodex/claudeto bind sessions to profiles; usecommand codex/command claudeto bypass. When you switch profiles within the same session, usage tracking and cost display follow the most recently applied profile for subsequent tokens.
Common commands
codenv list
codenv show codex primary
codenv default codex primary
codenv remove codex primarycodenv list (or codenv ls) prints a table with PROFILE, TYPE, and NOTE. Default profiles are labeled in the NOTE column, and the active profile is shown in green.
If profile.name is set, it is shown in PROFILE. Otherwise the profile key is shown (with legacy type- prefixes stripped when possible).
Reset usage history
codenv usage-reset
# skip confirmation
codenv usage-reset --yesThis deletes usage history files (usage.jsonl, usage state, profile-log.jsonl, statusline-debug.jsonl) plus any backup variants in the config directory.
Add / update a profile
codenv add primary OPENAI_BASE_URL=https://api.example.com/v1 OPENAI_API_KEY=YOUR_API_KEY --note "Primary endpoint"
# with explicit type (codex/claude, claude also accepts cc)
codenv add --type codex primary OPENAI_BASE_URL=https://api.example.com/v1 OPENAI_API_KEY=YOUR_API_KEYWhen --type is set, the profile name is kept as-is and type is stored separately.
Profiles are keyed by an internal id; the human-facing name lives in profile.name.
Codex profiles continue to store OPENAI_BASE_URL and OPENAI_API_KEY in the
JSON config for backward compatibility. When a Codex profile is applied,
codenv now unsets those shell variables, writes ~/.codex/config.toml with
model_provider = "OpenAI" plus a [model_providers.OpenAI] block, and writes
~/.codex/auth.json with the matching API key.
Interactive add (default):
codenv addRemove a profile
codenv remove primary
# or by type + name (recommended when names overlap)
codenv remove codex primary
# multiple at once
codenv remove codex primary claude default
# (legacy keys like codex-primary also work)
codenv remove codex-primary claude-default
# remove all
codenv remove --allSwitch in the current shell (bash/zsh)
codenv use
# use up/down then Enter (q to exit)
codenv use primary
# or by type + name (also matches legacy keys like codex-primary)
codenv use codex primary
codenv use cc primaryFirst run codenv init once to install the shell wrapper:
codenv init
# or target a specific shell
codenv init --shell zshThis wrapper makes codenv use and codenv unset apply automatically in the
current shell. To print the snippet without writing to rc, use
codenv init --print.
For Codex profiles, the generated shell snippet keeps reading the legacy
OPENAI_* values from your codenv profile, but the applied runtime state now
comes from ~/.codex/config.toml and ~/.codex/auth.json instead of exported
OPENAI_BASE_URL / OPENAI_API_KEY variables.
Auto-apply default profiles (per type)
Set a default per type (codex/claude) and re-run codenv init:
codenv default codex primary
codenv default claude default{
"defaultProfiles": {
"codex": "primary",
"claude": "default"
}
}On new terminal sessions, codenv will auto-apply all defaults via codenv auto.
To clear all defaults, run codenv default --clear (with confirmation).
One-off without init:
eval "$(codenv use codex primary)"Note: the change takes effect in new terminals. To apply immediately, run:
source ~/.bashrc
# or for zsh
source ~/.zshrcUnset known keys
codenv unset
# or one-off without init
eval "$(codenv unset)"For Codex, codenv unset also restores the previous ~/.codex/config.toml and
~/.codex/auth.json state captured before the last codenv-managed switch.
Fish shell
codenv use codex primary
# or one-off without init
codenv use codex primary | sourceConfig lookup order
codenv searches in this order:
--config <path>CODE_ENV_CONFIG~/.config/code-env/config.json
Use codenv config to print the path selected for the current directory.
If nothing is found, codenv add writes to ~/.config/code-env/config.json.
Config format
{
"unset": [],
"defaultProfiles": {
"codex": "primary",
"claude": "default"
},
"codexStatusline": {
"items": ["model-with-reasoning", "context-remaining", "current-dir", "git-branch"]
},
"claudeStatusline": {
"command": "codenv statusline --type claude --sync-usage",
"type": "command",
"padding": 0
},
"pricing": {
"models": {
"Claude Sonnet 4.5": {
"input": 3.0,
"output": 15.0,
"cacheWrite": 3.75,
"cacheRead": 0.3,
"description": "Balanced performance and speed for daily use."
}
}
},
"profiles": {
"p_a1b2c3": {
"name": "primary",
"type": "codex",
"note": "Primary endpoint",
"env": {
"OPENAI_BASE_URL": "https://api.example.com/v1",
"OPENAI_API_KEY": "YOUR_API_KEY"
},
"removeFiles": ["$HOME/.config/example/auth.json"],
"commands": ["echo \"Switched to codex primary\""]
}
}
}Notes:
unset: global keys to clear. Type-specific defaults are applied only for the active type and won't clear the other type.defaultProfiles: optional; map ofcodex/claudeto profile name or key used bycodenv auto.codexStatusline: optional; config to inject official Codex TUI status line settings when launchingcodex.items: string[]; ordered item IDs written totui.status_linein~/.codex/config.toml.- Supported item IDs include:
model-name,model-with-reasoning,current-dir,project-root,git-branch,context-remaining,context-used,five-hour-limit,weekly-limit,codex-version,context-window-size,used-tokens,total-input-tokens,total-output-tokens,session-id. configPath: optional; override~/.codex/config.toml(also supportsCODE_ENV_CODEX_CONFIG_PATH).- If
itemsis unset,codenvleaves Codex status-line config unchanged (Codex defaults apply).
claudeStatusline: optional; config to inject Claude Code statusLine settings when launchingclaude.command: string (or string[]; arrays are joined into a single command string).type: string; statusLine type (default:command).padding: number; statusLine padding (default: 0).settingsPath: optional; override~/.claude/settings.json(also supportsCODE_ENV_CLAUDE_SETTINGS_PATH).
pricing: optional; model pricing (USD per 1M tokens) used to convert token usage to dollar amounts in the status line.models: map of model name to pricing. Keys are matched case/format-insensitively.input/output/cacheRead/cacheWrite: token rates.- Cost display uses the profile pricing model if set; otherwise the status line model label. No breakdown => no cost.
name: human-facing profile name shown incodenv listand used bycodenv use <name>.type: optional;codexorclaude(aliascc) forcodenv use <type> <name>matching.note: shown incodenv list.removeFiles: optional;codenv useemitsrm -ffor each path. Codex profiles also remove~/.codex/auth.json.pricing(profile): optional; per-profile pricing override. Supportsmodelplusinput/output/cacheRead/cacheWrite.multiplier: optional; scale pricing (number).
ANTHROPIC_AUTH_TOKEN: whenANTHROPIC_API_KEYis set,codenv usealso exportsANTHROPIC_AUTH_TOKENwith the same value.commands: optional; emitted as-is in the switch script.
Security
Your config contains API keys. Keep it private and out of public repositories.
Development
npm install
npm run build