ccjk 10.1.0 → 10.3.0
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 +28 -0
- package/dist/chunks/agent-teams.mjs +1 -1
- package/dist/chunks/agent.mjs +1 -1
- package/dist/chunks/api-providers.mjs +1 -1
- package/dist/chunks/api.mjs +3 -3
- package/dist/chunks/auto-bootstrap.mjs +1 -1
- package/dist/chunks/auto-updater.mjs +1 -1
- package/dist/{shared/ccjk.Br91zBIG.mjs → chunks/banner.mjs} +52 -3
- package/dist/chunks/boost.mjs +2 -2
- package/dist/chunks/ccjk-agents.mjs +1 -1
- package/dist/chunks/ccjk-all.mjs +1 -1
- package/dist/chunks/ccjk-config.mjs +1 -1
- package/dist/chunks/ccjk-hooks.mjs +1 -1
- package/dist/chunks/ccjk-mcp.mjs +2 -2
- package/dist/chunks/ccjk-setup.mjs +1 -1
- package/dist/chunks/ccjk-skills.mjs +1 -1
- package/dist/chunks/ccr.mjs +11 -10
- package/dist/chunks/ccu.mjs +1 -1
- package/dist/chunks/check-updates.mjs +4 -3
- package/dist/chunks/claude-code-config-manager.mjs +8 -7
- package/dist/chunks/claude-code-incremental-manager.mjs +3 -2
- package/dist/chunks/claude-config.mjs +3 -3
- package/dist/chunks/claude-wrapper.mjs +2 -2
- package/dist/chunks/codex-config-switch.mjs +3 -2
- package/dist/chunks/codex-provider-manager.mjs +3 -2
- package/dist/chunks/codex-uninstaller.mjs +2 -2
- package/dist/chunks/codex.mjs +5 -5
- package/dist/chunks/commands.mjs +88 -391
- package/dist/chunks/commands2.mjs +391 -88
- package/dist/chunks/completion.mjs +1 -1
- package/dist/chunks/config-consolidator.mjs +2 -2
- package/dist/chunks/config-switch.mjs +4 -3
- package/dist/chunks/config.mjs +6 -98
- package/dist/chunks/config2.mjs +411 -400
- package/dist/chunks/config3.mjs +401 -410
- package/dist/chunks/constants.mjs +1 -1
- package/dist/chunks/context.mjs +283 -1
- package/dist/chunks/dashboard.mjs +365 -0
- package/dist/chunks/doctor.mjs +4 -4
- package/dist/chunks/features.mjs +12 -11
- package/dist/chunks/fs-operations.mjs +1 -1
- package/dist/chunks/health-alerts.mjs +304 -0
- package/dist/chunks/health-check.mjs +532 -0
- package/dist/chunks/index.mjs +10 -177
- package/dist/chunks/index2.mjs +168 -1162
- package/dist/chunks/index3.mjs +1076 -910
- package/dist/chunks/index4.mjs +947 -137
- package/dist/chunks/index5.mjs +167 -635
- package/dist/chunks/index6.mjs +663 -0
- package/dist/chunks/init.mjs +19 -19
- package/dist/chunks/installer.mjs +649 -147
- package/dist/chunks/installer2.mjs +147 -649
- package/dist/chunks/interview.mjs +2 -2
- package/dist/chunks/marketplace.mjs +1 -1
- package/dist/chunks/mcp.mjs +5 -4
- package/dist/chunks/menu.mjs +22 -9
- package/dist/chunks/metrics-display.mjs +152 -0
- package/dist/chunks/migrator.mjs +1 -1
- package/dist/chunks/monitor.mjs +2 -2
- package/dist/chunks/notification.mjs +1 -1
- package/dist/chunks/onboarding.mjs +2 -2
- package/dist/chunks/package.mjs +1 -1
- package/dist/chunks/permission-manager.mjs +2 -2
- package/dist/chunks/permissions.mjs +1 -1
- package/dist/chunks/persistence-manager.mjs +781 -0
- package/dist/chunks/persistence.mjs +667 -0
- package/dist/chunks/platform.mjs +1 -1
- package/dist/chunks/plugin.mjs +1 -1
- package/dist/chunks/prompts.mjs +1 -1
- package/dist/chunks/providers.mjs +1 -1
- package/dist/chunks/quick-actions.mjs +321 -0
- package/dist/chunks/quick-provider.mjs +2 -0
- package/dist/chunks/quick-setup.mjs +9 -8
- package/dist/chunks/silent-updater.mjs +1 -1
- package/dist/chunks/simple-config.mjs +3 -8
- package/dist/chunks/skill.mjs +1 -1
- package/dist/chunks/skills-sync.mjs +1 -1
- package/dist/chunks/skills.mjs +1 -1
- package/dist/chunks/slash-commands.mjs +208 -0
- package/dist/chunks/smart-defaults.mjs +1 -1
- package/dist/chunks/startup.mjs +1 -1
- package/dist/chunks/stats.mjs +1 -1
- package/dist/chunks/status.mjs +31 -2
- package/dist/chunks/team.mjs +1 -1
- package/dist/chunks/thinking.mjs +2 -2
- package/dist/chunks/uninstall.mjs +5 -5
- package/dist/chunks/update.mjs +8 -7
- package/dist/chunks/upgrade-manager.mjs +2 -2
- package/dist/chunks/version-checker.mjs +3 -3
- package/dist/chunks/vim.mjs +1 -1
- package/dist/chunks/zero-config.mjs +359 -0
- package/dist/cli.mjs +212 -21
- package/dist/i18n/locales/en/cli.json +14 -1
- package/dist/i18n/locales/en/common.json +27 -0
- package/dist/i18n/locales/en/configuration.json +33 -0
- package/dist/i18n/locales/en/context.json +54 -1
- package/dist/i18n/locales/en/dashboard.json +78 -0
- package/dist/i18n/locales/en/persistence.json +127 -0
- package/dist/i18n/locales/en/quick-actions.json +78 -0
- package/dist/i18n/locales/zh-CN/cli.json +14 -1
- package/dist/i18n/locales/zh-CN/common.json +27 -0
- package/dist/i18n/locales/zh-CN/configuration.json +33 -0
- package/dist/i18n/locales/zh-CN/context.json +54 -1
- package/dist/i18n/locales/zh-CN/dashboard.json +78 -0
- package/dist/i18n/locales/zh-CN/persistence.json +127 -0
- package/dist/i18n/locales/zh-CN/quick-actions.json +78 -0
- package/dist/index.mjs +3 -2
- package/dist/shared/{ccjk.DE91nClQ.mjs → ccjk.BKoi8-Hy.mjs} +1 -1
- package/dist/shared/ccjk.BiCrMV5O.mjs +94 -0
- package/dist/shared/{ccjk.Dpw86UX0.mjs → ccjk.CxtuJxaS.mjs} +1 -1
- package/dist/shared/{ccjk.ClzTOz9n.mjs → ccjk.DB2UYcq0.mjs} +5 -5
- package/dist/shared/{ccjk.CmsW23FN.mjs → ccjk.DVBW2wxp.mjs} +4 -3
- package/dist/shared/{ccjk.Bndhan7G.mjs → ccjk.DfwJOEok.mjs} +1 -1
- package/dist/shared/{ccjk.DvIrK0wz.mjs → ccjk.DrMygfCF.mjs} +1 -1
- package/package.json +19 -19
package/dist/chunks/config3.mjs
CHANGED
|
@@ -1,465 +1,456 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { existsSync, copyFileSync, mkdirSync } from 'node:fs';
|
|
3
|
-
import { homedir } from 'node:os';
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
4
2
|
import process__default from 'node:process';
|
|
5
|
-
import { promisify } from 'node:util';
|
|
6
3
|
import ansis from 'ansis';
|
|
7
|
-
import dayjs from 'dayjs';
|
|
8
4
|
import inquirer from 'inquirer';
|
|
9
|
-
import {
|
|
5
|
+
import { getApiProviderPresets } from './api-providers.mjs';
|
|
10
6
|
import { SETTINGS_FILE } from './constants.mjs';
|
|
11
|
-
import {
|
|
12
|
-
import { s as setPrimaryApiKey, a as addCompletedOnboarding } from './claude-config.mjs';
|
|
7
|
+
import { i18n } from './index2.mjs';
|
|
13
8
|
import { b as backupExistingConfig } from './config.mjs';
|
|
14
|
-
import
|
|
15
|
-
import
|
|
9
|
+
import 'node:os';
|
|
10
|
+
import 'pathe';
|
|
16
11
|
import 'node:url';
|
|
17
12
|
import 'i18next';
|
|
18
13
|
import 'i18next-fs-backend';
|
|
19
|
-
import '
|
|
20
|
-
import '
|
|
14
|
+
import 'dayjs';
|
|
15
|
+
import './claude-config.mjs';
|
|
16
|
+
import './json-config.mjs';
|
|
21
17
|
import './fs-operations.mjs';
|
|
22
18
|
import 'node:crypto';
|
|
23
19
|
import 'node:fs/promises';
|
|
24
|
-
import '
|
|
20
|
+
import './platform.mjs';
|
|
21
|
+
import 'tinyexec';
|
|
22
|
+
import '../shared/ccjk.BiCrMV5O.mjs';
|
|
25
23
|
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
async function getConfig(key, options = {}) {
|
|
25
|
+
const isZh = i18n.language === "zh-CN";
|
|
26
|
+
try {
|
|
27
|
+
const config = readClaudeConfig();
|
|
28
|
+
if (!config) {
|
|
29
|
+
console.log(ansis.yellow(isZh ? "\u26A0\uFE0F \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728" : "\u26A0\uFE0F Configuration file not found"));
|
|
30
|
+
console.log(ansis.dim(isZh ? '\u8FD0\u884C "ccjk init" \u521D\u59CB\u5316\u914D\u7F6E' : 'Run "ccjk init" to initialize configuration'));
|
|
31
|
+
console.log("");
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const value = getNestedValue(config, key);
|
|
35
|
+
if (value === void 0) {
|
|
36
|
+
console.log(ansis.yellow(isZh ? `\u26A0\uFE0F \u914D\u7F6E\u9879 "${key}" \u4E0D\u5B58\u5728` : `\u26A0\uFE0F Configuration key "${key}" not found`));
|
|
37
|
+
console.log("");
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
if (options.json) {
|
|
41
|
+
console.log(JSON.stringify(value, null, 2));
|
|
42
|
+
} else {
|
|
43
|
+
console.log("");
|
|
44
|
+
console.log(ansis.bold.cyan(isZh ? `\u{1F4CB} \u914D\u7F6E\u9879: ${key}` : `\u{1F4CB} Configuration: ${key}`));
|
|
45
|
+
console.log(ansis.dim("\u2500".repeat(60)));
|
|
46
|
+
console.log("");
|
|
47
|
+
displayValue(value, 0);
|
|
48
|
+
console.log("");
|
|
49
|
+
}
|
|
50
|
+
} catch (error) {
|
|
51
|
+
console.error(ansis.red(isZh ? "\u274C \u8BFB\u53D6\u914D\u7F6E\u5931\u8D25" : "\u274C Failed to read configuration"));
|
|
52
|
+
if (error instanceof Error) {
|
|
53
|
+
console.error(ansis.dim(error.message));
|
|
54
|
+
}
|
|
55
|
+
console.log("");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async function setConfig(key, value, _options = {}) {
|
|
59
|
+
const isZh = i18n.language === "zh-CN";
|
|
60
|
+
try {
|
|
61
|
+
const config = readClaudeConfig();
|
|
62
|
+
if (!config) {
|
|
63
|
+
console.log(ansis.yellow(isZh ? "\u26A0\uFE0F \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728" : "\u26A0\uFE0F Configuration file not found"));
|
|
64
|
+
console.log(ansis.dim(isZh ? '\u8FD0\u884C "ccjk init" \u521D\u59CB\u5316\u914D\u7F6E' : 'Run "ccjk init" to initialize configuration'));
|
|
65
|
+
console.log("");
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const backupPath = backupExistingConfig();
|
|
69
|
+
if (backupPath) {
|
|
70
|
+
console.log(ansis.dim(isZh ? `\u{1F4E6} \u5DF2\u5907\u4EFD\u914D\u7F6E\u5230: ${backupPath}` : `\u{1F4E6} Configuration backed up to: ${backupPath}`));
|
|
71
|
+
}
|
|
72
|
+
let parsedValue = value;
|
|
73
|
+
try {
|
|
74
|
+
parsedValue = JSON.parse(value);
|
|
75
|
+
} catch {
|
|
76
|
+
}
|
|
77
|
+
setNestedValue(config, key, parsedValue);
|
|
78
|
+
writeClaudeConfig(config);
|
|
79
|
+
console.log("");
|
|
80
|
+
console.log(ansis.green(isZh ? `\u2705 \u914D\u7F6E\u9879 "${key}" \u5DF2\u66F4\u65B0` : `\u2705 Configuration "${key}" updated`));
|
|
81
|
+
console.log("");
|
|
82
|
+
console.log(ansis.bold(isZh ? "\u65B0\u503C:" : "New value:"));
|
|
83
|
+
displayValue(parsedValue, 0);
|
|
84
|
+
console.log("");
|
|
85
|
+
} catch (error) {
|
|
86
|
+
console.error(ansis.red(isZh ? "\u274C \u8BBE\u7F6E\u914D\u7F6E\u5931\u8D25" : "\u274C Failed to set configuration"));
|
|
87
|
+
if (error instanceof Error) {
|
|
88
|
+
console.error(ansis.dim(error.message));
|
|
89
|
+
}
|
|
90
|
+
console.log("");
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async function listConfig(options = {}) {
|
|
94
|
+
const isZh = i18n.language === "zh-CN";
|
|
95
|
+
try {
|
|
96
|
+
const config = readClaudeConfig();
|
|
97
|
+
if (!config) {
|
|
98
|
+
console.log(ansis.yellow(isZh ? "\u26A0\uFE0F \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728" : "\u26A0\uFE0F Configuration file not found"));
|
|
99
|
+
console.log(ansis.dim(isZh ? '\u8FD0\u884C "ccjk init" \u521D\u59CB\u5316\u914D\u7F6E' : 'Run "ccjk init" to initialize configuration'));
|
|
100
|
+
console.log("");
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (options.json) {
|
|
104
|
+
console.log(JSON.stringify(config, null, 2));
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
console.log("");
|
|
108
|
+
console.log(ansis.bold.cyan(isZh ? "\u{1F4CB} Claude Code \u914D\u7F6E" : "\u{1F4CB} Claude Code Configuration"));
|
|
109
|
+
console.log(ansis.dim("\u2500".repeat(60)));
|
|
110
|
+
console.log("");
|
|
111
|
+
displayConfigSection(isZh ? "API \u914D\u7F6E" : "API Configuration", {
|
|
112
|
+
baseUrl: config.baseUrl,
|
|
113
|
+
apiKey: config.apiKey ? "***" : void 0,
|
|
114
|
+
authToken: config.authToken ? "***" : void 0,
|
|
115
|
+
model: config.model,
|
|
116
|
+
fastModel: config.fastModel
|
|
117
|
+
}, isZh);
|
|
118
|
+
if (config.mcpServers && Object.keys(config.mcpServers).length > 0) {
|
|
119
|
+
displayConfigSection(isZh ? "MCP \u670D\u52A1" : "MCP Services", {
|
|
120
|
+
count: Object.keys(config.mcpServers).length,
|
|
121
|
+
services: Object.keys(config.mcpServers)
|
|
122
|
+
}, isZh);
|
|
123
|
+
}
|
|
124
|
+
if (config.customInstructions) {
|
|
125
|
+
displayConfigSection(isZh ? "\u81EA\u5B9A\u4E49\u6307\u4EE4" : "Custom Instructions", {
|
|
126
|
+
length: config.customInstructions.length,
|
|
127
|
+
preview: `${config.customInstructions.substring(0, 100)}...`
|
|
128
|
+
}, isZh);
|
|
129
|
+
}
|
|
130
|
+
console.log("");
|
|
131
|
+
console.log(ansis.dim("\u2500".repeat(60)));
|
|
132
|
+
console.log(ansis.dim(isZh ? `\u914D\u7F6E\u6587\u4EF6: ${SETTINGS_FILE}` : `Config file: ${SETTINGS_FILE}`));
|
|
133
|
+
console.log("");
|
|
134
|
+
} catch (error) {
|
|
135
|
+
console.error(ansis.red(isZh ? "\u274C \u8BFB\u53D6\u914D\u7F6E\u5931\u8D25" : "\u274C Failed to read configuration"));
|
|
136
|
+
if (error instanceof Error) {
|
|
137
|
+
console.error(ansis.dim(error.message));
|
|
138
|
+
}
|
|
139
|
+
console.log("");
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
async function resetConfig(_options = {}) {
|
|
143
|
+
const isZh = i18n.language === "zh-CN";
|
|
28
144
|
try {
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
145
|
+
const config = readClaudeConfig();
|
|
146
|
+
if (!config) {
|
|
147
|
+
console.log(ansis.yellow(isZh ? "\u26A0\uFE0F \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728" : "\u26A0\uFE0F Configuration file not found"));
|
|
148
|
+
console.log("");
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const { confirm } = await inquirer.prompt({
|
|
152
|
+
type: "confirm",
|
|
153
|
+
name: "confirm",
|
|
154
|
+
message: isZh ? "\u786E\u5B9A\u8981\u91CD\u7F6E\u914D\u7F6E\u5417\uFF1F\u8FD9\u5C06\u5220\u9664\u6240\u6709\u81EA\u5B9A\u4E49\u8BBE\u7F6E\u3002" : "Are you sure you want to reset configuration? This will remove all custom settings.",
|
|
155
|
+
default: false
|
|
33
156
|
});
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const data = await response.json();
|
|
39
|
-
const presets = [];
|
|
40
|
-
if (Array.isArray(data)) {
|
|
41
|
-
for (const provider of data) {
|
|
42
|
-
if (provider && typeof provider === "object") {
|
|
43
|
-
presets.push({
|
|
44
|
-
name: provider.name || "",
|
|
45
|
-
provider: provider.name || "",
|
|
46
|
-
baseURL: provider.api_base_url || provider.baseURL || provider.url,
|
|
47
|
-
requiresApiKey: provider.api_key === "" || provider.requiresApiKey !== false,
|
|
48
|
-
models: provider.models || [],
|
|
49
|
-
description: provider.description || provider.name || "",
|
|
50
|
-
transformer: provider.transformer
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
} else if (data && typeof data === "object") {
|
|
55
|
-
for (const [key, value] of Object.entries(data)) {
|
|
56
|
-
if (typeof value === "object" && value !== null) {
|
|
57
|
-
const provider = value;
|
|
58
|
-
presets.push({
|
|
59
|
-
name: provider.name || key,
|
|
60
|
-
provider: key,
|
|
61
|
-
baseURL: provider.api_base_url || provider.baseURL || provider.url,
|
|
62
|
-
requiresApiKey: provider.api_key === "" || provider.requiresApiKey !== false,
|
|
63
|
-
models: provider.models || [],
|
|
64
|
-
description: provider.description || "",
|
|
65
|
-
transformer: provider.transformer
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
}
|
|
157
|
+
if (!confirm) {
|
|
158
|
+
console.log(ansis.yellow(isZh ? "\u5DF2\u53D6\u6D88" : "Cancelled"));
|
|
159
|
+
console.log("");
|
|
160
|
+
return;
|
|
69
161
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
162
|
+
const backupPath = backupExistingConfig();
|
|
163
|
+
if (backupPath) {
|
|
164
|
+
console.log(ansis.dim(isZh ? `\u{1F4E6} \u5DF2\u5907\u4EFD\u914D\u7F6E\u5230: ${backupPath}` : `\u{1F4E6} Configuration backed up to: ${backupPath}`));
|
|
165
|
+
}
|
|
166
|
+
const minimalConfig = {
|
|
167
|
+
completedOnboarding: true
|
|
168
|
+
};
|
|
169
|
+
writeClaudeConfig(minimalConfig);
|
|
170
|
+
console.log("");
|
|
171
|
+
console.log(ansis.green(isZh ? "\u2705 \u914D\u7F6E\u5DF2\u91CD\u7F6E" : "\u2705 Configuration reset"));
|
|
172
|
+
console.log(ansis.dim(isZh ? '\u8FD0\u884C "ccjk init" \u91CD\u65B0\u914D\u7F6E' : 'Run "ccjk init" to reconfigure'));
|
|
173
|
+
console.log("");
|
|
174
|
+
} catch (error) {
|
|
175
|
+
console.error(ansis.red(isZh ? "\u274C \u91CD\u7F6E\u914D\u7F6E\u5931\u8D25" : "\u274C Failed to reset configuration"));
|
|
176
|
+
if (error instanceof Error) {
|
|
177
|
+
console.error(ansis.dim(error.message));
|
|
178
|
+
}
|
|
179
|
+
console.log("");
|
|
73
180
|
}
|
|
74
181
|
}
|
|
75
|
-
function
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
use: ["enhancetool"]
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
},
|
|
91
|
-
{
|
|
92
|
-
name: "deepseek",
|
|
93
|
-
provider: "deepseek",
|
|
94
|
-
baseURL: "https://api.deepseek.com/chat/completions",
|
|
95
|
-
requiresApiKey: true,
|
|
96
|
-
models: ["deepseek-chat", "deepseek-reasoner"],
|
|
97
|
-
description: "DeepSeek AI models",
|
|
98
|
-
transformer: {
|
|
99
|
-
"use": ["deepseek"],
|
|
100
|
-
"deepseek-chat": {
|
|
101
|
-
use: ["tooluse"]
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
name: "gemini",
|
|
107
|
-
provider: "gemini",
|
|
108
|
-
baseURL: "https://generativelanguage.googleapis.com/v1beta/models/",
|
|
109
|
-
requiresApiKey: true,
|
|
110
|
-
models: ["gemini-2.5-flash", "gemini-2.5-pro"],
|
|
111
|
-
description: "Google Gemini models",
|
|
112
|
-
transformer: {
|
|
113
|
-
use: ["gemini"]
|
|
182
|
+
async function setProvider(providerId, options = {}) {
|
|
183
|
+
const isZh = i18n.language === "zh-CN";
|
|
184
|
+
const codeType = options.codeType || "claude-code";
|
|
185
|
+
try {
|
|
186
|
+
const providers = await getApiProviderPresets(codeType);
|
|
187
|
+
const provider = providers.find((p) => p.id === providerId);
|
|
188
|
+
if (!provider) {
|
|
189
|
+
console.log(ansis.yellow(isZh ? `\u26A0\uFE0F \u4F9B\u5E94\u5546 "${providerId}" \u4E0D\u5B58\u5728` : `\u26A0\uFE0F Provider "${providerId}" not found`));
|
|
190
|
+
console.log("");
|
|
191
|
+
console.log(ansis.dim(isZh ? "\u53EF\u7528\u7684\u4F9B\u5E94\u5546:" : "Available providers:"));
|
|
192
|
+
for (const p of providers) {
|
|
193
|
+
console.log(` - ${p.id} (${p.name})`);
|
|
114
194
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
195
|
+
console.log("");
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const config = readClaudeConfig();
|
|
199
|
+
if (!config) {
|
|
200
|
+
console.log(ansis.yellow(isZh ? "\u26A0\uFE0F \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728" : "\u26A0\uFE0F Configuration file not found"));
|
|
201
|
+
console.log(ansis.dim(isZh ? '\u8FD0\u884C "ccjk init" \u521D\u59CB\u5316\u914D\u7F6E' : 'Run "ccjk init" to initialize configuration'));
|
|
202
|
+
console.log("");
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
const backupPath = backupExistingConfig();
|
|
206
|
+
if (backupPath) {
|
|
207
|
+
console.log(ansis.dim(isZh ? `\u{1F4E6} \u5DF2\u5907\u4EFD\u914D\u7F6E\u5230: ${backupPath}` : `\u{1F4E6} Configuration backed up to: ${backupPath}`));
|
|
208
|
+
}
|
|
209
|
+
if (codeType === "claude-code" && provider.claudeCode) {
|
|
210
|
+
config.baseUrl = provider.claudeCode.baseUrl;
|
|
211
|
+
if (provider.claudeCode.defaultModels && provider.claudeCode.defaultModels.length > 0) {
|
|
212
|
+
config.model = provider.claudeCode.defaultModels[0];
|
|
213
|
+
if (provider.claudeCode.defaultModels.length > 1) {
|
|
214
|
+
config.fastModel = provider.claudeCode.defaultModels[1];
|
|
130
215
|
}
|
|
131
216
|
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
217
|
+
}
|
|
218
|
+
writeClaudeConfig(config);
|
|
219
|
+
console.log("");
|
|
220
|
+
console.log(ansis.green(isZh ? `\u2705 \u5DF2\u5207\u6362\u5230\u4F9B\u5E94\u5546: ${provider.name}` : `\u2705 Switched to provider: ${provider.name}`));
|
|
221
|
+
console.log("");
|
|
222
|
+
console.log(ansis.bold(isZh ? "\u914D\u7F6E\u8BE6\u60C5:" : "Configuration details:"));
|
|
223
|
+
console.log(` ${ansis.green(isZh ? "\u4F9B\u5E94\u5546" : "Provider")}: ${provider.name}`);
|
|
224
|
+
console.log(` ${ansis.green(isZh ? "\u63A5\u53E3\u5730\u5740" : "Base URL")}: ${config.baseUrl}`);
|
|
225
|
+
if (config.model) {
|
|
226
|
+
console.log(` ${ansis.green(isZh ? "\u4E3B\u6A21\u578B" : "Primary Model")}: ${config.model}`);
|
|
227
|
+
}
|
|
228
|
+
if (config.fastModel) {
|
|
229
|
+
console.log(` ${ansis.green(isZh ? "\u5FEB\u901F\u6A21\u578B" : "Fast Model")}: ${config.fastModel}`);
|
|
230
|
+
}
|
|
231
|
+
console.log("");
|
|
232
|
+
console.log(ansis.dim(isZh ? "\u{1F4A1} \u63D0\u793A: \u8BF7\u786E\u4FDD\u5DF2\u8BBE\u7F6E\u6B63\u786E\u7684 API \u5BC6\u94A5\u6216\u8BA4\u8BC1\u4EE4\u724C" : "\u{1F4A1} Tip: Make sure to set the correct API key or auth token"));
|
|
233
|
+
console.log("");
|
|
234
|
+
} catch (error) {
|
|
235
|
+
console.error(ansis.red(isZh ? "\u274C \u8BBE\u7F6E\u4F9B\u5E94\u5546\u5931\u8D25" : "\u274C Failed to set provider"));
|
|
236
|
+
if (error instanceof Error) {
|
|
237
|
+
console.error(ansis.dim(error.message));
|
|
238
|
+
}
|
|
239
|
+
console.log("");
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
async function configCommand(action, args, options = {}) {
|
|
243
|
+
switch (action) {
|
|
244
|
+
case "get":
|
|
245
|
+
if (args.length === 0) {
|
|
246
|
+
const isZh = i18n.language === "zh-CN";
|
|
247
|
+
console.log(ansis.yellow(isZh ? "\u26A0\uFE0F \u8BF7\u6307\u5B9A\u914D\u7F6E\u9879" : "\u26A0\uFE0F Please specify a configuration key"));
|
|
248
|
+
console.log(ansis.dim(isZh ? "\u7528\u6CD5: ccjk config get <key>" : "Usage: ccjk config get <key>"));
|
|
249
|
+
console.log("");
|
|
250
|
+
return;
|
|
147
251
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
use: [["maxtoken", { max_tokens: 16384 }]]
|
|
252
|
+
await getConfig(args[0], options);
|
|
253
|
+
break;
|
|
254
|
+
case "set":
|
|
255
|
+
if (args.length < 2) {
|
|
256
|
+
const isZh = i18n.language === "zh-CN";
|
|
257
|
+
console.log(ansis.yellow(isZh ? "\u26A0\uFE0F \u8BF7\u6307\u5B9A\u914D\u7F6E\u9879\u548C\u503C" : "\u26A0\uFE0F Please specify key and value"));
|
|
258
|
+
console.log(ansis.dim(isZh ? "\u7528\u6CD5: ccjk config set <key> <value>" : "Usage: ccjk config set <key> <value>"));
|
|
259
|
+
console.log("");
|
|
260
|
+
return;
|
|
158
261
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
262
|
+
await setConfig(args[0], args.slice(1).join(" "), options);
|
|
263
|
+
break;
|
|
264
|
+
case "list":
|
|
265
|
+
case "ls":
|
|
266
|
+
await listConfig(options);
|
|
267
|
+
break;
|
|
268
|
+
case "reset":
|
|
269
|
+
await resetConfig(options);
|
|
270
|
+
break;
|
|
271
|
+
case "provider":
|
|
272
|
+
if (args.length === 0) {
|
|
273
|
+
const isZh = i18n.language === "zh-CN";
|
|
274
|
+
console.log(ansis.yellow(isZh ? "\u26A0\uFE0F \u8BF7\u6307\u5B9A\u4F9B\u5E94\u5546 ID" : "\u26A0\uFE0F Please specify provider ID"));
|
|
275
|
+
console.log(ansis.dim(isZh ? "\u7528\u6CD5: ccjk config provider <id>" : "Usage: ccjk config provider <id>"));
|
|
276
|
+
console.log("");
|
|
277
|
+
return;
|
|
169
278
|
}
|
|
279
|
+
await setProvider(args[0], options);
|
|
280
|
+
break;
|
|
281
|
+
default: {
|
|
282
|
+
const isZh = i18n.language === "zh-CN";
|
|
283
|
+
console.log("");
|
|
284
|
+
console.log(ansis.bold.cyan(isZh ? "\u2699\uFE0F \u914D\u7F6E\u7BA1\u7406\u547D\u4EE4" : "\u2699\uFE0F Configuration Management Commands"));
|
|
285
|
+
console.log("");
|
|
286
|
+
console.log(` ${ansis.green("ccjk config get <key>")} ${isZh ? "\u83B7\u53D6\u914D\u7F6E\u9879" : "Get configuration value"}`);
|
|
287
|
+
console.log(` ${ansis.green("ccjk config set <key> <value>")} ${isZh ? "\u8BBE\u7F6E\u914D\u7F6E\u9879" : "Set configuration value"}`);
|
|
288
|
+
console.log(` ${ansis.green("ccjk config list")} ${isZh ? "\u5217\u51FA\u6240\u6709\u914D\u7F6E" : "List all configuration"}`);
|
|
289
|
+
console.log(` ${ansis.green("ccjk config reset")} ${isZh ? "\u91CD\u7F6E\u914D\u7F6E" : "Reset configuration"}`);
|
|
290
|
+
console.log(` ${ansis.green("ccjk config provider <id>")} ${isZh ? "\u5207\u6362\u4F9B\u5E94\u5546" : "Switch provider"}`);
|
|
291
|
+
console.log("");
|
|
292
|
+
console.log(ansis.bold(isZh ? "\u9009\u9879" : "Options"));
|
|
293
|
+
console.log(` ${ansis.green("--code-type, -T")} <type> ${isZh ? "\u4EE3\u7801\u5DE5\u5177\u7C7B\u578B (claude-code, codex)" : "Code tool type (claude-code, codex)"}`);
|
|
294
|
+
console.log(` ${ansis.green("--json, -j")} ${isZh ? "JSON \u683C\u5F0F\u8F93\u51FA" : "JSON format output"}`);
|
|
295
|
+
console.log("");
|
|
296
|
+
console.log(ansis.bold(isZh ? "\u793A\u4F8B" : "Examples"));
|
|
297
|
+
console.log(` ${ansis.dim("ccjk config get baseUrl")}`);
|
|
298
|
+
console.log(` ${ansis.dim('ccjk config set model "claude-3-5-sonnet-20241022"')}`);
|
|
299
|
+
console.log(` ${ansis.dim("ccjk config provider glm")}`);
|
|
300
|
+
console.log("");
|
|
170
301
|
}
|
|
171
|
-
];
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
const execAsync = promisify(exec);
|
|
175
|
-
const CCR_CONFIG_DIR = join(homedir(), ".claude-code-router");
|
|
176
|
-
const CCR_CONFIG_FILE = join(CCR_CONFIG_DIR, "config.json");
|
|
177
|
-
const CCR_BACKUP_DIR = CCR_CONFIG_DIR;
|
|
178
|
-
function ensureCcrConfigDir() {
|
|
179
|
-
if (!existsSync(CCR_CONFIG_DIR)) {
|
|
180
|
-
mkdirSync(CCR_CONFIG_DIR, { recursive: true });
|
|
181
302
|
}
|
|
182
303
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
}
|
|
189
|
-
const timestamp = `${dayjs().format("YYYY-MM-DDTHH-mm-ss-SSS")}Z`;
|
|
190
|
-
const backupFileName = `config.json.${timestamp}.bak`;
|
|
191
|
-
const backupPath = join(CCR_BACKUP_DIR, backupFileName);
|
|
192
|
-
console.log(ansis.green(`${i18n.t("ccr:backupCcrConfig")}`));
|
|
193
|
-
copyFileSync(CCR_CONFIG_FILE, backupPath);
|
|
194
|
-
console.log(ansis.green(`\u2714 ${i18n.t("ccr:ccrBackupSuccess").replace("{path}", backupPath)}`));
|
|
195
|
-
return backupPath;
|
|
196
|
-
} catch (error) {
|
|
197
|
-
console.error(ansis.red(`${i18n.t("ccr:ccrBackupFailed")}:`), error.message);
|
|
304
|
+
function getClaudeConfigPath() {
|
|
305
|
+
return SETTINGS_FILE;
|
|
306
|
+
}
|
|
307
|
+
function readClaudeConfig() {
|
|
308
|
+
if (!existsSync(SETTINGS_FILE)) {
|
|
198
309
|
return null;
|
|
199
310
|
}
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
311
|
+
try {
|
|
312
|
+
const content = readFileSync(SETTINGS_FILE, "utf-8");
|
|
313
|
+
return JSON.parse(content);
|
|
314
|
+
} catch {
|
|
203
315
|
return null;
|
|
204
316
|
}
|
|
205
|
-
return readJsonConfig(CCR_CONFIG_FILE);
|
|
206
317
|
}
|
|
207
|
-
function
|
|
208
|
-
|
|
209
|
-
writeJsonConfig(CCR_CONFIG_FILE, config);
|
|
318
|
+
function writeClaudeConfig(config) {
|
|
319
|
+
writeFileSync(SETTINGS_FILE, JSON.stringify(config, null, 2), "utf-8");
|
|
210
320
|
}
|
|
211
|
-
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
delete settings.env.ANTHROPIC_AUTH_TOKEN;
|
|
220
|
-
settings.env.ANTHROPIC_BASE_URL = `http://${host}:${port}`;
|
|
221
|
-
settings.env.ANTHROPIC_API_KEY = apiKey;
|
|
222
|
-
writeJsonConfig(SETTINGS_FILE, settings);
|
|
223
|
-
try {
|
|
224
|
-
setPrimaryApiKey();
|
|
225
|
-
} catch (error) {
|
|
226
|
-
ensureI18nInitialized();
|
|
227
|
-
console.error(i18n.t("mcp:primaryApiKeySetFailed"), error);
|
|
321
|
+
function getNestedValue(obj, path) {
|
|
322
|
+
const keys = path.split(".");
|
|
323
|
+
let current = obj;
|
|
324
|
+
for (const key of keys) {
|
|
325
|
+
if (current === null || current === void 0) {
|
|
326
|
+
return void 0;
|
|
327
|
+
}
|
|
328
|
+
current = current[key];
|
|
228
329
|
}
|
|
330
|
+
return current;
|
|
229
331
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
}
|
|
238
|
-
try {
|
|
239
|
-
const choices = [
|
|
240
|
-
{
|
|
241
|
-
name: `1. ${i18n.t("ccr:skipOption")}`,
|
|
242
|
-
value: "skip"
|
|
243
|
-
},
|
|
244
|
-
...presets.map((p, index) => ({
|
|
245
|
-
name: `${index + 2}. ${p.name}`,
|
|
246
|
-
value: p
|
|
247
|
-
}))
|
|
248
|
-
];
|
|
249
|
-
const { preset } = await inquirer.prompt({
|
|
250
|
-
type: "list",
|
|
251
|
-
name: "preset",
|
|
252
|
-
message: i18n.t("ccr:selectCcrPreset"),
|
|
253
|
-
choices
|
|
254
|
-
});
|
|
255
|
-
return preset;
|
|
256
|
-
} catch (error) {
|
|
257
|
-
if (error.name === "ExitPromptError") {
|
|
258
|
-
console.log(ansis.yellow(i18n.t("common:cancelled")));
|
|
259
|
-
return null;
|
|
332
|
+
function setNestedValue(obj, path, value) {
|
|
333
|
+
const keys = path.split(".");
|
|
334
|
+
let current = obj;
|
|
335
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
336
|
+
const key = keys[i];
|
|
337
|
+
if (!(key in current) || typeof current[key] !== "object") {
|
|
338
|
+
current[key] = {};
|
|
260
339
|
}
|
|
261
|
-
|
|
340
|
+
current = current[key];
|
|
262
341
|
}
|
|
342
|
+
current[keys[keys.length - 1]] = value;
|
|
263
343
|
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
provider.api_key = apiKey;
|
|
285
|
-
} catch (error) {
|
|
286
|
-
if (error.name === "ExitPromptError") {
|
|
287
|
-
throw error;
|
|
288
|
-
}
|
|
289
|
-
throw error;
|
|
344
|
+
function displayValue(value, indent) {
|
|
345
|
+
const prefix = " ".repeat(indent);
|
|
346
|
+
if (value === null) {
|
|
347
|
+
console.log(`${prefix}${ansis.dim("null")}`);
|
|
348
|
+
} else if (typeof value === "boolean") {
|
|
349
|
+
console.log(`${prefix}${ansis.green(value.toString())}`);
|
|
350
|
+
} else if (typeof value === "number") {
|
|
351
|
+
console.log(`${prefix}${ansis.yellow(value.toString())}`);
|
|
352
|
+
} else if (typeof value === "string") {
|
|
353
|
+
console.log(`${prefix}${ansis.green(value)}`);
|
|
354
|
+
} else if (Array.isArray(value)) {
|
|
355
|
+
console.log(`${prefix}${ansis.dim("[")}`);
|
|
356
|
+
for (const item of value) {
|
|
357
|
+
displayValue(item, indent + 1);
|
|
358
|
+
}
|
|
359
|
+
console.log(`${prefix}${ansis.dim("]")}`);
|
|
360
|
+
} else if (typeof value === "object") {
|
|
361
|
+
for (const [key, val] of Object.entries(value)) {
|
|
362
|
+
console.log(`${prefix}${ansis.bold(key)}:`);
|
|
363
|
+
displayValue(val, indent + 1);
|
|
290
364
|
}
|
|
291
365
|
} else {
|
|
292
|
-
|
|
366
|
+
console.log(`${prefix}${value}`);
|
|
293
367
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
}))
|
|
305
|
-
});
|
|
306
|
-
defaultModel = model;
|
|
307
|
-
} catch (error) {
|
|
308
|
-
if (error.name === "ExitPromptError") {
|
|
309
|
-
throw error;
|
|
368
|
+
}
|
|
369
|
+
function displayConfigSection(title, data, _isZh) {
|
|
370
|
+
console.log(ansis.bold(title));
|
|
371
|
+
console.log("");
|
|
372
|
+
for (const [key, value] of Object.entries(data)) {
|
|
373
|
+
if (value !== void 0) {
|
|
374
|
+
if (Array.isArray(value)) {
|
|
375
|
+
console.log(` ${ansis.green(key)}: ${value.join(", ")}`);
|
|
376
|
+
} else {
|
|
377
|
+
console.log(` ${ansis.green(key)}: ${value}`);
|
|
310
378
|
}
|
|
311
|
-
throw error;
|
|
312
379
|
}
|
|
313
380
|
}
|
|
314
|
-
|
|
315
|
-
default: `${preset.name},${defaultModel}`,
|
|
316
|
-
// Use the original name
|
|
317
|
-
background: `${preset.name},${defaultModel}`,
|
|
318
|
-
think: `${preset.name},${defaultModel}`,
|
|
319
|
-
longContext: `${preset.name},${defaultModel}`,
|
|
320
|
-
longContextThreshold: 6e4,
|
|
321
|
-
webSearch: `${preset.name},${defaultModel}`
|
|
322
|
-
};
|
|
323
|
-
const config = {
|
|
324
|
-
LOG: true,
|
|
325
|
-
CLAUDE_PATH: "",
|
|
326
|
-
HOST: "127.0.0.1",
|
|
327
|
-
PORT: 3456,
|
|
328
|
-
APIKEY: "sk-ccjk-x-ccr",
|
|
329
|
-
API_TIMEOUT_MS: "600000",
|
|
330
|
-
PROXY_URL: "",
|
|
331
|
-
transformers: [],
|
|
332
|
-
Providers: [provider],
|
|
333
|
-
Router: router
|
|
334
|
-
};
|
|
335
|
-
return config;
|
|
381
|
+
console.log("");
|
|
336
382
|
}
|
|
337
|
-
async function
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
console.log(ansis.
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
383
|
+
async function unsetConfig(key, _options = {}) {
|
|
384
|
+
const isZh = i18n.language === "zh-CN";
|
|
385
|
+
if (!key) {
|
|
386
|
+
console.log(ansis.yellow(isZh ? "\u26A0\uFE0F \u8BF7\u6307\u5B9A\u914D\u7F6E\u9879" : "\u26A0\uFE0F Please specify a configuration key"));
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
const config = readClaudeConfig();
|
|
390
|
+
const keys = key.split(".");
|
|
391
|
+
let current = config;
|
|
392
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
393
|
+
if (current[keys[i]] === void 0) {
|
|
394
|
+
console.log(ansis.yellow(isZh ? `\u26A0\uFE0F \u914D\u7F6E\u9879 "${key}" \u4E0D\u5B58\u5728` : `\u26A0\uFE0F Configuration key "${key}" does not exist`));
|
|
395
|
+
return;
|
|
350
396
|
}
|
|
397
|
+
current = current[keys[i]];
|
|
351
398
|
}
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
\u{1F4CC} ${i18n.t("ccr:configTips")}:`));
|
|
357
|
-
console.log(ansis.green(` \u2022 ${i18n.t("ccr:advancedConfigTip")}`));
|
|
358
|
-
console.log(ansis.green(` \u2022 ${i18n.t("ccr:manualConfigTip")}`));
|
|
359
|
-
console.log(ansis.bold.yellow(` \u2022 ${i18n.t("ccr:useClaudeCommand")}`));
|
|
360
|
-
if (apiKey) {
|
|
361
|
-
console.log(ansis.bold.green(` \u2022 ${i18n.t("ccr:ccrUiApiKey") || "CCR UI API Key"}: ${apiKey}`));
|
|
362
|
-
console.log(ansis.gray(` ${i18n.t("ccr:ccrUiApiKeyHint") || "Use this API key to login to CCR UI"}`));
|
|
399
|
+
const lastKey = keys[keys.length - 1];
|
|
400
|
+
if (current[lastKey] === void 0) {
|
|
401
|
+
console.log(ansis.yellow(isZh ? `\u26A0\uFE0F \u914D\u7F6E\u9879 "${key}" \u4E0D\u5B58\u5728` : `\u26A0\uFE0F Configuration key "${key}" does not exist`));
|
|
402
|
+
return;
|
|
363
403
|
}
|
|
364
|
-
|
|
404
|
+
delete current[lastKey];
|
|
405
|
+
writeClaudeConfig(config);
|
|
406
|
+
console.log(ansis.green(isZh ? `\u2705 \u5DF2\u5220\u9664\u914D\u7F6E\u9879: ${key}` : `\u2705 Removed configuration: ${key}`));
|
|
365
407
|
}
|
|
366
|
-
function
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
Router: {}
|
|
379
|
-
// Empty router configuration - user configures in UI
|
|
380
|
-
};
|
|
408
|
+
async function editConfig(_options = {}) {
|
|
409
|
+
const isZh = i18n.language === "zh-CN";
|
|
410
|
+
const configPath = getClaudeConfigPath();
|
|
411
|
+
const editor = process__default.env.EDITOR || process__default.env.VISUAL || "vi";
|
|
412
|
+
console.log(ansis.green(isZh ? `\u{1F4DD} \u6B63\u5728\u6253\u5F00\u914D\u7F6E\u6587\u4EF6: ${configPath}` : `\u{1F4DD} Opening config file: ${configPath}`));
|
|
413
|
+
const { spawn } = await import('node:child_process');
|
|
414
|
+
const child = spawn(editor, [configPath], { stdio: "inherit" });
|
|
415
|
+
child.on("exit", (code) => {
|
|
416
|
+
if (code === 0) {
|
|
417
|
+
console.log(ansis.green(isZh ? "\u2705 \u914D\u7F6E\u6587\u4EF6\u5DF2\u4FDD\u5B58" : "\u2705 Config file saved"));
|
|
418
|
+
}
|
|
419
|
+
});
|
|
381
420
|
}
|
|
382
|
-
async function
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
const { manageApiKeyApproval } = await import('./claude-config.mjs').then(function (n) { return n.h; });
|
|
406
|
-
const apiKey = existingConfig.APIKEY || "sk-ccjk-x-ccr";
|
|
407
|
-
manageApiKeyApproval(apiKey);
|
|
408
|
-
console.log(ansis.green(`\u2714 ${i18n.t("ccr:apiKeyApprovalSuccess")}`));
|
|
409
|
-
} catch (error) {
|
|
410
|
-
console.error(ansis.red(`${i18n.t("ccr:apiKeyApprovalFailed")}:`), error);
|
|
411
|
-
}
|
|
412
|
-
return true;
|
|
421
|
+
async function validateConfig(_options = {}) {
|
|
422
|
+
const isZh = i18n.language === "zh-CN";
|
|
423
|
+
console.log(ansis.green(isZh ? "\u{1F50D} \u6B63\u5728\u9A8C\u8BC1\u914D\u7F6E..." : "\u{1F50D} Validating configuration..."));
|
|
424
|
+
console.log("");
|
|
425
|
+
const config = readClaudeConfig();
|
|
426
|
+
const errors = [];
|
|
427
|
+
const warnings = [];
|
|
428
|
+
if (!config.apiKey) {
|
|
429
|
+
errors.push(isZh ? "apiKey \u672A\u8BBE\u7F6E" : "apiKey is not set");
|
|
430
|
+
}
|
|
431
|
+
if (!config.baseUrl) {
|
|
432
|
+
warnings.push(isZh ? "baseUrl \u672A\u8BBE\u7F6E\uFF0C\u5C06\u4F7F\u7528\u9ED8\u8BA4\u503C" : "baseUrl is not set, will use default");
|
|
433
|
+
}
|
|
434
|
+
if (config.model && typeof config.model !== "string") {
|
|
435
|
+
errors.push(isZh ? "model \u683C\u5F0F\u65E0\u6548" : "model format is invalid");
|
|
436
|
+
}
|
|
437
|
+
if (errors.length === 0 && warnings.length === 0) {
|
|
438
|
+
console.log(ansis.green(isZh ? "\u2705 \u914D\u7F6E\u9A8C\u8BC1\u901A\u8FC7" : "\u2705 Configuration is valid"));
|
|
439
|
+
} else {
|
|
440
|
+
if (errors.length > 0) {
|
|
441
|
+
console.log(ansis.red(isZh ? "\u274C \u9519\u8BEF:" : "\u274C Errors:"));
|
|
442
|
+
for (const error of errors) {
|
|
443
|
+
console.log(ansis.red(` \u2022 ${error}`));
|
|
413
444
|
}
|
|
414
|
-
|
|
445
|
+
console.log("");
|
|
415
446
|
}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
if (preset === "skip") {
|
|
422
|
-
console.log(ansis.yellow(`${i18n.t("ccr:skipConfiguring")}`));
|
|
423
|
-
config = createDefaultCcrConfig();
|
|
424
|
-
} else {
|
|
425
|
-
config = await configureCcrWithPreset(preset);
|
|
426
|
-
}
|
|
427
|
-
writeCcrConfig(config);
|
|
428
|
-
console.log(ansis.green(`\u2714 ${i18n.t("ccr:ccrConfigSuccess")}`));
|
|
429
|
-
await configureCcrProxy(config);
|
|
430
|
-
console.log(ansis.green(`\u2714 ${i18n.t("ccr:proxyConfigSuccess")}`));
|
|
431
|
-
await restartAndCheckCcrStatus();
|
|
432
|
-
await showConfigurationTips(config.APIKEY);
|
|
433
|
-
try {
|
|
434
|
-
addCompletedOnboarding();
|
|
435
|
-
} catch (error) {
|
|
436
|
-
console.error(ansis.red(i18n.t("errors:failedToSetOnboarding")), error);
|
|
437
|
-
}
|
|
438
|
-
try {
|
|
439
|
-
const { manageApiKeyApproval } = await import('./claude-config.mjs').then(function (n) { return n.h; });
|
|
440
|
-
const apiKey = config.APIKEY || "sk-ccjk-x-ccr";
|
|
441
|
-
manageApiKeyApproval(apiKey);
|
|
442
|
-
console.log(ansis.green(`\u2714 ${i18n.t("ccr:apiKeyApprovalSuccess")}`));
|
|
443
|
-
} catch (error) {
|
|
444
|
-
console.error(ansis.red(`${i18n.t("ccr:apiKeyApprovalFailed")}:`), error);
|
|
445
|
-
}
|
|
446
|
-
return true;
|
|
447
|
-
} catch (error) {
|
|
448
|
-
if (error.name === "ExitPromptError") {
|
|
449
|
-
console.log(ansis.yellow(i18n.t("common:cancelled")));
|
|
450
|
-
return false;
|
|
447
|
+
if (warnings.length > 0) {
|
|
448
|
+
console.log(ansis.yellow(isZh ? "\u26A0\uFE0F \u8B66\u544A:" : "\u26A0\uFE0F Warnings:"));
|
|
449
|
+
for (const warning of warnings) {
|
|
450
|
+
console.log(ansis.yellow(` \u2022 ${warning}`));
|
|
451
|
+
}
|
|
451
452
|
}
|
|
452
|
-
console.error(ansis.red(`${i18n.t("ccr:ccrConfigFailed")}:`), error);
|
|
453
|
-
return false;
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
async function configureCcrFeature() {
|
|
457
|
-
ensureI18nInitialized();
|
|
458
|
-
const backupDir = backupExistingConfig();
|
|
459
|
-
if (backupDir) {
|
|
460
|
-
console.log(ansis.gray(`\u2714 ${i18n.t("configuration:backupSuccess")}: ${backupDir}`));
|
|
461
453
|
}
|
|
462
|
-
await setupCcrConfiguration();
|
|
463
454
|
}
|
|
464
455
|
|
|
465
|
-
export {
|
|
456
|
+
export { configCommand, editConfig, getConfig, listConfig, resetConfig, setConfig, setProvider, unsetConfig, validateConfig };
|