ccman 1.0.1 → 2.0.1
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/.env.development +3 -0
- package/.env.production +3 -0
- package/.github/workflows/release.yml +5 -5
- package/CLAUDE.md +246 -185
- package/README.md +282 -249
- package/README_zh.md +283 -250
- package/dev-test.sh +40 -0
- package/dist/cli.js +425 -369
- package/dist/cli.js.map +1 -1
- package/dist/commands/lang.d.ts +3 -0
- package/dist/commands/lang.d.ts.map +1 -0
- package/dist/commands/lang.js +99 -0
- package/dist/commands/lang.js.map +1 -0
- package/dist/config/static-env.d.ts +14 -0
- package/dist/config/static-env.d.ts.map +1 -0
- package/dist/config/static-env.js +17 -0
- package/dist/config/static-env.js.map +1 -0
- package/dist/core/CCMConfigManager.d.ts +52 -0
- package/dist/core/CCMConfigManager.d.ts.map +1 -0
- package/dist/core/CCMConfigManager.js +203 -0
- package/dist/core/CCMConfigManager.js.map +1 -0
- package/dist/core/ClaudeConfigManager.d.ts +35 -0
- package/dist/core/ClaudeConfigManager.d.ts.map +1 -0
- package/dist/core/ClaudeConfigManager.js +149 -0
- package/dist/core/ClaudeConfigManager.js.map +1 -0
- package/dist/i18n/LanguageManager.d.ts +43 -0
- package/dist/i18n/LanguageManager.d.ts.map +1 -0
- package/dist/i18n/LanguageManager.js +157 -0
- package/dist/i18n/LanguageManager.js.map +1 -0
- package/dist/i18n/messages.d.ts +65 -0
- package/dist/i18n/messages.d.ts.map +1 -0
- package/dist/i18n/messages.js +144 -0
- package/dist/i18n/messages.js.map +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -8
- package/dist/index.js.map +1 -1
- package/dist/providers/ProviderManager.d.ts +58 -0
- package/dist/providers/ProviderManager.d.ts.map +1 -0
- package/dist/providers/ProviderManager.js +335 -0
- package/dist/providers/ProviderManager.js.map +1 -0
- package/dist/types/index.d.ts +78 -38
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/dist/utils/env-config.d.ts +27 -0
- package/dist/utils/env-config.d.ts.map +1 -0
- package/dist/{config/constants.js → utils/env-config.js} +36 -50
- package/dist/utils/env-config.js.map +1 -0
- package/dist/utils/version.d.ts +2 -64
- package/dist/utils/version.d.ts.map +1 -1
- package/dist/utils/version.js +12 -158
- package/dist/utils/version.js.map +1 -1
- package/package.json +17 -16
- package/release-temp/README.md +282 -249
- package/release-temp/package.json +17 -16
- package/scripts/build-env.js +75 -0
- package/scripts/modules/create-tag.sh +53 -10
- package/scripts/modules/monitor-release.sh +40 -12
- package/scripts/modules/version-bump.sh +14 -17
- package/scripts/smart-release-v3.sh +20 -26
- package/src/cli.ts +462 -394
- package/src/commands/lang.ts +105 -0
- package/src/core/CCMConfigManager.ts +185 -0
- package/src/core/ClaudeConfigManager.ts +125 -0
- package/src/i18n/LanguageManager.ts +169 -0
- package/src/i18n/messages.ts +233 -0
- package/src/index.ts +4 -5
- package/src/providers/ProviderManager.ts +393 -0
- package/src/types/index.ts +80 -39
- package/src/utils/env-config.ts +53 -0
- package/src/utils/version.ts +11 -184
- package/dist/config/ConfigManager.d.ts +0 -67
- package/dist/config/ConfigManager.d.ts.map +0 -1
- package/dist/config/ConfigManager.js +0 -226
- package/dist/config/ConfigManager.js.map +0 -1
- package/dist/config/EnvironmentManager.d.ts +0 -83
- package/dist/config/EnvironmentManager.d.ts.map +0 -1
- package/dist/config/EnvironmentManager.js +0 -280
- package/dist/config/EnvironmentManager.js.map +0 -1
- package/dist/config/constants.d.ts +0 -40
- package/dist/config/constants.d.ts.map +0 -1
- package/dist/config/constants.js.map +0 -1
- package/dist/shell/ShellManager.d.ts +0 -81
- package/dist/shell/ShellManager.d.ts.map +0 -1
- package/dist/shell/ShellManager.js +0 -490
- package/dist/shell/ShellManager.js.map +0 -1
- package/src/config/ConfigManager.ts +0 -227
- package/src/config/EnvironmentManager.ts +0 -327
- package/src/config/constants.ts +0 -64
- package/src/shell/ShellManager.ts +0 -526
package/dist/cli.js
CHANGED
|
@@ -7,108 +7,374 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
const commander_1 = require("commander");
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
9
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
10
|
-
const
|
|
10
|
+
const ProviderManager_1 = require("./providers/ProviderManager");
|
|
11
|
+
const LanguageManager_1 = require("./i18n/LanguageManager");
|
|
12
|
+
const lang_1 = require("./commands/lang");
|
|
11
13
|
const version_1 = require("./utils/version");
|
|
12
14
|
const program = new commander_1.Command();
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
const providerManager = new ProviderManager_1.ProviderManager();
|
|
16
|
+
const languageManager = new LanguageManager_1.LanguageManager();
|
|
17
|
+
// 询问是否继续操作
|
|
18
|
+
async function askToContinue() {
|
|
19
|
+
const messages = await languageManager.getMessages();
|
|
20
|
+
const answer = await inquirer_1.default.prompt([
|
|
21
|
+
{
|
|
22
|
+
type: 'confirm',
|
|
23
|
+
name: 'continue',
|
|
24
|
+
message: messages.forms.continueOperation,
|
|
25
|
+
default: true
|
|
26
|
+
}
|
|
27
|
+
]);
|
|
28
|
+
return answer.continue;
|
|
29
|
+
}
|
|
30
|
+
// 交互式配置菜单
|
|
31
|
+
async function showInteractiveMenu() {
|
|
32
|
+
// 处理首次运行语言设置
|
|
33
|
+
await languageManager.handleFirstRun();
|
|
34
|
+
// 获取当前语言的消息
|
|
35
|
+
const messages = await languageManager.getMessages();
|
|
36
|
+
// 设置 Ctrl+C 优雅退出处理
|
|
37
|
+
process.removeAllListeners('SIGINT');
|
|
38
|
+
process.on('SIGINT', () => {
|
|
39
|
+
console.log(chalk_1.default.yellow(messages.interruptMessage));
|
|
40
|
+
process.exit(0);
|
|
21
41
|
});
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
42
|
+
try {
|
|
43
|
+
let shouldContinue = true;
|
|
44
|
+
while (shouldContinue) {
|
|
45
|
+
await providerManager.init();
|
|
46
|
+
const providers = await providerManager.listProviders();
|
|
47
|
+
if (providers.length === 0) {
|
|
48
|
+
console.log(chalk_1.default.yellow(messages.noProvidersFound));
|
|
49
|
+
const answers = await inquirer_1.default.prompt([
|
|
50
|
+
{
|
|
51
|
+
type: 'input',
|
|
52
|
+
name: 'id',
|
|
53
|
+
message: messages.forms.providerId,
|
|
54
|
+
default: 'anthropic'
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
type: 'input',
|
|
58
|
+
name: 'name',
|
|
59
|
+
message: messages.forms.providerName,
|
|
60
|
+
default: 'Anthropic Official'
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
type: 'input',
|
|
64
|
+
name: 'description',
|
|
65
|
+
message: messages.forms.description,
|
|
66
|
+
default: 'Official Anthropic API'
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
type: 'input',
|
|
70
|
+
name: 'baseUrl',
|
|
71
|
+
message: messages.forms.baseUrl,
|
|
72
|
+
default: 'https://api.anthropic.com'
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
type: 'password',
|
|
76
|
+
name: 'apiKey',
|
|
77
|
+
message: messages.forms.apiKey,
|
|
78
|
+
mask: '*'
|
|
79
|
+
}
|
|
80
|
+
]);
|
|
81
|
+
const result = await providerManager.addProvider({
|
|
82
|
+
id: answers.id,
|
|
83
|
+
name: answers.name,
|
|
84
|
+
description: answers.description,
|
|
85
|
+
baseUrl: answers.baseUrl,
|
|
86
|
+
apiKey: answers.apiKey
|
|
87
|
+
});
|
|
88
|
+
if (result.success) {
|
|
89
|
+
console.log(chalk_1.default.green(`✓ ${result.message}`));
|
|
90
|
+
// 自动设为当前供应商
|
|
91
|
+
const useResult = await providerManager.useProvider(answers.id);
|
|
92
|
+
if (useResult.success) {
|
|
93
|
+
console.log(chalk_1.default.green(`✓ ${useResult.message}`));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
console.error(chalk_1.default.red(`✗ ${result.message}`));
|
|
98
|
+
}
|
|
99
|
+
console.log();
|
|
100
|
+
shouldContinue = await askToContinue();
|
|
101
|
+
continue;
|
|
36
102
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
103
|
+
const choices = providers.map(provider => ({
|
|
104
|
+
name: `${provider.name} (${provider.id}) - ${provider.baseUrl}${provider.isCurrent ? ' [current]' : ''}`,
|
|
105
|
+
value: provider.id
|
|
106
|
+
}));
|
|
107
|
+
const action = await inquirer_1.default.prompt([
|
|
41
108
|
{
|
|
42
109
|
type: 'list',
|
|
43
|
-
name: '
|
|
44
|
-
message:
|
|
110
|
+
name: 'action',
|
|
111
|
+
message: messages.mainMenuTitle,
|
|
45
112
|
choices: [
|
|
46
|
-
{ name:
|
|
47
|
-
{ name:
|
|
48
|
-
|
|
49
|
-
|
|
113
|
+
{ name: messages.mainMenuOptions.switchProvider, value: 'switch' },
|
|
114
|
+
{ name: messages.mainMenuOptions.addProvider, value: 'add' },
|
|
115
|
+
{ name: messages.mainMenuOptions.updateProvider, value: 'update' },
|
|
116
|
+
{ name: messages.mainMenuOptions.removeProvider, value: 'remove' },
|
|
117
|
+
{ name: messages.mainMenuOptions.showStatus, value: 'status' },
|
|
118
|
+
{ name: messages.mainMenuOptions.exit, value: 'exit' }
|
|
119
|
+
]
|
|
50
120
|
}
|
|
51
121
|
]);
|
|
52
|
-
if (
|
|
53
|
-
console.log(chalk_1.default.
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
122
|
+
if (action.action === 'exit') {
|
|
123
|
+
console.log(chalk_1.default.cyan(messages.exitMessage));
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
switch (action.action) {
|
|
127
|
+
case 'switch': {
|
|
128
|
+
const switchAnswer = await inquirer_1.default.prompt([
|
|
129
|
+
{
|
|
130
|
+
type: 'list',
|
|
131
|
+
name: 'id',
|
|
132
|
+
message: 'Select provider:',
|
|
133
|
+
choices
|
|
134
|
+
}
|
|
135
|
+
]);
|
|
136
|
+
const switchResult = await providerManager.useProvider(switchAnswer.id);
|
|
137
|
+
if (switchResult.success) {
|
|
138
|
+
console.log(chalk_1.default.green(`✓ ${switchResult.message}`));
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
console.error(chalk_1.default.red(`✗ ${switchResult.message}`));
|
|
142
|
+
}
|
|
143
|
+
console.log();
|
|
144
|
+
shouldContinue = await askToContinue();
|
|
145
|
+
break;
|
|
57
146
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
147
|
+
case 'add': {
|
|
148
|
+
const addAnswers = await inquirer_1.default.prompt([
|
|
149
|
+
{ type: 'input', name: 'id', message: 'Provider ID:' },
|
|
150
|
+
{ type: 'input', name: 'name', message: 'Provider name:' },
|
|
151
|
+
{ type: 'input', name: 'description', message: 'Description:' },
|
|
152
|
+
{ type: 'input', name: 'baseUrl', message: 'Base URL:' },
|
|
153
|
+
{ type: 'password', name: 'apiKey', message: 'API Key:', mask: '*' }
|
|
154
|
+
]);
|
|
155
|
+
const addResult = await providerManager.addProvider(addAnswers);
|
|
156
|
+
if (addResult.success) {
|
|
157
|
+
console.log(chalk_1.default.green(`✓ ${addResult.message}`));
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
console.error(chalk_1.default.red(`✗ ${addResult.message}`));
|
|
161
|
+
}
|
|
162
|
+
console.log();
|
|
163
|
+
shouldContinue = await askToContinue();
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
case 'update': {
|
|
167
|
+
const updateIdAnswer = await inquirer_1.default.prompt([
|
|
168
|
+
{
|
|
169
|
+
type: 'list',
|
|
170
|
+
name: 'id',
|
|
171
|
+
message: 'Select provider to update:',
|
|
172
|
+
choices
|
|
173
|
+
}
|
|
174
|
+
]);
|
|
175
|
+
const currentProvider = providers.find(p => p.id === updateIdAnswer.id);
|
|
176
|
+
if (currentProvider) {
|
|
177
|
+
const updateAnswers = await inquirer_1.default.prompt([
|
|
178
|
+
{ type: 'input', name: 'name', message: 'Provider name:', default: currentProvider.name },
|
|
179
|
+
{ type: 'input', name: 'description', message: 'Description:', default: currentProvider.description },
|
|
180
|
+
{ type: 'input', name: 'baseUrl', message: 'Base URL:', default: currentProvider.baseUrl },
|
|
181
|
+
{ type: 'password', name: 'apiKey', message: 'API Key (leave empty to keep current):', mask: '*' }
|
|
182
|
+
]);
|
|
183
|
+
const updateOptions = {
|
|
184
|
+
name: updateAnswers.name,
|
|
185
|
+
description: updateAnswers.description,
|
|
186
|
+
baseUrl: updateAnswers.baseUrl
|
|
187
|
+
};
|
|
188
|
+
if (updateAnswers.apiKey.trim()) {
|
|
189
|
+
updateOptions.apiKey = updateAnswers.apiKey;
|
|
190
|
+
}
|
|
191
|
+
const updateResult = await providerManager.updateProvider(updateIdAnswer.id, updateOptions);
|
|
192
|
+
if (updateResult.success) {
|
|
193
|
+
console.log(chalk_1.default.green(`✓ ${updateResult.message}`));
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
console.error(chalk_1.default.red(`✗ ${updateResult.message}`));
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
console.log();
|
|
200
|
+
shouldContinue = await askToContinue();
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
case 'remove': {
|
|
204
|
+
const removeAnswer = await inquirer_1.default.prompt([
|
|
205
|
+
{
|
|
206
|
+
type: 'list',
|
|
207
|
+
name: 'id',
|
|
208
|
+
message: 'Select provider to remove:',
|
|
209
|
+
choices
|
|
210
|
+
}
|
|
211
|
+
]);
|
|
212
|
+
const confirmRemove = await inquirer_1.default.prompt([
|
|
213
|
+
{
|
|
214
|
+
type: 'confirm',
|
|
215
|
+
name: 'confirm',
|
|
216
|
+
message: `Are you sure you want to remove this provider?`,
|
|
217
|
+
default: false
|
|
218
|
+
}
|
|
219
|
+
]);
|
|
220
|
+
if (confirmRemove.confirm) {
|
|
221
|
+
const removeResult = await providerManager.removeProvider(removeAnswer.id);
|
|
222
|
+
if (removeResult.success) {
|
|
223
|
+
console.log(chalk_1.default.green(`✓ ${removeResult.message}`));
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
console.error(chalk_1.default.red(`✗ ${removeResult.message}`));
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
console.log(chalk_1.default.yellow('Operation cancelled'));
|
|
231
|
+
}
|
|
232
|
+
console.log();
|
|
233
|
+
shouldContinue = await askToContinue();
|
|
234
|
+
break;
|
|
235
|
+
}
|
|
236
|
+
case 'status': {
|
|
237
|
+
const stats = await providerManager.getStats();
|
|
238
|
+
console.log();
|
|
239
|
+
console.log(chalk_1.default.blue('CCM Status:'));
|
|
240
|
+
console.log(`Total providers: ${stats.totalProviders}`);
|
|
241
|
+
console.log(`Current provider: ${stats.currentProvider || 'None'}`);
|
|
242
|
+
console.log(`Claude config: ${stats.claudeConfigPath}`);
|
|
243
|
+
console.log(`CCM config: ${stats.ccmConfigPath}`);
|
|
244
|
+
if (providers.length > 0) {
|
|
245
|
+
console.log();
|
|
246
|
+
console.log(chalk_1.default.blue('Recent providers:'));
|
|
247
|
+
providers
|
|
248
|
+
.filter(p => p.lastUsed)
|
|
249
|
+
.slice(0, 3)
|
|
250
|
+
.forEach(provider => {
|
|
251
|
+
const marker = provider.isCurrent ? chalk_1.default.green('* ') : ' ';
|
|
252
|
+
const name = provider.isCurrent ? chalk_1.default.green(provider.name) : provider.name;
|
|
253
|
+
const lastUsed = new Date(provider.lastUsed).toLocaleDateString();
|
|
254
|
+
console.log(`${marker}${name} (${lastUsed}, ${provider.usageCount} uses)`);
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
console.log();
|
|
258
|
+
console.log();
|
|
259
|
+
shouldContinue = await askToContinue();
|
|
260
|
+
break;
|
|
61
261
|
}
|
|
62
262
|
}
|
|
63
|
-
|
|
64
|
-
console.log(chalk_1.default.cyan('To apply changes, restart your terminal or run:'));
|
|
65
|
-
console.log(chalk_1.default.cyan('source ~/.bashrc (or ~/.zshrc)'));
|
|
66
|
-
}
|
|
67
|
-
}
|
|
263
|
+
} // while 循环结束
|
|
68
264
|
}
|
|
69
|
-
|
|
70
|
-
console.
|
|
71
|
-
|
|
265
|
+
catch (error) {
|
|
266
|
+
console.error(chalk_1.default.red(`✗ Error: ${error}`));
|
|
267
|
+
process.exit(1);
|
|
72
268
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
269
|
+
finally {
|
|
270
|
+
// 恢复原始的 SIGINT 处理器
|
|
271
|
+
process.removeAllListeners('SIGINT');
|
|
76
272
|
}
|
|
77
273
|
}
|
|
78
274
|
program
|
|
79
275
|
.name('ccman')
|
|
80
|
-
.description('Claude Code Manager - Manage Claude
|
|
81
|
-
.version((0, version_1.
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
.
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
276
|
+
.description('Claude Code Manager - Manage Claude API configurations')
|
|
277
|
+
.version((0, version_1.getPackageVersion)())
|
|
278
|
+
.hook('preAction', () => {
|
|
279
|
+
// 开发模式提示
|
|
280
|
+
if (process.env.CCM_CONFIG_DIR || process.env.CLAUDE_CONFIG_PATH) {
|
|
281
|
+
console.log(chalk_1.default.yellow('🔧 Development Mode:'));
|
|
282
|
+
if (process.env.CCM_CONFIG_DIR) {
|
|
283
|
+
console.log(chalk_1.default.yellow(` CCM Config: ${process.env.CCM_CONFIG_DIR}`));
|
|
284
|
+
}
|
|
285
|
+
if (process.env.CLAUDE_CONFIG_PATH) {
|
|
286
|
+
console.log(chalk_1.default.yellow(` Claude Config: ${process.env.CLAUDE_CONFIG_PATH}`));
|
|
287
|
+
}
|
|
288
|
+
console.log();
|
|
92
289
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
290
|
+
})
|
|
291
|
+
.action(async () => {
|
|
292
|
+
// 默认无参数时进入交互菜单
|
|
293
|
+
await showInteractiveMenu();
|
|
294
|
+
});
|
|
295
|
+
// 智能列表命令
|
|
296
|
+
program
|
|
297
|
+
.command('ls')
|
|
298
|
+
.alias('list')
|
|
299
|
+
.description('List provider configurations')
|
|
300
|
+
.option('--current', 'Show only current provider details')
|
|
301
|
+
.option('--brief', 'Show brief summary')
|
|
302
|
+
.action(async (options) => {
|
|
303
|
+
try {
|
|
304
|
+
await providerManager.init();
|
|
305
|
+
if (options?.current) {
|
|
306
|
+
// 显示当前供应商详情
|
|
307
|
+
const currentProvider = await providerManager.getCurrentProvider();
|
|
308
|
+
if (!currentProvider) {
|
|
309
|
+
console.log(chalk_1.default.yellow('No provider is currently active.'));
|
|
310
|
+
console.log('Use "ccman use <id>" to activate a provider.');
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
console.log();
|
|
314
|
+
console.log(chalk_1.default.green(`Current provider: ${currentProvider.config.name} (${currentProvider.id})`));
|
|
315
|
+
console.log(`Description: ${currentProvider.config.description}`);
|
|
316
|
+
console.log(`Base URL: ${currentProvider.config.config.env.ANTHROPIC_BASE_URL}`);
|
|
317
|
+
console.log(`API Key: ${'*'.repeat(Math.min(currentProvider.config.config.env.ANTHROPIC_AUTH_TOKEN.length, 20))}`);
|
|
318
|
+
console.log(`Usage count: ${currentProvider.config.metadata.usageCount} times`);
|
|
319
|
+
console.log(`Last updated: ${new Date(currentProvider.config.metadata.updatedAt).toLocaleString()}`);
|
|
320
|
+
console.log();
|
|
321
|
+
return;
|
|
101
322
|
}
|
|
102
|
-
|
|
103
|
-
|
|
323
|
+
const providers = await providerManager.listProviders();
|
|
324
|
+
const stats = await providerManager.getStats();
|
|
325
|
+
// 显示状态和配置信息,不管是否有providers
|
|
326
|
+
console.log();
|
|
327
|
+
console.log(chalk_1.default.blue('CCM Status:'));
|
|
328
|
+
console.log(`Total providers: ${stats.totalProviders}`);
|
|
329
|
+
console.log(`Current provider: ${stats.currentProvider || 'None'}`);
|
|
330
|
+
console.log(`Environment: ${stats.environment}`);
|
|
331
|
+
console.log();
|
|
332
|
+
console.log(chalk_1.default.blue('Configuration Files:'));
|
|
333
|
+
console.log(`Claude config: ${chalk_1.default.cyan(stats.claudeConfigPath)}`);
|
|
334
|
+
console.log(`CCM config: ${chalk_1.default.cyan(stats.ccmConfigFile)}`);
|
|
335
|
+
console.log(`Providers dir: ${chalk_1.default.cyan(stats.providersDir)}`);
|
|
336
|
+
console.log();
|
|
337
|
+
if (providers.length === 0) {
|
|
338
|
+
console.log(chalk_1.default.yellow('No provider configurations found. Use "ccman add" to create one.'));
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
if (options?.brief) {
|
|
342
|
+
// 简洁模式
|
|
343
|
+
providers.forEach(provider => {
|
|
344
|
+
const marker = provider.isCurrent ? chalk_1.default.green('* ') : ' ';
|
|
345
|
+
const name = provider.isCurrent ? chalk_1.default.green(provider.name) : provider.name;
|
|
346
|
+
console.log(`${marker}${name} (${provider.id})`);
|
|
347
|
+
});
|
|
348
|
+
console.log();
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
// 详细显示providers信息
|
|
352
|
+
console.log(chalk_1.default.blue('Providers:'));
|
|
353
|
+
providers.forEach(provider => {
|
|
354
|
+
const marker = provider.isCurrent ? chalk_1.default.green('* ') : ' ';
|
|
355
|
+
const name = provider.isCurrent ? chalk_1.default.green(provider.name) : provider.name;
|
|
356
|
+
console.log(`${marker}${name.padEnd(15)} ${provider.baseUrl}`);
|
|
357
|
+
console.log(`${' '.repeat(17)} ${provider.description}`);
|
|
358
|
+
if (provider.lastUsed) {
|
|
359
|
+
const lastUsed = new Date(provider.lastUsed).toLocaleDateString();
|
|
360
|
+
console.log(`${' '.repeat(17)} Last used: ${lastUsed}, Usage: ${provider.usageCount} times`);
|
|
361
|
+
}
|
|
362
|
+
console.log();
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
catch (error) {
|
|
366
|
+
console.error(chalk_1.default.red(`✗ Error: ${error}`));
|
|
367
|
+
process.exit(1);
|
|
368
|
+
}
|
|
104
369
|
});
|
|
105
|
-
//
|
|
370
|
+
// 添加供应商
|
|
106
371
|
program
|
|
107
|
-
.command('add <name> <baseUrl> [apiKey]')
|
|
108
|
-
.description('Add a new
|
|
109
|
-
.option('--
|
|
110
|
-
.action(async (name, baseUrl, apiKey, options) => {
|
|
372
|
+
.command('add <id> <name> <baseUrl> [apiKey]')
|
|
373
|
+
.description('Add a new provider configuration')
|
|
374
|
+
.option('-d, --description <desc>', 'Provider description')
|
|
375
|
+
.action(async (id, name, baseUrl, apiKey, options) => {
|
|
111
376
|
try {
|
|
377
|
+
await providerManager.init();
|
|
112
378
|
if (!apiKey) {
|
|
113
379
|
const answer = await inquirer_1.default.prompt([
|
|
114
380
|
{
|
|
@@ -121,62 +387,99 @@ program
|
|
|
121
387
|
apiKey = answer.apiKey;
|
|
122
388
|
}
|
|
123
389
|
const addOptions = {
|
|
390
|
+
id,
|
|
124
391
|
name,
|
|
392
|
+
description: options?.description,
|
|
125
393
|
baseUrl,
|
|
126
|
-
apiKey: apiKey
|
|
127
|
-
autoWriteShell: options?.autoWrite
|
|
394
|
+
apiKey: apiKey
|
|
128
395
|
};
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
396
|
+
const result = await providerManager.addProvider(addOptions);
|
|
397
|
+
if (result.success) {
|
|
398
|
+
console.log(chalk_1.default.green(`✓ ${result.message}`));
|
|
399
|
+
// 询问是否设为当前供应商
|
|
400
|
+
const currentProvider = await providerManager.getCurrentProvider();
|
|
401
|
+
if (!currentProvider || currentProvider.id !== id) {
|
|
402
|
+
const useAnswer = await inquirer_1.default.prompt([
|
|
403
|
+
{
|
|
404
|
+
type: 'confirm',
|
|
405
|
+
name: 'useCurrent',
|
|
406
|
+
message: `Set "${name}" as current provider?`,
|
|
407
|
+
default: true
|
|
408
|
+
}
|
|
409
|
+
]);
|
|
410
|
+
if (useAnswer.useCurrent) {
|
|
411
|
+
const useResult = await providerManager.useProvider(id);
|
|
412
|
+
if (useResult.success) {
|
|
413
|
+
console.log(chalk_1.default.green(`✓ ${useResult.message}`));
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
console.error(chalk_1.default.red(`✗ ${useResult.message}`));
|
|
417
|
+
}
|
|
142
418
|
}
|
|
143
|
-
]);
|
|
144
|
-
if (useAnswer.useCurrent) {
|
|
145
|
-
await performUseEnvironment(name, {
|
|
146
|
-
autoWrite: options?.autoWrite,
|
|
147
|
-
skipSuccessMessage: true // 因为前面已经显示了添加成功的信息
|
|
148
|
-
});
|
|
149
419
|
}
|
|
150
420
|
}
|
|
421
|
+
else {
|
|
422
|
+
console.error(chalk_1.default.red(`✗ ${result.message}`));
|
|
423
|
+
process.exit(1);
|
|
424
|
+
}
|
|
151
425
|
}
|
|
152
426
|
catch (error) {
|
|
153
427
|
console.error(chalk_1.default.red(`✗ Error: ${error}`));
|
|
154
428
|
process.exit(1);
|
|
155
429
|
}
|
|
156
430
|
});
|
|
157
|
-
//
|
|
431
|
+
// 使用供应商
|
|
158
432
|
program
|
|
159
|
-
.command('
|
|
160
|
-
.
|
|
161
|
-
.
|
|
162
|
-
.action(async (name) => {
|
|
433
|
+
.command('use <id>')
|
|
434
|
+
.description('Switch to a provider configuration')
|
|
435
|
+
.action(async (id) => {
|
|
163
436
|
try {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
437
|
+
await providerManager.init();
|
|
438
|
+
const result = await providerManager.useProvider(id);
|
|
439
|
+
if (result.success) {
|
|
440
|
+
console.log(chalk_1.default.green(`✓ ${result.message}`));
|
|
441
|
+
console.log(chalk_1.default.cyan('Claude Code configuration has been updated successfully!'));
|
|
442
|
+
}
|
|
443
|
+
else {
|
|
444
|
+
console.error(chalk_1.default.red(`✗ ${result.message}`));
|
|
445
|
+
process.exit(1);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
catch (error) {
|
|
449
|
+
console.error(chalk_1.default.red(`✗ Error: ${error}`));
|
|
450
|
+
process.exit(1);
|
|
451
|
+
}
|
|
452
|
+
});
|
|
453
|
+
// 删除供应商
|
|
454
|
+
program
|
|
455
|
+
.command('rm <id>')
|
|
456
|
+
.alias('remove')
|
|
457
|
+
.description('Remove a provider configuration')
|
|
458
|
+
.action(async (id) => {
|
|
459
|
+
try {
|
|
460
|
+
await providerManager.init();
|
|
461
|
+
const providers = await providerManager.listProviders();
|
|
462
|
+
const provider = providers.find(p => p.id === id);
|
|
463
|
+
if (!provider) {
|
|
464
|
+
console.error(chalk_1.default.red(`✗ Provider '${id}' not found`));
|
|
167
465
|
process.exit(1);
|
|
168
466
|
}
|
|
169
467
|
const answer = await inquirer_1.default.prompt([
|
|
170
468
|
{
|
|
171
469
|
type: 'confirm',
|
|
172
470
|
name: 'confirm',
|
|
173
|
-
message: `Are you sure you want to remove
|
|
471
|
+
message: `Are you sure you want to remove provider "${provider.name}" (${id})?`,
|
|
174
472
|
default: false
|
|
175
473
|
}
|
|
176
474
|
]);
|
|
177
475
|
if (answer.confirm) {
|
|
178
|
-
await
|
|
179
|
-
|
|
476
|
+
const result = await providerManager.removeProvider(id);
|
|
477
|
+
if (result.success) {
|
|
478
|
+
console.log(chalk_1.default.green(`✓ ${result.message}`));
|
|
479
|
+
}
|
|
480
|
+
else {
|
|
481
|
+
console.error(chalk_1.default.red(`✗ ${result.message}`));
|
|
482
|
+
}
|
|
180
483
|
}
|
|
181
484
|
else {
|
|
182
485
|
console.log(chalk_1.default.yellow('Operation cancelled'));
|
|
@@ -187,115 +490,18 @@ program
|
|
|
187
490
|
process.exit(1);
|
|
188
491
|
}
|
|
189
492
|
});
|
|
190
|
-
// 使用环境
|
|
191
|
-
program
|
|
192
|
-
.command('use <name>')
|
|
193
|
-
.description('Switch to an environment group')
|
|
194
|
-
.option('--no-auto-write', 'Do not automatically write to shell config')
|
|
195
|
-
.option('--auto-source', 'Automatically source shell config after writing (risky)')
|
|
196
|
-
.action(async (name, options) => {
|
|
197
|
-
try {
|
|
198
|
-
await performUseEnvironment(name, {
|
|
199
|
-
autoWrite: options?.autoWrite,
|
|
200
|
-
autoSource: options?.autoSource
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
catch (error) {
|
|
204
|
-
console.error(chalk_1.default.red(`✗ Error: ${error}`));
|
|
205
|
-
process.exit(1);
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
// 显示当前环境
|
|
209
|
-
program
|
|
210
|
-
.command('current')
|
|
211
|
-
.description('Show current environment group')
|
|
212
|
-
.action(() => {
|
|
213
|
-
const currentEnv = envManager.getCurrentEnvironment();
|
|
214
|
-
if (!currentEnv) {
|
|
215
|
-
console.log(chalk_1.default.yellow('No environment is currently active.'));
|
|
216
|
-
console.log('Use "ccman use <name>" to activate an environment.');
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
console.log();
|
|
220
|
-
console.log(chalk_1.default.green(`Current environment: ${currentEnv.name}`));
|
|
221
|
-
console.log(`Base URL: ${currentEnv.baseUrl}`);
|
|
222
|
-
console.log(`API Key: ${'*'.repeat(Math.min(currentEnv.apiKey.length, 20))}`);
|
|
223
|
-
console.log(`Created: ${new Date(currentEnv.createdAt).toLocaleString()}`);
|
|
224
|
-
if (currentEnv.lastUsed) {
|
|
225
|
-
console.log(`Last used: ${new Date(currentEnv.lastUsed).toLocaleString()}`);
|
|
226
|
-
}
|
|
227
|
-
console.log();
|
|
228
|
-
});
|
|
229
|
-
// 生成环境变量脚本
|
|
230
|
-
program
|
|
231
|
-
.command('env')
|
|
232
|
-
.description('Generate shell script to set environment variables')
|
|
233
|
-
.action(() => {
|
|
234
|
-
try {
|
|
235
|
-
const script = envManager.generateEnvScript();
|
|
236
|
-
console.log(script);
|
|
237
|
-
}
|
|
238
|
-
catch (error) {
|
|
239
|
-
console.error(chalk_1.default.red(`✗ Error: ${error}`));
|
|
240
|
-
process.exit(1);
|
|
241
|
-
}
|
|
242
|
-
});
|
|
243
|
-
// 测试环境
|
|
244
|
-
program
|
|
245
|
-
.command('test [name]')
|
|
246
|
-
.description('Test environment configuration (defaults to current)')
|
|
247
|
-
.action(async (name) => {
|
|
248
|
-
const result = await envManager.testEnvironment(name);
|
|
249
|
-
if (result.success) {
|
|
250
|
-
console.log(chalk_1.default.green(`✓ ${result.message}`));
|
|
251
|
-
}
|
|
252
|
-
else {
|
|
253
|
-
console.error(chalk_1.default.red(`✗ ${result.message}`));
|
|
254
|
-
if (result.error) {
|
|
255
|
-
console.error(chalk_1.default.gray(`Details: ${result.error}`));
|
|
256
|
-
}
|
|
257
|
-
process.exit(1);
|
|
258
|
-
}
|
|
259
|
-
});
|
|
260
|
-
// 显示统计信息
|
|
261
|
-
program
|
|
262
|
-
.command('status')
|
|
263
|
-
.description('Show CCM status and statistics')
|
|
264
|
-
.action(() => {
|
|
265
|
-
const stats = envManager.getStats();
|
|
266
|
-
const environments = envManager.listEnvironments();
|
|
267
|
-
console.log();
|
|
268
|
-
console.log(chalk_1.default.blue('CCM Status:'));
|
|
269
|
-
console.log(`Total environments: ${stats.totalEnvironments}`);
|
|
270
|
-
console.log(`Current environment: ${stats.currentEnvironment || 'None'}`);
|
|
271
|
-
console.log(`Shell integration: ${stats.hasShellIntegration ? 'Enabled' : 'Disabled'}`);
|
|
272
|
-
if (environments.length > 0) {
|
|
273
|
-
console.log();
|
|
274
|
-
console.log(chalk_1.default.blue('Recent environments:'));
|
|
275
|
-
const sortedEnvs = environments
|
|
276
|
-
.filter(env => env.lastUsed)
|
|
277
|
-
.sort((a, b) => new Date(b.lastUsed).getTime() - new Date(a.lastUsed).getTime())
|
|
278
|
-
.slice(0, 3);
|
|
279
|
-
sortedEnvs.forEach(env => {
|
|
280
|
-
const lastUsed = new Date(env.lastUsed).toLocaleDateString();
|
|
281
|
-
console.log(` ${env.name} (${lastUsed})`);
|
|
282
|
-
});
|
|
283
|
-
}
|
|
284
|
-
console.log();
|
|
285
|
-
});
|
|
286
493
|
// 清除所有配置
|
|
287
494
|
program
|
|
288
495
|
.command('clear')
|
|
289
|
-
.alias('
|
|
290
|
-
.description('Clear all
|
|
496
|
+
.alias('reset')
|
|
497
|
+
.description('Clear all provider configurations (DESTRUCTIVE)')
|
|
291
498
|
.action(async () => {
|
|
292
499
|
try {
|
|
293
|
-
// 确认操作
|
|
294
500
|
const confirmAnswer = await inquirer_1.default.prompt([
|
|
295
501
|
{
|
|
296
502
|
type: 'confirm',
|
|
297
503
|
name: 'confirmed',
|
|
298
|
-
message: chalk_1.default.red('⚠️ This will remove ALL
|
|
504
|
+
message: chalk_1.default.red('⚠️ This will remove ALL provider configurations. Are you sure?'),
|
|
299
505
|
default: false
|
|
300
506
|
}
|
|
301
507
|
]);
|
|
@@ -303,174 +509,24 @@ program
|
|
|
303
509
|
console.log(chalk_1.default.yellow('Operation cancelled.'));
|
|
304
510
|
return;
|
|
305
511
|
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
const result = await envManager.clearAll();
|
|
309
|
-
// 显示结果
|
|
310
|
-
console.log();
|
|
512
|
+
await providerManager.init();
|
|
513
|
+
const result = await providerManager.clearAll();
|
|
311
514
|
if (result.success) {
|
|
312
515
|
console.log(chalk_1.default.green(`✓ ${result.message}`));
|
|
516
|
+
console.log(chalk_1.default.cyan('CCM has been reset to initial state.'));
|
|
517
|
+
console.log(chalk_1.default.cyan('You can start fresh with: ccman'));
|
|
313
518
|
}
|
|
314
519
|
else {
|
|
315
|
-
console.
|
|
520
|
+
console.error(chalk_1.default.red(`✗ ${result.message}`));
|
|
316
521
|
}
|
|
317
|
-
// 显示详细信息
|
|
318
|
-
if (result.details.length > 0) {
|
|
319
|
-
console.log();
|
|
320
|
-
result.details.forEach(detail => {
|
|
321
|
-
if (detail.startsWith('✓')) {
|
|
322
|
-
console.log(chalk_1.default.green(detail));
|
|
323
|
-
}
|
|
324
|
-
else if (detail.startsWith('⚠')) {
|
|
325
|
-
console.log(chalk_1.default.yellow(detail));
|
|
326
|
-
}
|
|
327
|
-
else if (detail.startsWith('✗')) {
|
|
328
|
-
console.log(chalk_1.default.red(detail));
|
|
329
|
-
}
|
|
330
|
-
else {
|
|
331
|
-
console.log(detail);
|
|
332
|
-
}
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
|
-
console.log();
|
|
336
|
-
console.log(chalk_1.default.cyan('CCM has been reset to initial state.'));
|
|
337
|
-
console.log(chalk_1.default.cyan('You can start fresh with: ccman config'));
|
|
338
522
|
}
|
|
339
523
|
catch (error) {
|
|
340
524
|
console.error(chalk_1.default.red(`✗ Error: ${error}`));
|
|
341
525
|
process.exit(1);
|
|
342
526
|
}
|
|
343
527
|
});
|
|
344
|
-
//
|
|
345
|
-
program
|
|
346
|
-
.command('config')
|
|
347
|
-
.description('Interactive configuration')
|
|
348
|
-
.action(async () => {
|
|
349
|
-
const environments = envManager.listEnvironments();
|
|
350
|
-
if (environments.length === 0) {
|
|
351
|
-
console.log(chalk_1.default.yellow('No environments found. Let\'s create your first one.'));
|
|
352
|
-
const answers = await inquirer_1.default.prompt([
|
|
353
|
-
{ type: 'input', name: 'name', message: 'Environment name:', default: 'default' },
|
|
354
|
-
{ type: 'input', name: 'baseUrl', message: 'Base URL:', default: 'https://api.anthropic.com' },
|
|
355
|
-
{ type: 'password', name: 'apiKey', message: 'API Key:', mask: '*' },
|
|
356
|
-
{ type: 'confirm', name: 'autoWrite', message: 'Automatically write to shell config?', default: true }
|
|
357
|
-
]);
|
|
358
|
-
try {
|
|
359
|
-
await envManager.addEnvironment({
|
|
360
|
-
name: answers.name,
|
|
361
|
-
baseUrl: answers.baseUrl,
|
|
362
|
-
apiKey: answers.apiKey,
|
|
363
|
-
autoWriteShell: answers.autoWrite
|
|
364
|
-
});
|
|
365
|
-
console.log(chalk_1.default.green(`✓ Created environment "${answers.name}"`));
|
|
366
|
-
}
|
|
367
|
-
catch (error) {
|
|
368
|
-
console.error(chalk_1.default.red(`✗ Error: ${error}`));
|
|
369
|
-
}
|
|
370
|
-
return;
|
|
371
|
-
}
|
|
372
|
-
const choices = environments.map(env => ({
|
|
373
|
-
name: `${env.name} (${env.baseUrl})${env.isCurrent ? ' [current]' : ''}`,
|
|
374
|
-
value: env.name
|
|
375
|
-
}));
|
|
376
|
-
const action = await inquirer_1.default.prompt([
|
|
377
|
-
{
|
|
378
|
-
type: 'list',
|
|
379
|
-
name: 'action',
|
|
380
|
-
message: 'What would you like to do?',
|
|
381
|
-
choices: [
|
|
382
|
-
{ name: 'Switch environment', value: 'switch' },
|
|
383
|
-
{ name: 'Add new environment', value: 'add' },
|
|
384
|
-
{ name: 'Edit environment', value: 'edit' },
|
|
385
|
-
{ name: 'Remove environment', value: 'remove' },
|
|
386
|
-
{ name: 'Show current status', value: 'status' }
|
|
387
|
-
]
|
|
388
|
-
}
|
|
389
|
-
]);
|
|
390
|
-
switch (action.action) {
|
|
391
|
-
case 'switch':
|
|
392
|
-
const switchAnswer = await inquirer_1.default.prompt([
|
|
393
|
-
{
|
|
394
|
-
type: 'list',
|
|
395
|
-
name: 'name',
|
|
396
|
-
message: 'Select environment:',
|
|
397
|
-
choices
|
|
398
|
-
}
|
|
399
|
-
]);
|
|
400
|
-
try {
|
|
401
|
-
await performUseEnvironment(switchAnswer.name);
|
|
402
|
-
}
|
|
403
|
-
catch (error) {
|
|
404
|
-
console.error(chalk_1.default.red(`✗ Error: ${error}`));
|
|
405
|
-
}
|
|
406
|
-
break;
|
|
407
|
-
case 'add':
|
|
408
|
-
const addAnswers = await inquirer_1.default.prompt([
|
|
409
|
-
{ type: 'input', name: 'name', message: 'Environment name:' },
|
|
410
|
-
{ type: 'input', name: 'baseUrl', message: 'Base URL:' },
|
|
411
|
-
{ type: 'password', name: 'apiKey', message: 'API Key:', mask: '*' }
|
|
412
|
-
]);
|
|
413
|
-
try {
|
|
414
|
-
await envManager.addEnvironment(addAnswers);
|
|
415
|
-
console.log(chalk_1.default.green(`✓ Added environment "${addAnswers.name}"`));
|
|
416
|
-
}
|
|
417
|
-
catch (error) {
|
|
418
|
-
console.error(chalk_1.default.red(`✗ Error: ${error}`));
|
|
419
|
-
}
|
|
420
|
-
break;
|
|
421
|
-
case 'edit':
|
|
422
|
-
const editEnvAnswer = await inquirer_1.default.prompt([
|
|
423
|
-
{
|
|
424
|
-
type: 'list',
|
|
425
|
-
name: 'name',
|
|
426
|
-
message: 'Select environment to edit:',
|
|
427
|
-
choices
|
|
428
|
-
}
|
|
429
|
-
]);
|
|
430
|
-
const currentConfig = envManager.getEnvironment(editEnvAnswer.name);
|
|
431
|
-
if (currentConfig) {
|
|
432
|
-
const editAnswers = await inquirer_1.default.prompt([
|
|
433
|
-
{ type: 'input', name: 'baseUrl', message: 'Base URL:', default: currentConfig.baseUrl },
|
|
434
|
-
{ type: 'password', name: 'apiKey', message: 'API Key:', mask: '*', default: currentConfig.apiKey }
|
|
435
|
-
]);
|
|
436
|
-
try {
|
|
437
|
-
await envManager.updateEnvironment(editEnvAnswer.name, {
|
|
438
|
-
baseUrl: editAnswers.baseUrl,
|
|
439
|
-
apiKey: editAnswers.apiKey
|
|
440
|
-
});
|
|
441
|
-
console.log(chalk_1.default.green(`✓ Updated environment "${editEnvAnswer.name}"`));
|
|
442
|
-
}
|
|
443
|
-
catch (error) {
|
|
444
|
-
console.error(chalk_1.default.red(`✗ Error: ${error}`));
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
break;
|
|
448
|
-
case 'status':
|
|
449
|
-
{
|
|
450
|
-
const stats = envManager.getStats();
|
|
451
|
-
const environments = envManager.listEnvironments();
|
|
452
|
-
console.log();
|
|
453
|
-
console.log(chalk_1.default.blue('CCM Status:'));
|
|
454
|
-
console.log(`Total environments: ${stats.totalEnvironments}`);
|
|
455
|
-
console.log(`Current environment: ${stats.currentEnvironment || 'None'}`);
|
|
456
|
-
console.log(`Shell integration: ${stats.hasShellIntegration ? 'Enabled' : 'Disabled'}`);
|
|
457
|
-
if (environments.length > 0) {
|
|
458
|
-
console.log();
|
|
459
|
-
console.log(chalk_1.default.blue('Recent environments:'));
|
|
460
|
-
environments
|
|
461
|
-
.sort((a, b) => new Date(b.lastUsed || b.createdAt).getTime() - new Date(a.lastUsed || a.createdAt).getTime())
|
|
462
|
-
.slice(0, 3)
|
|
463
|
-
.forEach(env => {
|
|
464
|
-
const marker = env.isCurrent ? chalk_1.default.green('* ') : ' ';
|
|
465
|
-
const name = env.isCurrent ? chalk_1.default.green(env.name) : env.name;
|
|
466
|
-
console.log(`${marker}${name.padEnd(15)} ${env.baseUrl}`);
|
|
467
|
-
});
|
|
468
|
-
}
|
|
469
|
-
console.log();
|
|
470
|
-
}
|
|
471
|
-
break;
|
|
472
|
-
}
|
|
473
|
-
});
|
|
528
|
+
// 添加语言管理命令
|
|
529
|
+
program.addCommand((0, lang_1.createLanguageCommands)());
|
|
474
530
|
// 解析命令行参数
|
|
475
|
-
program.parse();
|
|
531
|
+
program.parse(process.argv);
|
|
476
532
|
//# sourceMappingURL=cli.js.map
|