README
codeai
开发初衷,防止Claude封号,并且支持跟随CC Switch 切换到其他供应商的时候切换对应的代理配置。
一个轻量级的 Go CLI 工具,通过按需加载配置文件(Profile)向 AI 命令行程序(如 claude、codex 等)注入环境变量,实现多账号、多模型、多密钥的快速切换。
配合CC Switch 使用体验完美
功能特性
- 多 Profile 管理:为同一程序创建多个配置文件,按需切换
- 环境变量注入:Profile 中定义的变量会覆盖当前 Shell 环境,不污染全局配置
- 自动 Profile 匹配:通过
~/.codeai/setting.json按当前环境变量自动选择 Profile,无需手动指定 - 额外参数支持:Profile 可附带默认启动参数
- 内置代理:可选启动本地 HTTP 代理,按白名单/黑名单规则决定流量走向,支持 IP、CIDR、域名、通配符域名
- 可配置日志级别:默认静默运行,配置
"log_level": "debug"后输出详细调试信息,便于排查问题 - 零依赖:纯 Go 标准库实现,无需安装任何第三方包
安装
可选:移至 PATH
sudo mv codeai /usr/local/bin/使用方法
创建 Profile
codeai init <程序名> <profile名>示例:
codeai init claude default
# 创建 ~/.codeai/claude/default.json编辑 Profile
打开生成的 JSON 文件,填入你的配置:
{
"env": {
"ANTHROPIC_API_KEY": "sk-ant-xxxxxxxx"
},
"args": ["--verbose"],
"log_level": "",
"proxy": {
"enabled": false,
"upstream": "http://user:pass@proxy.host:port",
"mode": "whitelist",
"rules": ["api.anthropic.com", "*.anthropic.com"]
}
}| 字段 | 类型 | 说明 |
|---|---|---|
env |
map[string]string |
注入的环境变量,覆盖当前 Shell 中的同名变量 |
args |
[]string |
启动程序时自动附加的参数 |
log_level |
string |
日志级别,留空或省略时静默运行,设为 "debug" 时输出调试日志至 stderr |
proxy |
object |
内置代理配置,省略或 enabled: false 时不启用 |
proxy 字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
enabled |
bool |
是否启用内置代理 |
upstream |
string |
上游代理地址,格式 http://[user:pass@]host:port |
mode |
string |
"whitelist" 或 "blacklist",见下文 |
rules |
[]string |
匹配规则列表,支持精确 IP、CIDR、域名、通配符域名(*.example.com) |
mode 语义:
| mode | rules 内的主机 | rules 外的主机 |
|---|---|---|
whitelist |
走上游代理 | 直连 |
blacklist |
直连(绕过代理) | 走上游代理 |
工作原理:
启用后,codeai 在本地随机端口(20000–30000)启动一个轻量 HTTP 代理,将子进程的 HTTP_PROXY / HTTPS_PROXY 指向它,同时清空 NO_PROXY。代理根据规则决定每个连接是转发至上游还是直连。子进程退出后代理随即关闭。
启动程序
# 使用 default profile 启动
codeai claude
# 指定 profile(跳过自动匹配)
codeai claude work等效于:
ANTHROPIC_API_KEY=sk-ant-xxxxxxxx claude --verbose自动 Profile 匹配
无需每次手动输入 profile 名称。在 ~/.codeai/setting.json 中配置规则,codeai 启动时会依次评估规则,命中第一条匹配的规则即使用对应的 profile;若无匹配则回退到 default。
~/.codeai/setting.json 示例:
{
"env_profiles": [
{
"program": "claude",
"profile": "work",
"when": { "ANTHROPIC_BASE_URL": "https://work.example.com" }
},
{
"program": "claude",
"profile": "corp",
"when": {
"$and": [
{ "ANTHROPIC_BASE_URL": "https://corp.example.com" },
{ "ANTHROPIC_AUTH_TOKEN": "sk-corp-token" }
]
}
},
{
"program": "claude",
"profile": "personal",
"when": {
"$or": [
{ "ANTHROPIC_BASE_URL": "https://personal.example.com" },
{ "ANTHROPIC_AUTH_TOKEN": "sk-personal-token" }
]
}
}
]
}规则字段说明:
| 字段 | 说明 |
|---|---|
program |
规则作用的程序名,与 codeai <program> 中的程序名对应,不匹配则跳过 |
profile |
命中时使用的 profile 名称 |
when |
匹配条件(见下文) |
when 条件语法:
| 写法 | 含义 |
|---|---|
{ "KEY": "VALUE" } |
环境变量 KEY 的值等于 VALUE |
| 多个顶层 key | 隐式 AND,所有条件均需满足 |
{ "$or": [...] } |
任意一个子条件满足即可 |
{ "$and": [...] } |
所有子条件均需满足 |
$or / $and 可任意嵌套。
查看已有 Profile
codeai list claude
# 输出:
# default
# work
# personal配置文件位置
所有配置文件存放在 ~/.codeai/ 目录下,按程序名分组:
~/.codeai/
├── setting.json # 全局设置:env_profiles 自动匹配规则
├── claude/
│ ├── default.json
│ └── work.json
└── codex/
└── default.json- 目录权限:
0700 - 文件权限:
0600
错误码
| 场景 | 退出码 |
|---|---|
| 未传入参数 | 1 |
| Profile 文件不存在 | 1 |
| JSON 格式错误 | 1 |
| 程序不在 PATH 中 | 127 |
| 子进程退出 | 子进程的退出码 |
init 目标文件已存在 |
1 |
所有错误信息输出至 stderr,以 codeai: 为前缀。
典型使用场景
场景一:个人账号与工作账号分离
codeai init claude personal
codeai init claude work
# 分别填入不同的 API Key
codeai claude personal # 使用个人账号
codeai claude work # 使用工作账号场景二:切换不同模型
{
"env": {
"ANTHROPIC_API_KEY": "sk-ant-xxxxxxxx",
"ANTHROPIC_MODEL": "claude-opus-4-6"
},
"args": []
}场景三:通过代理访问(黑名单模式)
内网域名直连,其他流量走上游代理:
{
"env": { "ANTHROPIC_API_KEY": "sk-ant-xxxxxxxx" },
"args": [],
"proxy": {
"enabled": true,
"upstream": "http://user:pass@corp-proxy.example.com:8080",
"mode": "blacklist",
"rules": [
"localhost",
"127.0.0.1",
"192.168.0.0/16",
"*.internal.example.com"
]
}
}场景四:白名单模式——仅代理 Anthropic API
只让 Anthropic 相关域名走代理,其余全部直连:
{
"env": { "ANTHROPIC_API_KEY": "sk-ant-xxxxxxxx" },
"args": [],
"proxy": {
"enabled": true,
"upstream": "http://127.0.0.1:7890",
"mode": "whitelist",
"rules": [
"api.anthropic.com",
"*.anthropic.com"
]
}
}场景五:按环境变量自动切换 Profile
在不同终端会话或 CI 环境中设置不同的环境变量,codeai 自动使用对应的 Profile,无需手动指定:
// ~/.codeai/setting.json
{
"env_profiles": [
{
"program": "claude",
"profile": "work",
"when": { "ANTHROPIC_BASE_URL": "https://work.example.com" }
},
{
"program": "claude",
"profile": "personal",
"when": { "ANTHROPIC_BASE_URL": "https://personal.example.com" }
}
]
}命令行如下
export ANTHROPIC_BASE_URL=https://work.example.com
codeai claude # 自动使用 work profile
export ANTHROPIC_BASE_URL=https://personal.example.com
codeai claude # 自动使用 personal profile
codeai claude default # 显式指定时跳过自动匹配场景六:管理多个 AI 工具
codeai init codex default
codeai init gemini default
codeai codex
codeai gemini场景七:开启调试日志排查问题
当程序运行无输出或行为异常时,在 Profile 中设置 "log_level": "debug" 即可在 stderr 看到完整的执行过程:
{
"env": { "ANTHROPIC_API_KEY": "sk-ant-xxxxxxxx" },
"args": [],
"log_level": "debug"
}示例输出(运行 codeai curl default -s https://ipinfo.io):
codeai[debug] loaded profile: program=curl, profile=default
codeai[debug] profile args: []
codeai[debug] resolved path: /usr/bin/curl
codeai[debug] final args: [-s https://ipinfo.io]
codeai[debug] injected env keys: [ANTHROPIC_API_KEY]
codeai[debug] proxy disabled
codeai[debug] exec: /usr/bin/curl [-s https://ipinfo.io]
codeai[debug] exit code: 0调试完毕后将 log_level 删除或置为 "" 即可恢复静默模式。
项目结构
codeai/
├── main.go # 入口
├── cmd/
│ ├── root.go # 命令分发
│ ├── run.go # codeai <程序> [profile]
│ ├── list.go # codeai list <程序>
│ ├── init.go # codeai init <程序> <profile>
│ └── open.go # codeai open <程序>
├── config/
│ ├── config.go # 配置路径解析、JSON 解析、Profile / ProxyConfig 结构体
│ └── setting.go # 全局设置解析、env_profiles 规则匹配引擎
├── logger/
│ └── logger.go # 全局调试日志(由 log_level 控制)
├── proxy/
│ ├── proxy.go # 本地 HTTP 代理服务器(CONNECT + 普通 HTTP)
│ └── rules.go # 规则匹配引擎(IP / CIDR / 域名 / 通配符)
└── executor/
└── executor.go # 环境变量合并、代理生命周期、进程启动、stdio 透传License
MIT