@pikecode/api-key-manager 1.0.37 → 1.0.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +526 -1
- package/package.json +1 -1
- package/src/commands/add.js +8 -1
- package/src/commands/switch.js +2 -1
- package/src/utils/codex-files.js +43 -2
- package/src/utils/codex-launcher.js +3 -0
package/README.md
CHANGED
|
@@ -39,6 +39,447 @@ akm list
|
|
|
39
39
|
akm current
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
+
## 📚 详细使用指南
|
|
43
|
+
|
|
44
|
+
### 首次使用完整流程
|
|
45
|
+
|
|
46
|
+
#### 步骤 1: 安装 akm
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# 全局安装
|
|
50
|
+
npm install -g @pikecode/api-key-manager
|
|
51
|
+
|
|
52
|
+
# 验证安装
|
|
53
|
+
akm --version
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
#### 步骤 2: 添加第一个供应商
|
|
57
|
+
|
|
58
|
+
**添加 Claude Code 供应商:**
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
akm add --claude
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
交互式问答流程:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
? 选择要管理的 IDE: Claude Code (Anthropic)
|
|
68
|
+
? 请输入供应商名称 (用于命令行): my-claude
|
|
69
|
+
? 请输入显示名称: My Claude Account
|
|
70
|
+
? 选择认证模式:
|
|
71
|
+
❯ 🌐 OAuth令牌模式 (CLAUDE_CODE_OAUTH_TOKEN) - 适用于官方Claude Code
|
|
72
|
+
🔑 通用API密钥模式 - 支持 ANTHROPIC_API_KEY 和 ANTHROPIC_AUTH_TOKEN
|
|
73
|
+
🔐 认证令牌模式 (仅 ANTHROPIC_AUTH_TOKEN) - 适用于某些服务商
|
|
74
|
+
? 请输入 OAuth Token: sk-ant-oat01-xxxxx
|
|
75
|
+
? 选择默认启动参数:
|
|
76
|
+
◉ --continue 继续上次对话
|
|
77
|
+
◯ --dangerously-skip-permissions 跳过权限检查
|
|
78
|
+
? 设置主模型 (ANTHROPIC_MODEL): claude-sonnet-4
|
|
79
|
+
? 设置快速模型 (ANTHROPIC_SMALL_FAST_MODEL): claude-haiku-4
|
|
80
|
+
|
|
81
|
+
✅ 供应商 'my-claude' 已添加
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**添加 Codex CLI 供应商:**
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
akm add --codex
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
交互式问答流程:
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
? 选择要管理的 IDE: Codex CLI (OpenAI)
|
|
94
|
+
? 选择配置方式:
|
|
95
|
+
❯ 从 ~/.codex 导入现有配置
|
|
96
|
+
手动输入配置
|
|
97
|
+
? 请输入供应商名称 (用于命令行): my-codex
|
|
98
|
+
? 请输入显示名称: My Codex Account
|
|
99
|
+
? 请输入 API Key (OPENAI_API_KEY): sk-xxxxx
|
|
100
|
+
? 请输入基础 URL (OPENAI_BASE_URL): https://api.openai.com
|
|
101
|
+
? 选择默认启动参数:
|
|
102
|
+
◉ resume 继续上次对话
|
|
103
|
+
◯ --full-auto 全自动模式
|
|
104
|
+
◯ --search 启用网页搜索
|
|
105
|
+
|
|
106
|
+
✅ 供应商 'my-codex' 已添加
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
#### 步骤 3: 切换并启动
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# 运行 akm 进入交互式选择界面
|
|
113
|
+
akm
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
选择供应商后,akm 会自动:
|
|
117
|
+
1. 设置为当前活跃供应商
|
|
118
|
+
2. 配置相应的环境变量/配置文件
|
|
119
|
+
3. 启动对应的 IDE(Claude Code 或 Codex CLI)
|
|
120
|
+
|
|
121
|
+
#### 步骤 4: 日常使用
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# 快速切换到指定供应商
|
|
125
|
+
akm my-claude
|
|
126
|
+
|
|
127
|
+
# 查看当前配置
|
|
128
|
+
akm current
|
|
129
|
+
|
|
130
|
+
# 查看所有供应商
|
|
131
|
+
akm list
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
### 交互式界面操作说明
|
|
137
|
+
|
|
138
|
+
#### 主界面(供应商选择)
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
总共 3 个供应商配置
|
|
142
|
+
|
|
143
|
+
↑ / ↓ 选择供应商 | Enter 确认 | Tab 切换选项 | ESC 退出程序 | Ctrl+C 强制退出
|
|
144
|
+
|
|
145
|
+
? 请选择要切换的供应商 (总计 3 个):
|
|
146
|
+
🟢 [Claude] My Claude Account --- 上次使用 - 可用
|
|
147
|
+
🟢 [Claude] Work Account - 可用
|
|
148
|
+
❯ 🟢 [Codex] My Codex Account - 可用
|
|
149
|
+
──────────────
|
|
150
|
+
➕ 添加新供应商
|
|
151
|
+
📋 供应商管理 (编辑/删除)
|
|
152
|
+
📁 打开配置文件
|
|
153
|
+
❌ 退出
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**状态图标说明:**
|
|
157
|
+
| 图标 | 含义 |
|
|
158
|
+
|-----|------|
|
|
159
|
+
| 🟢 | API 可用 |
|
|
160
|
+
| 🟡 | 有限可用/响应慢 |
|
|
161
|
+
| 🔴 | API 不可用 |
|
|
162
|
+
| ⏳ | 正在检测 |
|
|
163
|
+
| ⚪ | 未知状态 |
|
|
164
|
+
|
|
165
|
+
**IDE 标签:**
|
|
166
|
+
| 标签 | 含义 |
|
|
167
|
+
|------|------|
|
|
168
|
+
| [Claude] | Claude Code 供应商 |
|
|
169
|
+
| [Codex] | Codex CLI 供应商 |
|
|
170
|
+
|
|
171
|
+
#### 启动参数选择界面
|
|
172
|
+
|
|
173
|
+
选择供应商后进入启动参数选择:
|
|
174
|
+
|
|
175
|
+
```
|
|
176
|
+
┌─ 启动配置 ─────────────────────────────────┐
|
|
177
|
+
|
|
178
|
+
📋 供应商: My Claude Account
|
|
179
|
+
|
|
180
|
+
空格 切换选中 | A 全选 | I 反选 | Enter 启动 Claude Code | ESC 返回
|
|
181
|
+
|
|
182
|
+
? 选择启动参数:
|
|
183
|
+
◉ --continue (继续上次对话)
|
|
184
|
+
◯ --dangerously-skip-permissions (跳过权限检查)
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**快捷键:**
|
|
188
|
+
| 按键 | 功能 |
|
|
189
|
+
|------|------|
|
|
190
|
+
| `Space` | 切换选中状态 |
|
|
191
|
+
| `A` | 全选所有参数 |
|
|
192
|
+
| `I` | 反选(选中变未选,未选变选中)|
|
|
193
|
+
| `Enter` | 确认并启动 |
|
|
194
|
+
| `ESC` | 返回上一级 |
|
|
195
|
+
|
|
196
|
+
#### 供应商管理界面
|
|
197
|
+
|
|
198
|
+
从主界面选择"供应商管理"进入:
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
↑ / ↓ 选择供应商或操作 | Enter 确认 | ESC 返回主菜单
|
|
202
|
+
|
|
203
|
+
┌─ 供应商管理 ─────────────────────────────────┐
|
|
204
|
+
|
|
205
|
+
? 选择供应商或操作 (总计 3 个):
|
|
206
|
+
❯ 🟢 [Claude] My Claude Account - 可用
|
|
207
|
+
🟢 [Claude] Work Account - 可用
|
|
208
|
+
🟢 [Codex] My Codex Account - 可用
|
|
209
|
+
──────────────
|
|
210
|
+
◀ 返回供应商选择
|
|
211
|
+
❌ 退出
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
选择供应商后显示详情和操作选项:
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
┌─ 供应商详情 ─────────────────────────────────┐
|
|
218
|
+
|
|
219
|
+
┌──────────────┬─────────────────────────────────┐
|
|
220
|
+
│ 供应商名称 │ my-claude │
|
|
221
|
+
│ 显示名称 │ My Claude Account │
|
|
222
|
+
│ 认证模式 │ OAuth令牌模式 │
|
|
223
|
+
│ 基础URL │ ✨ 官方默认服务器 │
|
|
224
|
+
│ 认证令牌 │ sk-ant-***...***ddd │
|
|
225
|
+
│ 主模型 │ claude-sonnet-4 │
|
|
226
|
+
│ 快速模型 │ claude-haiku-4 │
|
|
227
|
+
│ 创建时间 │ 2025-12-15 13:00 │
|
|
228
|
+
│ 最后使用 │ 2025-12-17 10:30 │
|
|
229
|
+
│ 当前状态 │ ✅ 使用中 │
|
|
230
|
+
│ 使用次数 │ 42 │
|
|
231
|
+
└──────────────┴─────────────────────────────────┘
|
|
232
|
+
|
|
233
|
+
? 选择操作:
|
|
234
|
+
❯ 🚀 立即启动
|
|
235
|
+
✏️ 编辑供应商
|
|
236
|
+
🗑️ 删除供应商
|
|
237
|
+
◀ 返回管理列表
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
### 配置示例
|
|
243
|
+
|
|
244
|
+
#### Claude Code 官方 OAuth(推荐)
|
|
245
|
+
|
|
246
|
+
适用于:使用官方 Claude Code 登录获取的 OAuth Token
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
akm add --claude
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
```yaml
|
|
253
|
+
供应商名称: claude-official
|
|
254
|
+
显示名称: Claude Official
|
|
255
|
+
认证模式: oauth_token
|
|
256
|
+
Token: sk-ant-oat01-xxxxxxxx # 从 claude 登录后获取
|
|
257
|
+
基础URL: (留空,使用官方服务器)
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
#### Claude Code 第三方 API(API Key 模式)
|
|
261
|
+
|
|
262
|
+
适用于:使用 Anthropic API Key 或第三方兼容服务
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
akm add --claude
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
```yaml
|
|
269
|
+
供应商名称: anthropic-api
|
|
270
|
+
显示名称: Anthropic API
|
|
271
|
+
认证模式: api_key
|
|
272
|
+
Token类型: ANTHROPIC_API_KEY
|
|
273
|
+
Token: sk-ant-api03-xxxxxxxx
|
|
274
|
+
基础URL: https://api.anthropic.com # 或第三方服务地址
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
#### Claude Code 第三方 API(Auth Token 模式)
|
|
278
|
+
|
|
279
|
+
适用于:某些第三方服务商要求使用 ANTHROPIC_AUTH_TOKEN
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
akm add --claude
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
```yaml
|
|
286
|
+
供应商名称: third-party
|
|
287
|
+
显示名称: Third Party Service
|
|
288
|
+
认证模式: auth_token
|
|
289
|
+
Token: your-auth-token
|
|
290
|
+
基础URL: https://your-provider.com/v1
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
#### Codex CLI 官方 OpenAI
|
|
294
|
+
|
|
295
|
+
适用于:使用 OpenAI 官方 API
|
|
296
|
+
|
|
297
|
+
```bash
|
|
298
|
+
akm add --codex
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
```yaml
|
|
302
|
+
供应商名称: openai-official
|
|
303
|
+
显示名称: OpenAI Official
|
|
304
|
+
API Key: sk-xxxxxxxx
|
|
305
|
+
基础URL: https://api.openai.com # 可留空
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
#### Codex CLI 第三方兼容服务
|
|
309
|
+
|
|
310
|
+
适用于:使用兼容 OpenAI API 的第三方服务
|
|
311
|
+
|
|
312
|
+
```bash
|
|
313
|
+
akm add --codex
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
```yaml
|
|
317
|
+
供应商名称: azure-openai
|
|
318
|
+
显示名称: Azure OpenAI
|
|
319
|
+
API Key: your-azure-key
|
|
320
|
+
基础URL: https://your-resource.openai.azure.com/openai/deployments/your-deployment
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
#### 多账号配置示例
|
|
324
|
+
|
|
325
|
+
```bash
|
|
326
|
+
# 工作账号
|
|
327
|
+
akm add --claude
|
|
328
|
+
# 名称: work, Token: sk-ant-work-xxx
|
|
329
|
+
|
|
330
|
+
# 个人账号
|
|
331
|
+
akm add --claude
|
|
332
|
+
# 名称: personal, Token: sk-ant-personal-xxx
|
|
333
|
+
|
|
334
|
+
# 测试账号
|
|
335
|
+
akm add --codex
|
|
336
|
+
# 名称: test-codex, Token: sk-test-xxx
|
|
337
|
+
|
|
338
|
+
# 快速切换
|
|
339
|
+
akm work # 切换到工作账号
|
|
340
|
+
akm personal # 切换到个人账号
|
|
341
|
+
akm test-codex # 切换到测试账号
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
---
|
|
345
|
+
|
|
346
|
+
### 常见问题 FAQ
|
|
347
|
+
|
|
348
|
+
#### Q1: 切换 Codex 后提示 "Token data is not available"
|
|
349
|
+
|
|
350
|
+
**原因:** `~/.codex/auth.json` 格式不正确或 `config.toml` 未设置 API Key 认证模式。
|
|
351
|
+
|
|
352
|
+
**解决方案:**
|
|
353
|
+
```bash
|
|
354
|
+
# 确保使用最新版本 akm
|
|
355
|
+
npm update -g @pikecode/api-key-manager
|
|
356
|
+
|
|
357
|
+
# 重新切换供应商
|
|
358
|
+
akm my-codex
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
akm 会自动:
|
|
362
|
+
- 设置 `~/.codex/config.toml` 中的 `preferred_auth_method = "apikey"`
|
|
363
|
+
- 写入正确格式的 `~/.codex/auth.json`
|
|
364
|
+
|
|
365
|
+
#### Q2: Claude Code 切换后环境变量不生效
|
|
366
|
+
|
|
367
|
+
**原因:** `~/.claude/settings.json` 中存在冲突的环境变量配置。
|
|
368
|
+
|
|
369
|
+
**解决方案:** 切换时 akm 会自动检测并提示处理冲突,选择"备份并清空这些变量"即可。
|
|
370
|
+
|
|
371
|
+
手动检查:
|
|
372
|
+
```bash
|
|
373
|
+
cat ~/.claude/settings.json | grep -A 10 '"env"'
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
#### Q3: 如何查看完整的 API Key/Token?
|
|
377
|
+
|
|
378
|
+
**解决方案:** 默认脱敏显示,使用 `--show-token` 参数:
|
|
379
|
+
|
|
380
|
+
```bash
|
|
381
|
+
akm list --show-token
|
|
382
|
+
akm current --show-token
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
#### Q4: 配置文件在哪里?如何手动编辑?
|
|
386
|
+
|
|
387
|
+
**位置:** `~/.akm-config.json`
|
|
388
|
+
|
|
389
|
+
```bash
|
|
390
|
+
# 通过 akm 打开
|
|
391
|
+
akm
|
|
392
|
+
# 选择 "📁 打开配置文件"
|
|
393
|
+
|
|
394
|
+
# 或直接编辑
|
|
395
|
+
code ~/.akm-config.json
|
|
396
|
+
vim ~/.akm-config.json
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
#### Q5: 如何备份和恢复配置?
|
|
400
|
+
|
|
401
|
+
```bash
|
|
402
|
+
# 创建备份
|
|
403
|
+
akm backup
|
|
404
|
+
|
|
405
|
+
# 查看备份列表
|
|
406
|
+
akm backup --list
|
|
407
|
+
|
|
408
|
+
# 恢复备份
|
|
409
|
+
akm backup --restore akm-backup-2025-12-17T10-30-00.json
|
|
410
|
+
|
|
411
|
+
# 导出到指定文件(可分享)
|
|
412
|
+
akm export my-config.json
|
|
413
|
+
|
|
414
|
+
# 导出脱敏版本(分享配置模板)
|
|
415
|
+
akm export template.json --mask
|
|
416
|
+
|
|
417
|
+
# 从文件导入
|
|
418
|
+
akm import my-config.json
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
#### Q6: 切换时报错 "找不到 claude/codex 命令"
|
|
422
|
+
|
|
423
|
+
**原因:** 未安装对应的 CLI 工具。
|
|
424
|
+
|
|
425
|
+
**解决方案:**
|
|
426
|
+
|
|
427
|
+
```bash
|
|
428
|
+
# 安装 Claude Code
|
|
429
|
+
npm install -g @anthropic-ai/claude-code
|
|
430
|
+
|
|
431
|
+
# 安装 Codex CLI
|
|
432
|
+
npm install -g @openai/codex
|
|
433
|
+
# 或
|
|
434
|
+
brew install codex
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
#### Q7: 如何删除某个供应商配置?
|
|
438
|
+
|
|
439
|
+
```bash
|
|
440
|
+
# 交互式选择删除
|
|
441
|
+
akm remove
|
|
442
|
+
|
|
443
|
+
# 直接删除指定供应商
|
|
444
|
+
akm remove my-provider
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
#### Q8: 支持哪些第三方服务?
|
|
448
|
+
|
|
449
|
+
理论上支持所有兼容以下 API 的服务:
|
|
450
|
+
- **Claude Code**: 兼容 Anthropic API 的服务
|
|
451
|
+
- **Codex CLI**: 兼容 OpenAI API 的服务
|
|
452
|
+
|
|
453
|
+
常见第三方服务配置:
|
|
454
|
+
| 服务 | IDE | 基础 URL |
|
|
455
|
+
|------|-----|----------|
|
|
456
|
+
| Azure OpenAI | Codex | `https://{resource}.openai.azure.com/...` |
|
|
457
|
+
| OpenRouter | Claude/Codex | `https://openrouter.ai/api/v1` |
|
|
458
|
+
| Together AI | Codex | `https://api.together.xyz/v1` |
|
|
459
|
+
|
|
460
|
+
#### Q9: 如何只显示某一类 IDE 的供应商?
|
|
461
|
+
|
|
462
|
+
```bash
|
|
463
|
+
# 只显示 Claude Code 供应商
|
|
464
|
+
akm switch --claude
|
|
465
|
+
akm list --claude
|
|
466
|
+
|
|
467
|
+
# 只显示 Codex CLI 供应商
|
|
468
|
+
akm switch --codex
|
|
469
|
+
akm list --codex
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
#### Q10: 配置文件权限问题
|
|
473
|
+
|
|
474
|
+
akm 会自动设置配置文件权限为 `0600`(仅所有者可读写)。
|
|
475
|
+
|
|
476
|
+
如果遇到权限问题:
|
|
477
|
+
```bash
|
|
478
|
+
chmod 600 ~/.akm-config.json
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
---
|
|
482
|
+
|
|
42
483
|
## 📖 完整命令参考
|
|
43
484
|
|
|
44
485
|
### 基础命令
|
|
@@ -233,11 +674,34 @@ akm backup --restore backup.json --dir /path/to/backups
|
|
|
233
674
|
- **api_key** - 通用 API 密钥模式
|
|
234
675
|
- **auth_token** - 认证令牌模式
|
|
235
676
|
|
|
677
|
+
**切换原理:**
|
|
678
|
+
|
|
679
|
+
切换 Claude Code 供应商时,akm 通过**环境变量注入**方式工作:
|
|
680
|
+
|
|
681
|
+
1. **检测设置冲突** → 检查 `~/.claude/settings.json` 中是否有冲突的环境变量
|
|
682
|
+
2. **构建环境变量** → 根据认证模式构建相应的环境变量
|
|
683
|
+
3. **启动子进程** → 使用 `spawn('claude', args, { env })` 启动 Claude Code
|
|
684
|
+
|
|
685
|
+
```
|
|
686
|
+
认证模式 → 环境变量映射:
|
|
687
|
+
┌─────────────┬────────────────────────────┐
|
|
688
|
+
│ oauth_token │ CLAUDE_CODE_OAUTH_TOKEN │
|
|
689
|
+
│ api_key │ ANTHROPIC_API_KEY │
|
|
690
|
+
│ │ ANTHROPIC_BASE_URL │
|
|
691
|
+
│ auth_token │ ANTHROPIC_AUTH_TOKEN │
|
|
692
|
+
│ │ ANTHROPIC_BASE_URL (可选) │
|
|
693
|
+
└─────────────┴────────────────────────────┘
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
> 💡 Claude Code 使用环境变量注入,不修改配置文件,切换只在当前会话生效。
|
|
697
|
+
|
|
236
698
|
**环境变量:**
|
|
237
699
|
- `CLAUDE_CODE_OAUTH_TOKEN` - OAuth 模式
|
|
238
700
|
- `ANTHROPIC_API_KEY` - API Key 模式
|
|
239
701
|
- `ANTHROPIC_AUTH_TOKEN` - Auth Token 模式
|
|
240
702
|
- `ANTHROPIC_BASE_URL` - 自定义 API 端点
|
|
703
|
+
- `ANTHROPIC_MODEL` - 主模型
|
|
704
|
+
- `ANTHROPIC_SMALL_FAST_MODEL` - 快速模型
|
|
241
705
|
|
|
242
706
|
**启动参数:**
|
|
243
707
|
- `--continue` - 继续上次对话
|
|
@@ -254,6 +718,27 @@ akm add --claude
|
|
|
254
718
|
**认证模式:**
|
|
255
719
|
- 使用 `OPENAI_API_KEY` 和 `OPENAI_BASE_URL` 环境变量
|
|
256
720
|
|
|
721
|
+
**切换原理:**
|
|
722
|
+
|
|
723
|
+
切换 Codex 供应商时,akm 会自动:
|
|
724
|
+
|
|
725
|
+
1. **备份现有配置** → `~/.codex/akm-backups/backup-{timestamp}/`
|
|
726
|
+
2. **更新 config.toml** → 设置 `preferred_auth_method = "apikey"`
|
|
727
|
+
3. **写入 auth.json** → 包含选中供应商的 API Key
|
|
728
|
+
4. **注入环境变量** → 启动时传递 `OPENAI_API_KEY` 和 `OPENAI_BASE_URL`
|
|
729
|
+
|
|
730
|
+
```
|
|
731
|
+
~/.codex/
|
|
732
|
+
├── config.toml # preferred_auth_method = "apikey"
|
|
733
|
+
├── auth.json # { "OPENAI_API_KEY": "your-key" }
|
|
734
|
+
└── akm-backups/ # 自动备份目录
|
|
735
|
+
└── backup-20251217_120000/
|
|
736
|
+
├── config.toml
|
|
737
|
+
└── auth.json
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
> 💡 切换后直接运行 `codex` 命令也能使用新配置,无需通过 akm 启动。
|
|
741
|
+
|
|
257
742
|
**启动参数:**
|
|
258
743
|
- `resume` - 继续上次对话(子命令)
|
|
259
744
|
- `--full-auto` - 全自动模式(自动批准 + 工作区沙盒)⚠️ 与 `--dangerously-bypass-approvals-and-sandbox` 互斥
|
|
@@ -322,6 +807,40 @@ akm add --codex
|
|
|
322
807
|
}
|
|
323
808
|
```
|
|
324
809
|
|
|
810
|
+
## 🏗️ 架构设计
|
|
811
|
+
|
|
812
|
+
```
|
|
813
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
814
|
+
│ akm (CLI 入口) │
|
|
815
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
816
|
+
│ CommandRegistry 命令注册中心,懒加载命令模块 │
|
|
817
|
+
│ ├── add 添加供应商 │
|
|
818
|
+
│ ├── switch 切换供应商(默认命令) │
|
|
819
|
+
│ ├── list 列出供应商 │
|
|
820
|
+
│ ├── edit 编辑供应商 │
|
|
821
|
+
│ ├── remove 删除供应商 │
|
|
822
|
+
│ ├── export/import 导入导出 │
|
|
823
|
+
│ └── backup 备份恢复 │
|
|
824
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
825
|
+
│ ConfigManager 配置管理(~/.akm-config.json) │
|
|
826
|
+
│ ├── 懒加载 & 缓存 │
|
|
827
|
+
│ ├── 版本迁移 │
|
|
828
|
+
│ └── 文件权限管理 (0600) │
|
|
829
|
+
├─────────────────────────────────────────────────────────────────┤
|
|
830
|
+
│ IDE 启动器 │
|
|
831
|
+
│ ├── env-launcher.js Claude Code(环境变量注入) │
|
|
832
|
+
│ └── codex-launcher.js Codex CLI(配置文件 + 环境变量) │
|
|
833
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
**核心设计原则:**
|
|
837
|
+
|
|
838
|
+
1. **命令懒加载** - 通过 `CommandRegistry` 按需加载命令模块,减少启动时间
|
|
839
|
+
2. **配置缓存** - `ConfigManager` 单例模式,避免重复读取配置文件
|
|
840
|
+
3. **IDE 差异化处理** - Claude Code 用环境变量,Codex CLI 写配置文件
|
|
841
|
+
4. **安全优先** - 配置文件权限 0600,Token 默认脱敏显示
|
|
842
|
+
5. **自动备份** - 切换配置前自动备份,支持回滚
|
|
843
|
+
|
|
325
844
|
## 🎯 使用场景
|
|
326
845
|
|
|
327
846
|
### 场景 1: 同时使用多个 API Key
|
|
@@ -420,7 +939,13 @@ akm backup --restore akm-backup-2025-12-15T05-30-00.json
|
|
|
420
939
|
|
|
421
940
|
## 📝 更新日志
|
|
422
941
|
|
|
423
|
-
### v1.0.
|
|
942
|
+
### v1.0.37 (最新)
|
|
943
|
+
- 🐛 修复 Codex 切换时无法更新 `~/.codex/auth.json` 的问题
|
|
944
|
+
- ✨ 切换 Codex 供应商时自动写入配置文件
|
|
945
|
+
- ✨ 自动设置 `preferred_auth_method = "apikey"`
|
|
946
|
+
- 💾 切换前自动备份现有 Codex 配置
|
|
947
|
+
|
|
948
|
+
### v1.0.27
|
|
424
949
|
- ✨ 新增参数互斥校验
|
|
425
950
|
- ✨ 新增 `export` / `import` / `backup` 命令
|
|
426
951
|
- 🧪 测试覆盖率提升 46%
|
package/package.json
CHANGED
package/src/commands/add.js
CHANGED
|
@@ -590,11 +590,18 @@ class ProviderAdder extends BaseCommand {
|
|
|
590
590
|
}
|
|
591
591
|
|
|
592
592
|
// 尝试从 config.toml 获取 base URL
|
|
593
|
+
// 支持 api_base_url(akm 写入的格式)和 api_base(某些旧配置可能使用)
|
|
593
594
|
let baseUrl = null;
|
|
594
595
|
if (codexFiles.configToml) {
|
|
595
|
-
const baseUrlMatch = codexFiles.configToml.match(/
|
|
596
|
+
const baseUrlMatch = codexFiles.configToml.match(/api_base_url\s*=\s*["']([^"']+)["']/);
|
|
596
597
|
if (baseUrlMatch) {
|
|
597
598
|
baseUrl = baseUrlMatch[1];
|
|
599
|
+
} else {
|
|
600
|
+
// 兼容旧格式
|
|
601
|
+
const legacyMatch = codexFiles.configToml.match(/api_base\s*=\s*["']([^"']+)["']/);
|
|
602
|
+
if (legacyMatch) {
|
|
603
|
+
baseUrl = legacyMatch[1];
|
|
604
|
+
}
|
|
598
605
|
}
|
|
599
606
|
}
|
|
600
607
|
|
package/src/commands/switch.js
CHANGED
|
@@ -1450,7 +1450,8 @@ class EnvSwitcher extends BaseCommand {
|
|
|
1450
1450
|
|
|
1451
1451
|
// 更新供应商配置
|
|
1452
1452
|
provider.displayName = answers.displayName || newName;
|
|
1453
|
-
|
|
1453
|
+
// oauth_token 模式不需要 baseUrl,显式设为 null
|
|
1454
|
+
provider.baseUrl = answers.authMode === 'oauth_token' ? null : answers.baseUrl;
|
|
1454
1455
|
provider.authToken = answers.authToken;
|
|
1455
1456
|
|
|
1456
1457
|
// Claude Code 特定的更新
|
package/src/utils/codex-files.js
CHANGED
|
@@ -138,13 +138,49 @@ function ensureApiKeyAuthMethod(configToml) {
|
|
|
138
138
|
return 'preferred_auth_method = "apikey"\n' + configToml;
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
+
/**
|
|
142
|
+
* 更新 config.toml 中的 api_base_url
|
|
143
|
+
* @param {string} configToml - 现有的 config.toml 内容
|
|
144
|
+
* @param {string|null} baseUrl - API base URL,null 时移除该配置
|
|
145
|
+
* @returns {string} 更新后的 config.toml 内容
|
|
146
|
+
*/
|
|
147
|
+
function updateApiBaseUrl(configToml, baseUrl) {
|
|
148
|
+
if (!configToml) {
|
|
149
|
+
configToml = '';
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// 匹配 api_base_url 配置行
|
|
153
|
+
const baseUrlRegex = /^api_base_url\s*=\s*["']?[^"'\n]*["']?\s*\n?/m;
|
|
154
|
+
|
|
155
|
+
if (baseUrl) {
|
|
156
|
+
// 需要设置 base_url
|
|
157
|
+
const newLine = `api_base_url = "${baseUrl}"\n`;
|
|
158
|
+
|
|
159
|
+
if (configToml.match(baseUrlRegex)) {
|
|
160
|
+
// 替换现有的
|
|
161
|
+
return configToml.replace(baseUrlRegex, newLine);
|
|
162
|
+
}
|
|
163
|
+
// 在文件末尾添加
|
|
164
|
+
if (configToml.length === 0) {
|
|
165
|
+
// 空配置,直接返回新行
|
|
166
|
+
return newLine;
|
|
167
|
+
}
|
|
168
|
+
// 确保前面有换行
|
|
169
|
+
const separator = configToml.endsWith('\n') ? '' : '\n';
|
|
170
|
+
return configToml + separator + newLine;
|
|
171
|
+
} else {
|
|
172
|
+
// 移除 base_url(使用官方 API)
|
|
173
|
+
return configToml.replace(baseUrlRegex, '');
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
141
177
|
/**
|
|
142
178
|
* 构建 auth.json 内容
|
|
143
179
|
* @param {string} apiKey - API Key
|
|
144
180
|
* @returns {string} auth.json 内容
|
|
145
181
|
*/
|
|
146
182
|
function buildAuthJson(apiKey) {
|
|
147
|
-
return JSON.stringify({
|
|
183
|
+
return JSON.stringify({ OPENAI_API_KEY: apiKey }, null, 2);
|
|
148
184
|
}
|
|
149
185
|
|
|
150
186
|
/**
|
|
@@ -172,7 +208,11 @@ async function applyCodexConfig(config, options = {}) {
|
|
|
172
208
|
}
|
|
173
209
|
|
|
174
210
|
// 确保设置了 preferred_auth_method = "apikey"
|
|
175
|
-
|
|
211
|
+
let updatedConfigToml = ensureApiKeyAuthMethod(existingConfigToml);
|
|
212
|
+
|
|
213
|
+
// 更新 api_base_url(如果有则设置,没有则移除)
|
|
214
|
+
updatedConfigToml = updateApiBaseUrl(updatedConfigToml, config.baseUrl || null);
|
|
215
|
+
|
|
176
216
|
await fs.writeFile(configTomlPath, updatedConfigToml, 'utf8');
|
|
177
217
|
await setSecurePermissions(configTomlPath);
|
|
178
218
|
|
|
@@ -192,6 +232,7 @@ module.exports = {
|
|
|
192
232
|
applyCodexConfig,
|
|
193
233
|
backupCodexFiles,
|
|
194
234
|
ensureApiKeyAuthMethod,
|
|
235
|
+
updateApiBaseUrl,
|
|
195
236
|
buildAuthJson
|
|
196
237
|
};
|
|
197
238
|
|
|
@@ -48,8 +48,11 @@ async function executeCodexWithEnv(config, launchArgs = []) {
|
|
|
48
48
|
|
|
49
49
|
// 写入 ~/.codex/config.toml 和 ~/.codex/auth.json
|
|
50
50
|
// 确保 Codex CLI 使用 API Key 认证方式
|
|
51
|
+
// 这样用户也可以直接运行 `codex` 命令而无需通过 akm
|
|
51
52
|
await applyCodexConfig(config);
|
|
52
53
|
|
|
54
|
+
// 同时设置环境变量,确保兼容性
|
|
55
|
+
// 环境变量优先级更高,作为双重保障
|
|
53
56
|
const env = buildCodexEnvVariables(config);
|
|
54
57
|
|
|
55
58
|
// 处理参数:子命令放前面,选项放后面
|