@pikecode/api-key-manager 1.0.39 → 1.0.42

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.
@@ -1,19 +1,40 @@
1
+ /**
2
+ * Current Config Command
3
+ * 显示当前激活的供应商配置
4
+ * @module commands/current
5
+ */
6
+
1
7
  const chalk = require('chalk');
2
8
  const { configManager } = require('../config');
3
9
  const { Logger } = require('../utils/logger');
4
10
  const { maybeMaskToken } = require('../utils/secrets');
11
+ const { AUTH_MODE_DISPLAY, TOKEN_TYPE_DISPLAY, BASE_URL, CURRENT_STATUS } = require('../constants');
5
12
 
13
+ /**
14
+ * 当前配置显示类
15
+ * 用于显示当前激活的 API 供应商配置详情
16
+ */
6
17
  class CurrentConfig {
18
+ /**
19
+ * 创建当前配置显示器实例
20
+ */
7
21
  constructor() {
8
22
  this.configManager = configManager;
9
23
  }
10
24
 
25
+ /**
26
+ * 显示当前供应商配置
27
+ * @param {Object} options - 显示选项
28
+ * @param {boolean} [options.showToken=true] - 是否显示完整 token
29
+ * @returns {Promise<void>}
30
+ */
11
31
  async show(options = {}) {
12
32
  try {
13
- const showToken = Boolean(options.showToken);
33
+ // 默认显示完整 token,不再加密
34
+ const showToken = options.showToken !== false;
14
35
  await this.configManager.ensureLoaded();
15
36
  const currentProvider = this.configManager.getCurrentProvider();
16
-
37
+
17
38
  if (!currentProvider) {
18
39
  Logger.warning('未设置当前供应商');
19
40
  Logger.info('请使用 "akm <供应商名>" 切换供应商');
@@ -22,7 +43,7 @@ class CurrentConfig {
22
43
 
23
44
  console.log(chalk.blue('\n📍 当前配置:'));
24
45
  console.log(chalk.gray('═'.repeat(60)));
25
-
46
+
26
47
  console.log(chalk.green(`供应商: ${currentProvider.displayName}`));
27
48
  console.log(chalk.gray(`内部名称: ${currentProvider.name}`));
28
49
 
@@ -50,16 +71,11 @@ class CurrentConfig {
50
71
  }
51
72
 
52
73
  // 显示认证模式
53
- const authModeDisplay = {
54
- api_key: '通用API密钥模式',
55
- auth_token: '认证令牌模式',
56
- oauth_token: 'OAuth令牌模式'
57
- };
58
- console.log(chalk.gray(`认证模式: ${authModeDisplay[currentProvider.authMode] || currentProvider.authMode}`));
74
+ console.log(chalk.gray(`认证模式: ${AUTH_MODE_DISPLAY[currentProvider.authMode] || currentProvider.authMode}`));
59
75
 
60
76
  // 如果是 api_key 模式,显示 tokenType
61
77
  if (currentProvider.authMode === 'api_key' && currentProvider.tokenType) {
62
- const tokenTypeDisplay = currentProvider.tokenType === 'auth_token' ? 'ANTHROPIC_AUTH_TOKEN' : 'ANTHROPIC_API_KEY';
78
+ const tokenTypeDisplay = TOKEN_TYPE_DISPLAY[currentProvider.tokenType];
63
79
  console.log(chalk.gray(`Token类型: ${tokenTypeDisplay}`));
64
80
  }
65
81
 
@@ -69,15 +85,15 @@ class CurrentConfig {
69
85
  console.log(chalk.gray(`认证Token: ${maybeMaskToken(currentProvider.authToken, showToken)}`));
70
86
  console.log(chalk.gray(`创建时间: ${new Date(currentProvider.createdAt).toLocaleString()}`));
71
87
  console.log(chalk.gray(`最后使用: ${new Date(currentProvider.lastUsed).toLocaleString()}`));
72
-
88
+
73
89
  // 显示模型配置
74
90
  if (currentProvider.models && (currentProvider.models.primary || currentProvider.models.smallFast)) {
75
91
  console.log(chalk.gray(`主模型: ${currentProvider.models.primary || '未设置'}`));
76
92
  console.log(chalk.gray(`快速模型: ${currentProvider.models.smallFast || '未设置'}`));
77
93
  }
78
-
94
+
79
95
  console.log(chalk.gray('═'.repeat(60)));
80
-
96
+
81
97
  // 显示环境变量设置方式
82
98
  console.log(chalk.blue('\n🔧 环境变量设置:'));
83
99
  if (currentProvider.baseUrl) {
@@ -103,7 +119,7 @@ class CurrentConfig {
103
119
  console.log(chalk.gray(`set ANTHROPIC_SMALL_FAST_MODEL=${currentProvider.models.smallFast}`));
104
120
  }
105
121
  console.log(chalk.gray('claude'));
106
-
122
+
107
123
  } catch (error) {
108
124
  Logger.error(`获取当前配置失败: ${error.message}`);
109
125
  throw error;
@@ -1,3 +1,9 @@
1
+ /**
2
+ * Provider Editor Command
3
+ * 编辑现有供应商配置
4
+ * @module commands/edit
5
+ */
6
+
1
7
  const inquirer = require('inquirer');
2
8
  const chalk = require('chalk');
3
9
  const { configManager } = require('../config');
@@ -5,13 +11,27 @@ const { validator } = require('../utils/validator');
5
11
  const { Logger } = require('../utils/logger');
6
12
  const { UIHelper } = require('../utils/ui-helper');
7
13
  const { BaseCommand } = require('./BaseCommand');
14
+ const { AUTH_MODE_DISPLAY, TOKEN_TYPE_DISPLAY, IDE_NAMES } = require('../constants');
8
15
 
16
+ /**
17
+ * 供应商编辑器类
18
+ * 用于交互式编辑现有的 API 供应商配置
19
+ * @extends BaseCommand
20
+ */
9
21
  class ProviderEditor extends BaseCommand {
22
+ /**
23
+ * 创建供应商编辑器实例
24
+ */
10
25
  constructor() {
11
26
  super();
12
27
  this.configManager = configManager;
13
28
  }
14
29
 
30
+ /**
31
+ * 执行交互式编辑供应商流程
32
+ * @param {string} [providerName] - 要编辑的供应商名称,如果不提供则让用户选择
33
+ * @returns {Promise<void>}
34
+ */
15
35
  async interactive(providerName) {
16
36
  await this.configManager.load();
17
37
  const providers = this.configManager.listProviders();
@@ -23,40 +43,40 @@ class ProviderEditor extends BaseCommand {
23
43
 
24
44
  let providerToEdit;
25
45
  if (providerName) {
26
- providerToEdit = this.configManager.getProvider(providerName);
27
- if (!providerToEdit) {
28
- Logger.error(`供应商 '${providerName}' 不存在。`);
29
- return;
30
- }
46
+ providerToEdit = this.configManager.getProvider(providerName);
47
+ if (!providerToEdit) {
48
+ Logger.error(`供应商 '${providerName}' 不存在。`);
49
+ return;
50
+ }
31
51
  } else {
32
- let selection;
33
- try {
34
- selection = await this.prompt([
35
- {
36
- type: 'list',
37
- name: 'selectedProviderName',
38
- message: '请选择要编辑的供应商:',
39
- choices: [
40
- ...providers.map(p => ({ name: p.displayName || p.name, value: p.name })),
41
- new inquirer.Separator(),
42
- { name: '取消', value: null },
43
- ],
44
- },
45
- ]);
46
- } catch (error) {
47
- if (this.isEscCancelled(error)) {
48
- return;
52
+ let selection;
53
+ try {
54
+ selection = await this.prompt([
55
+ {
56
+ type: 'list',
57
+ name: 'selectedProviderName',
58
+ message: '请选择要编辑的供应商:',
59
+ choices: [
60
+ ...providers.map(p => ({ name: p.displayName || p.name, value: p.name })),
61
+ new inquirer.Separator(),
62
+ { name: '取消', value: null }
63
+ ]
49
64
  }
50
- throw error;
65
+ ]);
66
+ } catch (error) {
67
+ if (this.isEscCancelled(error)) {
68
+ return;
51
69
  }
70
+ throw error;
71
+ }
52
72
 
53
- const { selectedProviderName } = selection;
73
+ const { selectedProviderName } = selection;
54
74
 
55
- if (!selectedProviderName) {
56
- Logger.info('操作已取消。');
57
- return;
58
- }
59
- providerToEdit = this.configManager.getProvider(selectedProviderName);
75
+ if (!selectedProviderName) {
76
+ Logger.info('操作已取消。');
77
+ return;
78
+ }
79
+ providerToEdit = this.configManager.getProvider(selectedProviderName);
60
80
  }
61
81
 
62
82
  console.log(UIHelper.createTitle(`编辑供应商: ${providerToEdit.displayName}`, UIHelper.icons.edit));
@@ -81,7 +101,7 @@ class ProviderEditor extends BaseCommand {
81
101
  name: 'displayName',
82
102
  message: '供应商显示名称:',
83
103
  default: providerToEdit.displayName,
84
- validate: (input) => validator.validateDisplayName(input) || true,
104
+ validate: (input) => validator.validateDisplayName(input) || true
85
105
  }
86
106
  ];
87
107
 
@@ -123,13 +143,13 @@ class ProviderEditor extends BaseCommand {
123
143
  ...codexArgs.map(arg => ({
124
144
  name: `${arg.label} (${arg.name})${arg.description ? ' - ' + arg.description : ''}`,
125
145
  value: arg.name,
126
- checked: existingLaunchArgs.includes(arg.name),
146
+ checked: existingLaunchArgs.includes(arg.name)
127
147
  })),
128
148
  ...customCodexArgs.map(arg => ({
129
149
  name: `${arg} ${chalk.gray('(自定义参数)')}`,
130
150
  value: arg,
131
- checked: true,
132
- })),
151
+ checked: true
152
+ }))
133
153
  ],
134
154
  validate: (selected) => {
135
155
  const conflictError = checkExclusiveArgs(selected, codexArgs);
@@ -149,9 +169,9 @@ class ProviderEditor extends BaseCommand {
149
169
  choices: [
150
170
  { name: '🔑 通用API密钥模式 - 支持 ANTHROPIC_API_KEY 和 ANTHROPIC_AUTH_TOKEN', value: 'api_key' },
151
171
  { name: '🔐 认证令牌模式 (仅 ANTHROPIC_AUTH_TOKEN) - 适用于某些服务商', value: 'auth_token' },
152
- { name: '🌐 OAuth令牌模式 (CLAUDE_CODE_OAUTH_TOKEN) - 适用于官方Claude Code', value: 'oauth_token' },
172
+ { name: '🌐 OAuth令牌模式 (CLAUDE_CODE_OAUTH_TOKEN) - 适用于官方Claude Code', value: 'oauth_token' }
153
173
  ],
154
- default: providerToEdit.authMode,
174
+ default: providerToEdit.authMode
155
175
  },
156
176
  {
157
177
  type: 'list',
@@ -180,23 +200,23 @@ class ProviderEditor extends BaseCommand {
180
200
  }
181
201
  return validator.validateUrl(input) || true;
182
202
  },
183
- when: (answers) => answers.authMode === 'api_key' || answers.authMode === 'auth_token',
203
+ when: (answers) => answers.authMode === 'api_key' || answers.authMode === 'auth_token'
184
204
  },
185
205
  {
186
206
  type: 'input',
187
207
  name: 'authToken',
188
208
  message: (answers) => {
189
209
  switch (answers.authMode) {
190
- case 'api_key':
191
- const tokenTypeLabel = answers.tokenType === 'auth_token' ? 'ANTHROPIC_AUTH_TOKEN' : 'ANTHROPIC_API_KEY';
192
- return `Token (${tokenTypeLabel}):`;
193
- case 'auth_token': return '认证令牌 (ANTHROPIC_AUTH_TOKEN):';
194
- case 'oauth_token': return 'OAuth令牌 (CLAUDE_CODE_OAUTH_TOKEN):';
195
- default: return '认证令牌:';
210
+ case 'api_key':
211
+ const tokenTypeLabel = answers.tokenType === 'auth_token' ? 'ANTHROPIC_AUTH_TOKEN' : 'ANTHROPIC_API_KEY';
212
+ return `Token (${tokenTypeLabel}):`;
213
+ case 'auth_token': return '认证令牌 (ANTHROPIC_AUTH_TOKEN):';
214
+ case 'oauth_token': return 'OAuth令牌 (CLAUDE_CODE_OAUTH_TOKEN):';
215
+ default: return '认证令牌:';
196
216
  }
197
217
  },
198
218
  default: providerToEdit.authToken,
199
- validate: (input) => validator.validateToken(input) || true,
219
+ validate: (input) => validator.validateToken(input) || true
200
220
  },
201
221
  {
202
222
  type: 'checkbox',
@@ -205,8 +225,8 @@ class ProviderEditor extends BaseCommand {
205
225
  choices: validator.getAvailableLaunchArgs().map(arg => ({
206
226
  name: `${arg.label || arg.name} (${arg.name})${arg.description ? ' - ' + arg.description : ''}`,
207
227
  value: arg.name,
208
- checked: providerToEdit.launchArgs && providerToEdit.launchArgs.includes(arg.name),
209
- })),
228
+ checked: providerToEdit.launchArgs && providerToEdit.launchArgs.includes(arg.name)
229
+ }))
210
230
  }
211
231
  );
212
232
  }
@@ -262,7 +282,7 @@ class ProviderEditor extends BaseCommand {
262
282
  // Retain original model settings unless we add editing for them
263
283
  primaryModel: existingProvider.models?.primary || null,
264
284
  smallFastModel: existingProvider.models?.smallFast || null,
265
- setAsDefault: false, // Don't change default status on edit
285
+ setAsDefault: false // Don't change default status on edit
266
286
  });
267
287
  }
268
288
 
@@ -0,0 +1,222 @@
1
+ /**
2
+ * Health Check Command
3
+ * 配置健康检查和告警
4
+ * @module commands/health
5
+ */
6
+
7
+ const chalk = require('chalk');
8
+ const { configManager } = require('../config');
9
+ const { Logger } = require('../utils/logger');
10
+ const { HealthChecker } = require('../utils/health-checker');
11
+ const { UIHelper } = require('../utils/ui-helper');
12
+
13
+ /**
14
+ * 显示单个供应商的健康检查
15
+ * @param {string} providerName - 供应商名称或别名
16
+ * @param {Object} options - 选项
17
+ */
18
+ async function showProviderHealth(providerName, options = {}) {
19
+ try {
20
+ await configManager.ensureLoaded();
21
+
22
+ // 支持别名查找
23
+ let provider = configManager.getProvider(providerName);
24
+ if (!provider) {
25
+ provider = configManager.getProviderByNameOrAlias(providerName);
26
+ }
27
+
28
+ if (!provider) {
29
+ Logger.error(`供应商 '${providerName}' 不存在`);
30
+ Logger.info('使用 "akm list" 查看所有已配置的供应商');
31
+ return;
32
+ }
33
+
34
+ console.log(chalk.blue(`\n🏥 健康检查: ${provider.displayName} (${provider.name})`));
35
+ console.log(chalk.gray('═'.repeat(60)));
36
+ console.log();
37
+
38
+ const checker = new HealthChecker();
39
+ const loadingInterval = UIHelper.createLoadingAnimation('检查中...');
40
+
41
+ try {
42
+ const results = await checker.performHealthCheck(provider, options);
43
+ UIHelper.clearLoadingAnimation(loadingInterval);
44
+
45
+ console.log(checker.formatHealthReport(results));
46
+ console.log();
47
+
48
+ // 如果有问题,显示建议
49
+ if (results.overallStatus === 'error' || results.overallStatus === 'warning') {
50
+ console.log(chalk.yellow('💡 建议操作:'));
51
+
52
+ if (results.checks.tokenExpiry?.status === 'expired' || results.checks.tokenExpiry?.status === 'critical') {
53
+ console.log(chalk.yellow(' • 使用 "akm edit" 更新 Token'));
54
+ }
55
+
56
+ if (results.checks.quota?.status === 'exceeded' || results.checks.quota?.status === 'critical') {
57
+ console.log(chalk.yellow(' • 检查 API 配额使用情况'));
58
+ console.log(chalk.yellow(' • 考虑升级套餐或添加新的供应商'));
59
+ }
60
+
61
+ if (results.checks.connectivity?.status === 'offline') {
62
+ console.log(chalk.yellow(' • 检查网络连接'));
63
+ console.log(chalk.yellow(' • 验证 Token 是否正确'));
64
+ console.log(chalk.yellow(' • 使用 "akm validate" 进行详细诊断'));
65
+ }
66
+
67
+ if (results.checks.lastUsed?.status === 'stale') {
68
+ console.log(chalk.yellow(' • 考虑删除长期未使用的配置'));
69
+ console.log(chalk.yellow(' • 或运行一次验证确保仍然可用'));
70
+ }
71
+
72
+ console.log();
73
+ }
74
+
75
+ } catch (error) {
76
+ UIHelper.clearLoadingAnimation(loadingInterval);
77
+ Logger.error(`健康检查失败: ${error.message}`);
78
+ }
79
+
80
+ } catch (error) {
81
+ Logger.error(`健康检查执行失败: ${error.message}`);
82
+ throw error;
83
+ }
84
+ }
85
+
86
+ /**
87
+ * 显示所有供应商的健康检查
88
+ * @param {Object} options - 选项
89
+ */
90
+ async function showAllHealth(options = {}) {
91
+ try {
92
+ await configManager.ensureLoaded();
93
+ let providers = configManager.listProviders();
94
+
95
+ // 应用过滤器
96
+ if (options.filter === 'codex') {
97
+ providers = providers.filter(p => p.ideName === 'codex');
98
+ } else if (options.filter === 'claude') {
99
+ providers = providers.filter(p => p.ideName !== 'codex');
100
+ }
101
+
102
+ if (providers.length === 0) {
103
+ if (options.filter) {
104
+ const filterName = options.filter === 'codex' ? 'Codex CLI' : 'Claude Code';
105
+ Logger.warning(`暂无 ${filterName} 供应商配置`);
106
+ } else {
107
+ Logger.warning('暂无配置的供应商');
108
+ }
109
+ Logger.info('请使用 "akm add" 添加供应商配置');
110
+ return;
111
+ }
112
+
113
+ const titleSuffix = options.filter === 'codex' ? ' (Codex CLI)' : (options.filter === 'claude' ? ' (Claude Code)' : '');
114
+ console.log(chalk.blue(`\n🏥 健康检查${titleSuffix}`));
115
+ console.log(chalk.gray('═'.repeat(60)));
116
+ console.log();
117
+
118
+ const checker = new HealthChecker();
119
+ const allResults = [];
120
+ let completedCount = 0;
121
+ const total = providers.length;
122
+
123
+ // 创建进度显示
124
+ const progressInterval = setInterval(() => {
125
+ process.stdout.write(`\r检查中... ${completedCount}/${total}`);
126
+ }, 100);
127
+
128
+ try {
129
+ // 并行检查所有供应商
130
+ const checkPromises = providers.map(async (provider) => {
131
+ const results = await checker.performHealthCheck(provider, {
132
+ checkConnectivity: options.connectivity !== false
133
+ });
134
+ completedCount++;
135
+ return results;
136
+ });
137
+
138
+ const results = await Promise.all(checkPromises);
139
+ clearInterval(progressInterval);
140
+ process.stdout.write('\r' + ' '.repeat(50) + '\r'); // 清除进度显示
141
+
142
+ allResults.push(...results);
143
+
144
+ // 显示结果
145
+ const currentProvider = configManager.getCurrentProvider();
146
+
147
+ results.forEach((result, index) => {
148
+ const provider = providers[index];
149
+ const isCurrent = provider.name === currentProvider?.name;
150
+ const statusIcon = isCurrent ? '✅' : '🔹';
151
+
152
+ console.log(checker.formatHealthReport(result));
153
+ if (isCurrent) {
154
+ console.log(chalk.green(' (当前活跃)'));
155
+ }
156
+ console.log();
157
+ });
158
+
159
+ // 显示统计
160
+ const errorCount = allResults.filter(r => r.overallStatus === 'error').length;
161
+ const warningCount = allResults.filter(r => r.overallStatus === 'warning').length;
162
+ const okCount = allResults.filter(r => r.overallStatus === 'ok' || r.overallStatus === 'info').length;
163
+
164
+ console.log(chalk.gray('═'.repeat(60)));
165
+ console.log(chalk.blue('📊 健康统计:'));
166
+ console.log(` 总计: ${total} 个供应商`);
167
+ console.log(` ${chalk.green('✓')} 健康: ${okCount}`);
168
+ console.log(` ${chalk.yellow('⚠')} 警告: ${warningCount}`);
169
+ console.log(` ${chalk.red('✗')} 错误: ${errorCount}`);
170
+
171
+ // 显示需要关注的问题
172
+ if (errorCount > 0 || warningCount > 0) {
173
+ console.log();
174
+ console.log(chalk.yellow('⚠️ 发现需要关注的问题:'));
175
+
176
+ allResults.forEach((result) => {
177
+ const hasIssue = result.overallStatus === 'error' || result.overallStatus === 'warning';
178
+ if (hasIssue) {
179
+ const issues = Object.entries(result.checks)
180
+ .filter(([_, check]) => check.level === 'error' || check.level === 'warning')
181
+ .map(([name, check]) => `${checker._getCheckLabel(name)}: ${check.message}`);
182
+
183
+ if (issues.length > 0) {
184
+ console.log(chalk.yellow(` • ${result.displayName}:`));
185
+ issues.forEach(issue => {
186
+ console.log(chalk.yellow(` - ${issue}`));
187
+ });
188
+ }
189
+ }
190
+ });
191
+ }
192
+
193
+ } catch (error) {
194
+ clearInterval(progressInterval);
195
+ Logger.error(`批量健康检查失败: ${error.message}`);
196
+ }
197
+
198
+ } catch (error) {
199
+ Logger.error(`健康检查执行失败: ${error.message}`);
200
+ throw error;
201
+ }
202
+ }
203
+
204
+ /**
205
+ * 健康检查命令
206
+ * @param {string|null} providerName - 供应商名称
207
+ * @param {Object} options - 选项
208
+ */
209
+ async function healthCommand(providerName, options = {}) {
210
+ try {
211
+ if (providerName) {
212
+ await showProviderHealth(providerName, options);
213
+ } else {
214
+ await showAllHealth(options);
215
+ }
216
+ } catch (error) {
217
+ Logger.error(`健康检查失败: ${error.message}`);
218
+ throw error;
219
+ }
220
+ }
221
+
222
+ module.exports = { healthCommand };
@@ -1,18 +1,40 @@
1
+ /**
2
+ * Provider Lister Command
3
+ * 列出和显示所有配置的供应商
4
+ * @module commands/list
5
+ */
6
+
1
7
  const chalk = require('chalk');
2
8
  const { configManager } = require('../config');
3
9
  const { Logger } = require('../utils/logger');
4
10
  const { ProviderStatusChecker } = require('../utils/provider-status-checker');
5
11
  const { maybeMaskToken } = require('../utils/secrets');
12
+ const { AUTH_MODE_DISPLAY, TOKEN_TYPE_DISPLAY, BASE_URL } = require('../constants');
6
13
 
14
+ /**
15
+ * 供应商列表显示类
16
+ * 用于列出、过滤和显示所有配置的 API 供应商
17
+ */
7
18
  class ProviderLister {
19
+ /**
20
+ * 创建供应商列表显示器实例
21
+ */
8
22
  constructor() {
9
23
  this.configManager = configManager;
10
24
  this.statusChecker = new ProviderStatusChecker();
11
25
  }
12
26
 
27
+ /**
28
+ * 列出供应商配置
29
+ * @param {string|null} filter - 过滤器 ('codex', 'claude', 或 null 表示全部)
30
+ * @param {Object} options - 显示选项
31
+ * @param {boolean} [options.showToken=true] - 是否显示完整 token
32
+ * @returns {Promise<void>}
33
+ */
13
34
  async list(filter = null, options = {}) {
14
35
  try {
15
- const showToken = Boolean(options.showToken);
36
+ // 默认显示完整 token,不再加密
37
+ const showToken = options.showToken !== false;
16
38
  await this.configManager.ensureLoaded();
17
39
  let providers = this.configManager.listProviders();
18
40
  const currentProvider = this.configManager.getCurrentProvider();
@@ -54,7 +76,9 @@ class ProviderLister {
54
76
  ? chalk.cyan('[Codex]')
55
77
  : chalk.magenta('[Claude]');
56
78
 
57
- console.log(`${status} ${availabilityIcon} ${ideTag} ${nameColor(provider.name)} (${provider.displayName}) - ${availabilityText}`);
79
+ // 如果有别名,显示别名
80
+ const aliasText = provider.alias ? chalk.yellow(` [别名: ${provider.alias}]`) : '';
81
+ console.log(`${status} ${availabilityIcon} ${ideTag} ${nameColor(provider.name)} (${provider.displayName})${aliasText} - ${availabilityText}`);
58
82
 
59
83
  if (provider.ideName === 'codex') {
60
84
  console.log(chalk.gray(' IDE: Codex CLI'));
@@ -66,12 +90,7 @@ class ProviderLister {
66
90
  }
67
91
  } else {
68
92
  // 显示认证模式
69
- const authModeDisplay = {
70
- api_key: '通用API密钥模式',
71
- auth_token: '认证令牌模式',
72
- oauth_token: 'OAuth令牌模式'
73
- };
74
- console.log(chalk.gray(` 认证模式: ${authModeDisplay[provider.authMode] || provider.authMode}`));
93
+ console.log(chalk.gray(` 认证模式: ${AUTH_MODE_DISPLAY[provider.authMode] || provider.authMode}`));
75
94
 
76
95
  // 根据不同模式显示对应的环境变量名称
77
96
  if (provider.authMode === 'oauth_token') {
@@ -88,7 +107,7 @@ class ProviderLister {
88
107
  console.log(chalk.gray(` ANTHROPIC_BASE_URL: ${provider.baseUrl}`));
89
108
  }
90
109
  if (provider.authToken) {
91
- const tokenEnvName = provider.tokenType === 'auth_token' ? 'ANTHROPIC_AUTH_TOKEN' : 'ANTHROPIC_API_KEY';
110
+ const tokenEnvName = TOKEN_TYPE_DISPLAY[provider.tokenType] || 'ANTHROPIC_API_KEY';
92
111
  console.log(chalk.gray(` ${tokenEnvName}: ${maybeMaskToken(provider.authToken, showToken)}`));
93
112
  }
94
113
  } else {
@@ -118,7 +137,7 @@ class ProviderLister {
118
137
  });
119
138
 
120
139
  console.log(chalk.gray('═'.repeat(60)));
121
-
140
+
122
141
  if (currentProvider) {
123
142
  console.log(chalk.green(`\n当前供应商: ${currentProvider.displayName}`));
124
143
  } else {
@@ -126,7 +145,7 @@ class ProviderLister {
126
145
  }
127
146
 
128
147
  console.log(chalk.blue(`\n总计: ${providers.length} 个供应商`));
129
-
148
+
130
149
  } catch (error) {
131
150
  Logger.error(`获取供应商列表失败: ${error.message}`);
132
151
  throw error;
@@ -1,19 +1,38 @@
1
+ /**
2
+ * Provider Remover Command
3
+ * 删除供应商配置
4
+ * @module commands/remove
5
+ */
6
+
1
7
  const inquirer = require('inquirer');
2
8
  const { configManager } = require('../config');
3
9
  const { Logger } = require('../utils/logger');
4
10
  const { UIHelper } = require('../utils/ui-helper');
5
11
  const { BaseCommand } = require('./BaseCommand');
6
12
 
13
+ /**
14
+ * 供应商删除器类
15
+ * 用于删除已配置的 API 供应商
16
+ * @extends BaseCommand
17
+ */
7
18
  class ProviderRemover extends BaseCommand {
19
+ /**
20
+ * 创建供应商删除器实例
21
+ */
8
22
  constructor() {
9
23
  super();
10
24
  this.configManager = configManager;
11
25
  }
12
26
 
27
+ /**
28
+ * 删除供应商配置
29
+ * @param {string} [providerName] - 要删除的供应商名称,如果不提供则进入交互式选择
30
+ * @returns {Promise<void>}
31
+ */
13
32
  async remove(providerName) {
14
33
  try {
15
34
  await this.configManager.ensureLoaded();
16
-
35
+
17
36
  // 如果没有指定供应商名称,显示选择列表
18
37
  if (!providerName) {
19
38
  return await this.interactiveRemove();
@@ -50,7 +69,7 @@ class ProviderRemover extends BaseCommand {
50
69
 
51
70
  await this.configManager.removeProvider(providerName);
52
71
  Logger.success(`供应商 '${provider.displayName}' 已删除`);
53
-
72
+
54
73
  } catch (error) {
55
74
  if (this.isEscCancelled(error)) {
56
75
  return;
@@ -63,7 +82,7 @@ class ProviderRemover extends BaseCommand {
63
82
  async interactiveRemove() {
64
83
  await this.configManager.ensureLoaded();
65
84
  const providers = this.configManager.listProviders();
66
-
85
+
67
86
  if (providers.length === 0) {
68
87
  Logger.warning('暂无配置的供应商');
69
88
  return;