@pikecode/api-key-manager 1.0.5 → 1.0.7
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 +31 -11
- package/package.json +1 -1
- package/src/commands/add.js +40 -9
- package/src/commands/switch.js +3 -1
- package/src/utils/env-launcher.js +11 -11
- package/src/utils/provider-status-checker.js +15 -0
- package/src/utils/ui-helper.js +7 -1
package/README.md
CHANGED
|
@@ -76,11 +76,24 @@ akm list
|
|
|
76
76
|
"displayName": "Codex Provider",
|
|
77
77
|
"ideName": "codex",
|
|
78
78
|
"authMode": "api_key",
|
|
79
|
-
"authToken": "
|
|
80
|
-
"baseUrl":
|
|
81
|
-
"tokenType":
|
|
79
|
+
"authToken": "sk-...",
|
|
80
|
+
"baseUrl": null,
|
|
81
|
+
"tokenType": null,
|
|
82
|
+
"models": {
|
|
83
|
+
"primary": null,
|
|
84
|
+
"smallFast": null
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
"codex-chatgpt": {
|
|
88
|
+
"name": "codex-chatgpt",
|
|
89
|
+
"displayName": "Codex ChatGPT Login",
|
|
90
|
+
"ideName": "codex",
|
|
91
|
+
"authMode": "chatgpt_login",
|
|
92
|
+
"authToken": null,
|
|
93
|
+
"baseUrl": null,
|
|
94
|
+
"tokenType": null,
|
|
82
95
|
"models": {
|
|
83
|
-
"primary":
|
|
96
|
+
"primary": null,
|
|
84
97
|
"smallFast": null
|
|
85
98
|
}
|
|
86
99
|
}
|
|
@@ -90,13 +103,19 @@ akm list
|
|
|
90
103
|
|
|
91
104
|
## 支持的 IDE
|
|
92
105
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
-
|
|
106
|
+
### Claude Code - Anthropic 官方代码编辑器
|
|
107
|
+
- 认证模式:
|
|
108
|
+
- `oauth_token` - OAuth 令牌模式(推荐官方用户)
|
|
109
|
+
- `api_key` - 通用 API 密钥模式(支持 ANTHROPIC_API_KEY 和 ANTHROPIC_AUTH_TOKEN)
|
|
110
|
+
- `auth_token` - 认证令牌模式(仅 ANTHROPIC_AUTH_TOKEN)
|
|
111
|
+
- 环境变量:CLAUDE_CODE_OAUTH_TOKEN、ANTHROPIC_API_KEY、ANTHROPIC_AUTH_TOKEN、ANTHROPIC_BASE_URL
|
|
96
112
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
-
|
|
113
|
+
### Codex - OpenAI Codex 代码生成工具
|
|
114
|
+
- 认证模式:
|
|
115
|
+
- `chatgpt_login` - ChatGPT 登录模式(推荐,使用 ChatGPT 账户登录)
|
|
116
|
+
- `api_key` - OpenAI API 密钥模式
|
|
117
|
+
- 环境变量:OPENAI_API_KEY、OPENAI_API_BASE(可选)
|
|
118
|
+
- 官方包:`npm install -g @openai/codex`
|
|
100
119
|
|
|
101
120
|
## 支持的认证模式
|
|
102
121
|
|
|
@@ -104,7 +123,8 @@ akm list
|
|
|
104
123
|
|------|-----|------|
|
|
105
124
|
| **oauth_token** | Claude Code | OAuth 令牌模式 |
|
|
106
125
|
| **api_key** | Claude Code / Codex | 标准 API 密钥模式 |
|
|
107
|
-
| **auth_token** | Claude Code
|
|
126
|
+
| **auth_token** | Claude Code | 认证令牌模式 |
|
|
127
|
+
| **chatgpt_login** | Codex | ChatGPT 登录模式(推荐) |
|
|
108
128
|
|
|
109
129
|
## 快捷键
|
|
110
130
|
|
package/package.json
CHANGED
package/src/commands/add.js
CHANGED
|
@@ -216,9 +216,10 @@ class ProviderAdder extends BaseCommand {
|
|
|
216
216
|
choices: (answers) => {
|
|
217
217
|
if (answers.ideName === 'codex') {
|
|
218
218
|
// Codex 的认证模式选择
|
|
219
|
+
// @openai/codex 支持两种方式:ChatGPT 登录 (推荐) 或 OpenAI API Key
|
|
219
220
|
return [
|
|
220
|
-
{ name: '
|
|
221
|
-
{ name: '
|
|
221
|
+
{ name: '🔐 ChatGPT 登录 (推荐) - 使用 ChatGPT 账户登录', value: 'chatgpt_login' },
|
|
222
|
+
{ name: '🔑 OpenAI API Key - 使用 OPENAI_API_KEY', value: 'api_key' }
|
|
222
223
|
];
|
|
223
224
|
}
|
|
224
225
|
// Claude Code 的认证模式选择
|
|
@@ -239,13 +240,18 @@ class ProviderAdder extends BaseCommand {
|
|
|
239
240
|
{ name: '🔐 ANTHROPIC_AUTH_TOKEN - 认证令牌', value: 'auth_token' }
|
|
240
241
|
],
|
|
241
242
|
default: 'api_key',
|
|
242
|
-
|
|
243
|
+
// 只对 Claude Code 的 api_key 模式显示 tokenType 选择
|
|
244
|
+
// Codex 的 api_key 模式固定使用 OPENAI_API_KEY
|
|
245
|
+
when: (answers) => answers.ideName === 'claude' && answers.authMode === 'api_key'
|
|
243
246
|
},
|
|
244
247
|
{
|
|
245
248
|
type: 'input',
|
|
246
249
|
name: 'baseUrl',
|
|
247
250
|
message: (answers) => {
|
|
248
251
|
// 根据认证模式显示不同的提示
|
|
252
|
+
if (answers.ideName === 'codex' && answers.authMode === 'api_key') {
|
|
253
|
+
return '请输入OpenAI API基础URL (可选,默认为官方API):';
|
|
254
|
+
}
|
|
249
255
|
if (answers.authMode === 'auth_token') {
|
|
250
256
|
return '请输入API基础URL (如使用官方API可留空):';
|
|
251
257
|
}
|
|
@@ -256,20 +262,43 @@ class ProviderAdder extends BaseCommand {
|
|
|
256
262
|
if (input === '' && answers.authMode === 'auth_token') {
|
|
257
263
|
return true;
|
|
258
264
|
}
|
|
259
|
-
//
|
|
260
|
-
if (
|
|
265
|
+
// Codex 的 api_key 模式也允许空值(使用官方 OpenAI API)
|
|
266
|
+
if (input === '' && answers.ideName === 'codex' && answers.authMode === 'api_key') {
|
|
267
|
+
return true;
|
|
268
|
+
}
|
|
269
|
+
// Claude Code 的 api_key 模式需要有效的 URL
|
|
270
|
+
if (!input && answers.ideName === 'claude' && answers.authMode === 'api_key') {
|
|
261
271
|
return 'API基础URL不能为空';
|
|
262
272
|
}
|
|
263
|
-
|
|
264
|
-
if (
|
|
273
|
+
// 如果提供了 URL,验证格式
|
|
274
|
+
if (input) {
|
|
275
|
+
const error = validator.validateUrl(input);
|
|
276
|
+
if (error) return error;
|
|
277
|
+
}
|
|
265
278
|
return true;
|
|
266
279
|
},
|
|
267
|
-
|
|
280
|
+
// Codex 只在 api_key 模式时询问 baseUrl,Claude Code 在 api_key 和 auth_token 时询问
|
|
281
|
+
when: (answers) => {
|
|
282
|
+
if (answers.ideName === 'codex') {
|
|
283
|
+
return answers.authMode === 'api_key';
|
|
284
|
+
}
|
|
285
|
+
return answers.authMode === 'api_key' || answers.authMode === 'auth_token';
|
|
286
|
+
}
|
|
268
287
|
},
|
|
269
288
|
{
|
|
270
289
|
type: 'input',
|
|
271
290
|
name: 'authToken',
|
|
272
291
|
message: (answers) => {
|
|
292
|
+
// Codex 的特殊处理
|
|
293
|
+
if (answers.ideName === 'codex') {
|
|
294
|
+
if (answers.authMode === 'api_key') {
|
|
295
|
+
return '请输入OpenAI API Key (OPENAI_API_KEY):';
|
|
296
|
+
}
|
|
297
|
+
// chatgpt_login 模式不需要输入 Token
|
|
298
|
+
return '请输入认证令牌:';
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// Claude Code 的处理
|
|
273
302
|
switch (answers.authMode) {
|
|
274
303
|
case 'api_key':
|
|
275
304
|
const tokenTypeLabel = answers.tokenType === 'auth_token' ? 'ANTHROPIC_AUTH_TOKEN' : 'ANTHROPIC_API_KEY';
|
|
@@ -286,7 +315,9 @@ class ProviderAdder extends BaseCommand {
|
|
|
286
315
|
const error = validator.validateToken(input);
|
|
287
316
|
if (error) return error;
|
|
288
317
|
return true;
|
|
289
|
-
}
|
|
318
|
+
},
|
|
319
|
+
// Codex 的 chatgpt_login 模式不需要输入 Token
|
|
320
|
+
when: (answers) => !(answers.ideName === 'codex' && answers.authMode === 'chatgpt_login')
|
|
290
321
|
},
|
|
291
322
|
{
|
|
292
323
|
type: 'confirm',
|
package/src/commands/switch.js
CHANGED
|
@@ -40,11 +40,13 @@ class EnvSwitcher extends BaseCommand {
|
|
|
40
40
|
console.log();
|
|
41
41
|
console.log(UIHelper.createCard('供应商', UIHelper.formatProvider(provider), UIHelper.icons.info));
|
|
42
42
|
console.log();
|
|
43
|
+
// 根据 IDE 类型动态显示启动提示
|
|
44
|
+
const launchLabel = provider.ideName === 'codex' ? '启动 Codex' : '启动 Claude Code';
|
|
43
45
|
console.log(UIHelper.createHintLine([
|
|
44
46
|
['空格', '切换选中'],
|
|
45
47
|
['A', '全选'],
|
|
46
48
|
['I', '反选'],
|
|
47
|
-
['Enter',
|
|
49
|
+
['Enter', launchLabel],
|
|
48
50
|
['ESC', '返回供应商选择']
|
|
49
51
|
]));
|
|
50
52
|
console.log();
|
|
@@ -53,22 +53,22 @@ function buildEnvVariables(config) {
|
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
// Codex 配置
|
|
56
|
+
// @openai/codex 支持两种认证方式:
|
|
57
|
+
// 1. ChatGPT 登录(推荐)- 无需环境变量,使用交互式登录
|
|
58
|
+
// 2. OpenAI API Key - 通过 OPENAI_API_KEY 环境变量
|
|
56
59
|
if (config.ideName === 'codex') {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
// Codex
|
|
60
|
-
env.
|
|
60
|
+
if (config.authMode === 'api_key' && config.authToken) {
|
|
61
|
+
// 使用 OpenAI API Key 方式
|
|
62
|
+
// Codex 通过 OPENAI_API_KEY 环境变量读取 API 密钥
|
|
63
|
+
env.OPENAI_API_KEY = config.authToken;
|
|
61
64
|
|
|
62
|
-
// 如果指定了基础 URL(用于自定义 API 端点)
|
|
65
|
+
// 如果指定了基础 URL(用于自定义 OpenAI 兼容的 API 端点)
|
|
63
66
|
if (config.baseUrl) {
|
|
64
|
-
env.
|
|
67
|
+
env.OPENAI_API_BASE = config.baseUrl;
|
|
65
68
|
}
|
|
66
69
|
}
|
|
67
|
-
|
|
68
|
-
// Codex
|
|
69
|
-
if (config.models && config.models.primary) {
|
|
70
|
-
env.CODEX_MODEL = config.models.primary;
|
|
71
|
-
}
|
|
70
|
+
// 如果是 chatgpt_login 模式,不需要设置环境变量
|
|
71
|
+
// Codex 会启动交互式登录流程
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
return env;
|
|
@@ -13,6 +13,21 @@ class ProviderStatusChecker {
|
|
|
13
13
|
return this._result('unknown', '未找到配置', null);
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
// Codex 的特殊处理
|
|
17
|
+
if (provider.ideName === 'codex') {
|
|
18
|
+
if (provider.authMode === 'chatgpt_login') {
|
|
19
|
+
return this._result('online', '使用 ChatGPT 登录', null);
|
|
20
|
+
}
|
|
21
|
+
if (provider.authMode === 'api_key' && !provider.authToken) {
|
|
22
|
+
return this._result('unknown', '未配置 OpenAI API Key', null);
|
|
23
|
+
}
|
|
24
|
+
// Codex 的 api_key 模式支持检测(通过 OpenAI API)
|
|
25
|
+
// 但目前我们暂不实现 OpenAI SDK 的检测,只提示已配置
|
|
26
|
+
if (provider.authMode === 'api_key') {
|
|
27
|
+
return this._result('online', '已配置 OpenAI API Key', null);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
16
31
|
if (provider.authMode === 'oauth_token') {
|
|
17
32
|
return this._result('unknown', '暂不支持 OAuth 令牌检测', null);
|
|
18
33
|
}
|
package/src/utils/ui-helper.js
CHANGED
|
@@ -77,7 +77,13 @@ class UIHelper {
|
|
|
77
77
|
const status = provider.current ? 'current' : 'inactive';
|
|
78
78
|
const statusText = this.createStatus(status, provider.name);
|
|
79
79
|
const displayName = this.colors.secondary(`(${provider.displayName})`);
|
|
80
|
-
|
|
80
|
+
|
|
81
|
+
// 添加 IDE 类型标识
|
|
82
|
+
const ideIcon = provider.ideName === 'codex' ? '⚙️' : '🚀';
|
|
83
|
+
const ideLabel = provider.ideName === 'codex' ? 'Codex' : 'Claude Code';
|
|
84
|
+
const ideText = this.colors.muted(`[${ideIcon} ${ideLabel}]`);
|
|
85
|
+
|
|
86
|
+
return `${statusText} ${displayName} ${ideText}`;
|
|
81
87
|
}
|
|
82
88
|
|
|
83
89
|
// 创建进度条
|