ccjk 2.4.4 → 2.5.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.
Files changed (53) hide show
  1. package/dist/chunks/api-providers.mjs +73 -1
  2. package/dist/chunks/ccjk-config.mjs +13 -77
  3. package/dist/chunks/ccr.mjs +9 -4
  4. package/dist/chunks/check-updates.mjs +4 -2
  5. package/dist/chunks/claude-code-config-manager.mjs +9 -15
  6. package/dist/chunks/claude-code-incremental-manager.mjs +5 -8
  7. package/dist/chunks/codex.mjs +10 -569
  8. package/dist/chunks/config-switch.mjs +7 -5
  9. package/dist/chunks/config.mjs +573 -0
  10. package/dist/chunks/config2.mjs +451 -0
  11. package/dist/chunks/doctor.mjs +89 -1
  12. package/dist/chunks/features.mjs +13 -10
  13. package/dist/chunks/index.mjs +10 -1164
  14. package/dist/chunks/index2.mjs +8 -2
  15. package/dist/chunks/init.mjs +14 -11
  16. package/dist/chunks/json-config.mjs +59 -0
  17. package/dist/chunks/mcp-server.mjs +776 -0
  18. package/dist/chunks/mcp.mjs +10 -8
  19. package/dist/chunks/menu.mjs +5 -5
  20. package/dist/chunks/package.mjs +1 -1
  21. package/dist/chunks/permissions.mjs +420 -0
  22. package/dist/chunks/prompts.mjs +2 -1
  23. package/dist/chunks/providers.mjs +261 -0
  24. package/dist/chunks/session.mjs +484 -41
  25. package/dist/chunks/skills.mjs +553 -0
  26. package/dist/chunks/stats.mjs +411 -0
  27. package/dist/chunks/uninstall.mjs +4 -3
  28. package/dist/chunks/update.mjs +6 -3
  29. package/dist/chunks/workflows2.mjs +140 -0
  30. package/dist/cli.mjs +316 -10
  31. package/dist/i18n/locales/en/hooks.json +47 -0
  32. package/dist/i18n/locales/en/mcp.json +55 -0
  33. package/dist/i18n/locales/en/permissions.json +43 -0
  34. package/dist/i18n/locales/en/sandbox.json +44 -0
  35. package/dist/i18n/locales/en/skills.json +89 -129
  36. package/dist/i18n/locales/en/stats.json +20 -0
  37. package/dist/i18n/locales/zh-CN/hooks.json +47 -0
  38. package/dist/i18n/locales/zh-CN/mcp.json +55 -0
  39. package/dist/i18n/locales/zh-CN/permissions.json +43 -0
  40. package/dist/i18n/locales/zh-CN/sandbox.json +44 -0
  41. package/dist/i18n/locales/zh-CN/skills.json +88 -128
  42. package/dist/i18n/locales/zh-CN/stats.json +20 -0
  43. package/dist/index.mjs +12 -8
  44. package/dist/shared/ccjk.B-lZxV2u.mjs +1162 -0
  45. package/dist/shared/{ccjk.CURU8gbR.mjs → ccjk.CUdzQluX.mjs} +1 -1
  46. package/dist/shared/{ccjk.ByTIGCUC.mjs → ccjk.Dut3wyoP.mjs} +1 -1
  47. package/dist/shared/ccjk.J8YiPsOw.mjs +259 -0
  48. package/dist/shared/{ccjk.CGTmRqsu.mjs → ccjk.rLRHmcqD.mjs} +5 -134
  49. package/dist/shared/{ccjk.QbS8EAOd.mjs → ccjk.uVUeWAt8.mjs} +2 -1
  50. package/package.json +1 -1
  51. package/templates/common/skills/code-review.md +343 -0
  52. package/templates/common/skills/summarize.md +312 -0
  53. package/templates/common/skills/translate.md +202 -0
@@ -0,0 +1,451 @@
1
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import process__default from 'node:process';
3
+ import ansis from 'ansis';
4
+ import inquirer from 'inquirer';
5
+ import { getApiProviderPresets } from './api-providers.mjs';
6
+ import { SETTINGS_FILE } from './constants.mjs';
7
+ import { i18n } from './index2.mjs';
8
+ import { l as backupExistingConfig } from './config.mjs';
9
+ import 'node:os';
10
+ import 'pathe';
11
+ import 'node:url';
12
+ import 'i18next';
13
+ import 'i18next-fs-backend';
14
+ import 'dayjs';
15
+ import './json-config.mjs';
16
+ import './fs-operations.mjs';
17
+ import 'node:crypto';
18
+ import 'node:fs/promises';
19
+ import './platform.mjs';
20
+ import 'tinyexec';
21
+
22
+ async function getConfig(key, options = {}) {
23
+ const isZh = i18n.language === "zh-CN";
24
+ try {
25
+ const config = readClaudeConfig();
26
+ if (!config) {
27
+ console.log(ansis.yellow(isZh ? "\u26A0\uFE0F \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728" : "\u26A0\uFE0F Configuration file not found"));
28
+ console.log(ansis.dim(isZh ? '\u8FD0\u884C "ccjk init" \u521D\u59CB\u5316\u914D\u7F6E' : 'Run "ccjk init" to initialize configuration'));
29
+ console.log("");
30
+ return;
31
+ }
32
+ const value = getNestedValue(config, key);
33
+ if (value === void 0) {
34
+ console.log(ansis.yellow(isZh ? `\u26A0\uFE0F \u914D\u7F6E\u9879 "${key}" \u4E0D\u5B58\u5728` : `\u26A0\uFE0F Configuration key "${key}" not found`));
35
+ console.log("");
36
+ return;
37
+ }
38
+ if (options.json) {
39
+ console.log(JSON.stringify(value, null, 2));
40
+ } else {
41
+ console.log("");
42
+ console.log(ansis.bold.cyan(isZh ? `\u{1F4CB} \u914D\u7F6E\u9879: ${key}` : `\u{1F4CB} Configuration: ${key}`));
43
+ console.log(ansis.dim("\u2500".repeat(60)));
44
+ console.log("");
45
+ displayValue(value, 0);
46
+ console.log("");
47
+ }
48
+ } catch (error) {
49
+ console.error(ansis.red(isZh ? "\u274C \u8BFB\u53D6\u914D\u7F6E\u5931\u8D25" : "\u274C Failed to read configuration"));
50
+ if (error instanceof Error) {
51
+ console.error(ansis.dim(error.message));
52
+ }
53
+ console.log("");
54
+ }
55
+ }
56
+ async function setConfig(key, value, _options = {}) {
57
+ const isZh = i18n.language === "zh-CN";
58
+ try {
59
+ const config = readClaudeConfig();
60
+ if (!config) {
61
+ console.log(ansis.yellow(isZh ? "\u26A0\uFE0F \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728" : "\u26A0\uFE0F Configuration file not found"));
62
+ console.log(ansis.dim(isZh ? '\u8FD0\u884C "ccjk init" \u521D\u59CB\u5316\u914D\u7F6E' : 'Run "ccjk init" to initialize configuration'));
63
+ console.log("");
64
+ return;
65
+ }
66
+ const backupPath = backupExistingConfig();
67
+ if (backupPath) {
68
+ console.log(ansis.dim(isZh ? `\u{1F4E6} \u5DF2\u5907\u4EFD\u914D\u7F6E\u5230: ${backupPath}` : `\u{1F4E6} Configuration backed up to: ${backupPath}`));
69
+ }
70
+ let parsedValue = value;
71
+ try {
72
+ parsedValue = JSON.parse(value);
73
+ } catch {
74
+ }
75
+ setNestedValue(config, key, parsedValue);
76
+ writeClaudeConfig(config);
77
+ console.log("");
78
+ console.log(ansis.green(isZh ? `\u2705 \u914D\u7F6E\u9879 "${key}" \u5DF2\u66F4\u65B0` : `\u2705 Configuration "${key}" updated`));
79
+ console.log("");
80
+ console.log(ansis.bold(isZh ? "\u65B0\u503C:" : "New value:"));
81
+ displayValue(parsedValue, 0);
82
+ console.log("");
83
+ } catch (error) {
84
+ console.error(ansis.red(isZh ? "\u274C \u8BBE\u7F6E\u914D\u7F6E\u5931\u8D25" : "\u274C Failed to set configuration"));
85
+ if (error instanceof Error) {
86
+ console.error(ansis.dim(error.message));
87
+ }
88
+ console.log("");
89
+ }
90
+ }
91
+ async function listConfig(options = {}) {
92
+ const isZh = i18n.language === "zh-CN";
93
+ try {
94
+ const config = readClaudeConfig();
95
+ if (!config) {
96
+ console.log(ansis.yellow(isZh ? "\u26A0\uFE0F \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728" : "\u26A0\uFE0F Configuration file not found"));
97
+ console.log(ansis.dim(isZh ? '\u8FD0\u884C "ccjk init" \u521D\u59CB\u5316\u914D\u7F6E' : 'Run "ccjk init" to initialize configuration'));
98
+ console.log("");
99
+ return;
100
+ }
101
+ if (options.json) {
102
+ console.log(JSON.stringify(config, null, 2));
103
+ return;
104
+ }
105
+ console.log("");
106
+ console.log(ansis.bold.cyan(isZh ? "\u{1F4CB} Claude Code \u914D\u7F6E" : "\u{1F4CB} Claude Code Configuration"));
107
+ console.log(ansis.dim("\u2500".repeat(60)));
108
+ console.log("");
109
+ displayConfigSection(isZh ? "API \u914D\u7F6E" : "API Configuration", {
110
+ baseUrl: config.baseUrl,
111
+ apiKey: config.apiKey ? "***" : void 0,
112
+ authToken: config.authToken ? "***" : void 0,
113
+ model: config.model,
114
+ fastModel: config.fastModel
115
+ }, isZh);
116
+ if (config.mcpServers && Object.keys(config.mcpServers).length > 0) {
117
+ displayConfigSection(isZh ? "MCP \u670D\u52A1" : "MCP Services", {
118
+ count: Object.keys(config.mcpServers).length,
119
+ services: Object.keys(config.mcpServers)
120
+ }, isZh);
121
+ }
122
+ if (config.customInstructions) {
123
+ displayConfigSection(isZh ? "\u81EA\u5B9A\u4E49\u6307\u4EE4" : "Custom Instructions", {
124
+ length: config.customInstructions.length,
125
+ preview: `${config.customInstructions.substring(0, 100)}...`
126
+ }, isZh);
127
+ }
128
+ console.log("");
129
+ console.log(ansis.dim("\u2500".repeat(60)));
130
+ console.log(ansis.dim(isZh ? `\u914D\u7F6E\u6587\u4EF6: ${SETTINGS_FILE}` : `Config file: ${SETTINGS_FILE}`));
131
+ console.log("");
132
+ } catch (error) {
133
+ console.error(ansis.red(isZh ? "\u274C \u8BFB\u53D6\u914D\u7F6E\u5931\u8D25" : "\u274C Failed to read configuration"));
134
+ if (error instanceof Error) {
135
+ console.error(ansis.dim(error.message));
136
+ }
137
+ console.log("");
138
+ }
139
+ }
140
+ async function resetConfig(_options = {}) {
141
+ const isZh = i18n.language === "zh-CN";
142
+ try {
143
+ const config = readClaudeConfig();
144
+ if (!config) {
145
+ console.log(ansis.yellow(isZh ? "\u26A0\uFE0F \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728" : "\u26A0\uFE0F Configuration file not found"));
146
+ console.log("");
147
+ return;
148
+ }
149
+ const { confirm } = await inquirer.prompt({
150
+ type: "confirm",
151
+ name: "confirm",
152
+ 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.",
153
+ default: false
154
+ });
155
+ if (!confirm) {
156
+ console.log(ansis.yellow(isZh ? "\u5DF2\u53D6\u6D88" : "Cancelled"));
157
+ console.log("");
158
+ return;
159
+ }
160
+ const backupPath = backupExistingConfig();
161
+ if (backupPath) {
162
+ console.log(ansis.dim(isZh ? `\u{1F4E6} \u5DF2\u5907\u4EFD\u914D\u7F6E\u5230: ${backupPath}` : `\u{1F4E6} Configuration backed up to: ${backupPath}`));
163
+ }
164
+ const minimalConfig = {
165
+ completedOnboarding: true
166
+ };
167
+ writeClaudeConfig(minimalConfig);
168
+ console.log("");
169
+ console.log(ansis.green(isZh ? "\u2705 \u914D\u7F6E\u5DF2\u91CD\u7F6E" : "\u2705 Configuration reset"));
170
+ console.log(ansis.dim(isZh ? '\u8FD0\u884C "ccjk init" \u91CD\u65B0\u914D\u7F6E' : 'Run "ccjk init" to reconfigure'));
171
+ console.log("");
172
+ } catch (error) {
173
+ console.error(ansis.red(isZh ? "\u274C \u91CD\u7F6E\u914D\u7F6E\u5931\u8D25" : "\u274C Failed to reset configuration"));
174
+ if (error instanceof Error) {
175
+ console.error(ansis.dim(error.message));
176
+ }
177
+ console.log("");
178
+ }
179
+ }
180
+ async function setProvider(providerId, options = {}) {
181
+ const isZh = i18n.language === "zh-CN";
182
+ const codeType = options.codeType || "claude-code";
183
+ try {
184
+ const providers = await getApiProviderPresets(codeType);
185
+ const provider = providers.find((p) => p.id === providerId);
186
+ if (!provider) {
187
+ console.log(ansis.yellow(isZh ? `\u26A0\uFE0F \u4F9B\u5E94\u5546 "${providerId}" \u4E0D\u5B58\u5728` : `\u26A0\uFE0F Provider "${providerId}" not found`));
188
+ console.log("");
189
+ console.log(ansis.dim(isZh ? "\u53EF\u7528\u7684\u4F9B\u5E94\u5546:" : "Available providers:"));
190
+ for (const p of providers) {
191
+ console.log(` - ${p.id} (${p.name})`);
192
+ }
193
+ console.log("");
194
+ return;
195
+ }
196
+ const config = readClaudeConfig();
197
+ if (!config) {
198
+ console.log(ansis.yellow(isZh ? "\u26A0\uFE0F \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728" : "\u26A0\uFE0F Configuration file not found"));
199
+ console.log(ansis.dim(isZh ? '\u8FD0\u884C "ccjk init" \u521D\u59CB\u5316\u914D\u7F6E' : 'Run "ccjk init" to initialize configuration'));
200
+ console.log("");
201
+ return;
202
+ }
203
+ const backupPath = backupExistingConfig();
204
+ if (backupPath) {
205
+ console.log(ansis.dim(isZh ? `\u{1F4E6} \u5DF2\u5907\u4EFD\u914D\u7F6E\u5230: ${backupPath}` : `\u{1F4E6} Configuration backed up to: ${backupPath}`));
206
+ }
207
+ if (codeType === "claude-code" && provider.claudeCode) {
208
+ config.baseUrl = provider.claudeCode.baseUrl;
209
+ if (provider.claudeCode.defaultModels && provider.claudeCode.defaultModels.length > 0) {
210
+ config.model = provider.claudeCode.defaultModels[0];
211
+ if (provider.claudeCode.defaultModels.length > 1) {
212
+ config.fastModel = provider.claudeCode.defaultModels[1];
213
+ }
214
+ }
215
+ }
216
+ writeClaudeConfig(config);
217
+ console.log("");
218
+ console.log(ansis.green(isZh ? `\u2705 \u5DF2\u5207\u6362\u5230\u4F9B\u5E94\u5546: ${provider.name}` : `\u2705 Switched to provider: ${provider.name}`));
219
+ console.log("");
220
+ console.log(ansis.bold(isZh ? "\u914D\u7F6E\u8BE6\u60C5:" : "Configuration details:"));
221
+ console.log(` ${ansis.cyan(isZh ? "\u4F9B\u5E94\u5546" : "Provider")}: ${provider.name}`);
222
+ console.log(` ${ansis.cyan(isZh ? "\u63A5\u53E3\u5730\u5740" : "Base URL")}: ${config.baseUrl}`);
223
+ if (config.model) {
224
+ console.log(` ${ansis.cyan(isZh ? "\u4E3B\u6A21\u578B" : "Primary Model")}: ${config.model}`);
225
+ }
226
+ if (config.fastModel) {
227
+ console.log(` ${ansis.cyan(isZh ? "\u5FEB\u901F\u6A21\u578B" : "Fast Model")}: ${config.fastModel}`);
228
+ }
229
+ console.log("");
230
+ 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"));
231
+ console.log("");
232
+ } catch (error) {
233
+ console.error(ansis.red(isZh ? "\u274C \u8BBE\u7F6E\u4F9B\u5E94\u5546\u5931\u8D25" : "\u274C Failed to set provider"));
234
+ if (error instanceof Error) {
235
+ console.error(ansis.dim(error.message));
236
+ }
237
+ console.log("");
238
+ }
239
+ }
240
+ async function configCommand(action, args, options = {}) {
241
+ switch (action) {
242
+ case "get":
243
+ if (args.length === 0) {
244
+ const isZh = i18n.language === "zh-CN";
245
+ console.log(ansis.yellow(isZh ? "\u26A0\uFE0F \u8BF7\u6307\u5B9A\u914D\u7F6E\u9879" : "\u26A0\uFE0F Please specify a configuration key"));
246
+ console.log(ansis.dim(isZh ? "\u7528\u6CD5: ccjk config get <key>" : "Usage: ccjk config get <key>"));
247
+ console.log("");
248
+ return;
249
+ }
250
+ await getConfig(args[0], options);
251
+ break;
252
+ case "set":
253
+ if (args.length < 2) {
254
+ const isZh = i18n.language === "zh-CN";
255
+ console.log(ansis.yellow(isZh ? "\u26A0\uFE0F \u8BF7\u6307\u5B9A\u914D\u7F6E\u9879\u548C\u503C" : "\u26A0\uFE0F Please specify key and value"));
256
+ console.log(ansis.dim(isZh ? "\u7528\u6CD5: ccjk config set <key> <value>" : "Usage: ccjk config set <key> <value>"));
257
+ console.log("");
258
+ return;
259
+ }
260
+ await setConfig(args[0], args.slice(1).join(" "), options);
261
+ break;
262
+ case "list":
263
+ case "ls":
264
+ await listConfig(options);
265
+ break;
266
+ case "reset":
267
+ await resetConfig(options);
268
+ break;
269
+ case "provider":
270
+ if (args.length === 0) {
271
+ const isZh = i18n.language === "zh-CN";
272
+ console.log(ansis.yellow(isZh ? "\u26A0\uFE0F \u8BF7\u6307\u5B9A\u4F9B\u5E94\u5546 ID" : "\u26A0\uFE0F Please specify provider ID"));
273
+ console.log(ansis.dim(isZh ? "\u7528\u6CD5: ccjk config provider <id>" : "Usage: ccjk config provider <id>"));
274
+ console.log("");
275
+ return;
276
+ }
277
+ await setProvider(args[0], options);
278
+ break;
279
+ default: {
280
+ const isZh = i18n.language === "zh-CN";
281
+ console.log("");
282
+ console.log(ansis.bold.cyan(isZh ? "\u2699\uFE0F \u914D\u7F6E\u7BA1\u7406\u547D\u4EE4" : "\u2699\uFE0F Configuration Management Commands"));
283
+ console.log("");
284
+ console.log(` ${ansis.cyan("ccjk config get <key>")} ${isZh ? "\u83B7\u53D6\u914D\u7F6E\u9879" : "Get configuration value"}`);
285
+ console.log(` ${ansis.cyan("ccjk config set <key> <value>")} ${isZh ? "\u8BBE\u7F6E\u914D\u7F6E\u9879" : "Set configuration value"}`);
286
+ console.log(` ${ansis.cyan("ccjk config list")} ${isZh ? "\u5217\u51FA\u6240\u6709\u914D\u7F6E" : "List all configuration"}`);
287
+ console.log(` ${ansis.cyan("ccjk config reset")} ${isZh ? "\u91CD\u7F6E\u914D\u7F6E" : "Reset configuration"}`);
288
+ console.log(` ${ansis.cyan("ccjk config provider <id>")} ${isZh ? "\u5207\u6362\u4F9B\u5E94\u5546" : "Switch provider"}`);
289
+ console.log("");
290
+ console.log(ansis.bold(isZh ? "\u9009\u9879" : "Options"));
291
+ console.log(` ${ansis.green("--code-type, -T")} <type> ${isZh ? "\u4EE3\u7801\u5DE5\u5177\u7C7B\u578B (claude-code, codex)" : "Code tool type (claude-code, codex)"}`);
292
+ console.log(` ${ansis.green("--json, -j")} ${isZh ? "JSON \u683C\u5F0F\u8F93\u51FA" : "JSON format output"}`);
293
+ console.log("");
294
+ console.log(ansis.bold(isZh ? "\u793A\u4F8B" : "Examples"));
295
+ console.log(` ${ansis.dim("ccjk config get baseUrl")}`);
296
+ console.log(` ${ansis.dim('ccjk config set model "claude-3-5-sonnet-20241022"')}`);
297
+ console.log(` ${ansis.dim("ccjk config provider glm")}`);
298
+ console.log("");
299
+ }
300
+ }
301
+ }
302
+ function readClaudeConfig() {
303
+ if (!existsSync(SETTINGS_FILE)) {
304
+ return null;
305
+ }
306
+ try {
307
+ const content = readFileSync(SETTINGS_FILE, "utf-8");
308
+ return JSON.parse(content);
309
+ } catch {
310
+ return null;
311
+ }
312
+ }
313
+ function writeClaudeConfig(config) {
314
+ writeFileSync(SETTINGS_FILE, JSON.stringify(config, null, 2), "utf-8");
315
+ }
316
+ function getNestedValue(obj, path) {
317
+ const keys = path.split(".");
318
+ let current = obj;
319
+ for (const key of keys) {
320
+ if (current === null || current === void 0) {
321
+ return void 0;
322
+ }
323
+ current = current[key];
324
+ }
325
+ return current;
326
+ }
327
+ function setNestedValue(obj, path, value) {
328
+ const keys = path.split(".");
329
+ let current = obj;
330
+ for (let i = 0; i < keys.length - 1; i++) {
331
+ const key = keys[i];
332
+ if (!(key in current) || typeof current[key] !== "object") {
333
+ current[key] = {};
334
+ }
335
+ current = current[key];
336
+ }
337
+ current[keys[keys.length - 1]] = value;
338
+ }
339
+ function displayValue(value, indent) {
340
+ const prefix = " ".repeat(indent);
341
+ if (value === null) {
342
+ console.log(`${prefix}${ansis.dim("null")}`);
343
+ } else if (typeof value === "boolean") {
344
+ console.log(`${prefix}${ansis.cyan(value.toString())}`);
345
+ } else if (typeof value === "number") {
346
+ console.log(`${prefix}${ansis.yellow(value.toString())}`);
347
+ } else if (typeof value === "string") {
348
+ console.log(`${prefix}${ansis.green(value)}`);
349
+ } else if (Array.isArray(value)) {
350
+ console.log(`${prefix}${ansis.dim("[")}`);
351
+ for (const item of value) {
352
+ displayValue(item, indent + 1);
353
+ }
354
+ console.log(`${prefix}${ansis.dim("]")}`);
355
+ } else if (typeof value === "object") {
356
+ for (const [key, val] of Object.entries(value)) {
357
+ console.log(`${prefix}${ansis.bold(key)}:`);
358
+ displayValue(val, indent + 1);
359
+ }
360
+ } else {
361
+ console.log(`${prefix}${value}`);
362
+ }
363
+ }
364
+ function displayConfigSection(title, data, _isZh) {
365
+ console.log(ansis.bold(title));
366
+ console.log("");
367
+ for (const [key, value] of Object.entries(data)) {
368
+ if (value !== void 0) {
369
+ if (Array.isArray(value)) {
370
+ console.log(` ${ansis.cyan(key)}: ${value.join(", ")}`);
371
+ } else {
372
+ console.log(` ${ansis.cyan(key)}: ${value}`);
373
+ }
374
+ }
375
+ }
376
+ console.log("");
377
+ }
378
+ async function unsetConfig(key, _options = {}) {
379
+ const isZh = i18n.language === "zh-CN";
380
+ if (!key) {
381
+ console.log(ansis.yellow(isZh ? "\u26A0\uFE0F \u8BF7\u6307\u5B9A\u914D\u7F6E\u9879" : "\u26A0\uFE0F Please specify a configuration key"));
382
+ return;
383
+ }
384
+ const config = readClaudeConfig();
385
+ const keys = key.split(".");
386
+ let current = config;
387
+ for (let i = 0; i < keys.length - 1; i++) {
388
+ if (current[keys[i]] === void 0) {
389
+ console.log(ansis.yellow(isZh ? `\u26A0\uFE0F \u914D\u7F6E\u9879 "${key}" \u4E0D\u5B58\u5728` : `\u26A0\uFE0F Configuration key "${key}" does not exist`));
390
+ return;
391
+ }
392
+ current = current[keys[i]];
393
+ }
394
+ const lastKey = keys[keys.length - 1];
395
+ if (current[lastKey] === void 0) {
396
+ console.log(ansis.yellow(isZh ? `\u26A0\uFE0F \u914D\u7F6E\u9879 "${key}" \u4E0D\u5B58\u5728` : `\u26A0\uFE0F Configuration key "${key}" does not exist`));
397
+ return;
398
+ }
399
+ delete current[lastKey];
400
+ writeClaudeConfig(config);
401
+ console.log(ansis.green(isZh ? `\u2705 \u5DF2\u5220\u9664\u914D\u7F6E\u9879: ${key}` : `\u2705 Removed configuration: ${key}`));
402
+ }
403
+ async function editConfig(_options = {}) {
404
+ const isZh = i18n.language === "zh-CN";
405
+ const configPath = getClaudeConfigPath();
406
+ const editor = process__default.env.EDITOR || process__default.env.VISUAL || "vi";
407
+ console.log(ansis.cyan(isZh ? `\u{1F4DD} \u6B63\u5728\u6253\u5F00\u914D\u7F6E\u6587\u4EF6: ${configPath}` : `\u{1F4DD} Opening config file: ${configPath}`));
408
+ const { spawn } = await import('node:child_process');
409
+ const child = spawn(editor, [configPath], { stdio: "inherit" });
410
+ child.on("exit", (code) => {
411
+ if (code === 0) {
412
+ console.log(ansis.green(isZh ? "\u2705 \u914D\u7F6E\u6587\u4EF6\u5DF2\u4FDD\u5B58" : "\u2705 Config file saved"));
413
+ }
414
+ });
415
+ }
416
+ async function validateConfig(_options = {}) {
417
+ const isZh = i18n.language === "zh-CN";
418
+ console.log(ansis.cyan(isZh ? "\u{1F50D} \u6B63\u5728\u9A8C\u8BC1\u914D\u7F6E..." : "\u{1F50D} Validating configuration..."));
419
+ console.log("");
420
+ const config = readClaudeConfig();
421
+ const errors = [];
422
+ const warnings = [];
423
+ if (!config.apiKey) {
424
+ errors.push(isZh ? "apiKey \u672A\u8BBE\u7F6E" : "apiKey is not set");
425
+ }
426
+ if (!config.baseUrl) {
427
+ warnings.push(isZh ? "baseUrl \u672A\u8BBE\u7F6E\uFF0C\u5C06\u4F7F\u7528\u9ED8\u8BA4\u503C" : "baseUrl is not set, will use default");
428
+ }
429
+ if (config.model && typeof config.model !== "string") {
430
+ errors.push(isZh ? "model \u683C\u5F0F\u65E0\u6548" : "model format is invalid");
431
+ }
432
+ if (errors.length === 0 && warnings.length === 0) {
433
+ console.log(ansis.green(isZh ? "\u2705 \u914D\u7F6E\u9A8C\u8BC1\u901A\u8FC7" : "\u2705 Configuration is valid"));
434
+ } else {
435
+ if (errors.length > 0) {
436
+ console.log(ansis.red(isZh ? "\u274C \u9519\u8BEF:" : "\u274C Errors:"));
437
+ for (const error of errors) {
438
+ console.log(ansis.red(` \u2022 ${error}`));
439
+ }
440
+ console.log("");
441
+ }
442
+ if (warnings.length > 0) {
443
+ console.log(ansis.yellow(isZh ? "\u26A0\uFE0F \u8B66\u544A:" : "\u26A0\uFE0F Warnings:"));
444
+ for (const warning of warnings) {
445
+ console.log(ansis.yellow(` \u2022 ${warning}`));
446
+ }
447
+ }
448
+ }
449
+ }
450
+
451
+ export { configCommand, editConfig, getConfig, listConfig, resetConfig, setConfig, setProvider, unsetConfig, validateConfig };
@@ -3,9 +3,11 @@ import process__default from 'node:process';
3
3
  import ansis from 'ansis';
4
4
  import inquirer from 'inquirer';
5
5
  import { resolve, join, dirname } from 'pathe';
6
+ import { getApiProviderPresets } from './api-providers.mjs';
6
7
  import { SETTINGS_FILE, CLAUDE_DIR } from './constants.mjs';
7
8
  import { i18n } from './index2.mjs';
8
9
  import { commandExists } from './platform.mjs';
10
+ import { P as ProviderHealthMonitor } from '../shared/ccjk.J8YiPsOw.mjs';
9
11
  import { platform, userInfo, homedir } from 'node:os';
10
12
  import ora from 'ora';
11
13
  import { exec } from 'tinyexec';
@@ -648,7 +650,70 @@ async function checkOutputStyles() {
648
650
  fix: "Run: npx ccjk init"
649
651
  };
650
652
  }
651
- async function doctor() {
653
+ async function checkProviders(codeType = "claude-code") {
654
+ try {
655
+ const providers = await getApiProviderPresets(codeType);
656
+ if (providers.length === 0) {
657
+ return {
658
+ name: "API Providers",
659
+ status: "warning",
660
+ message: "No providers available"
661
+ };
662
+ }
663
+ const monitor = new ProviderHealthMonitor({
664
+ timeout: 3e3,
665
+ degradedLatencyThreshold: 1e3,
666
+ unhealthyLatencyThreshold: 3e3
667
+ });
668
+ monitor.setProviders(providers);
669
+ const results = await Promise.race([
670
+ Promise.all(
671
+ providers.map(async (provider) => {
672
+ const result = await monitor.checkHealth(provider);
673
+ return { provider, result };
674
+ })
675
+ ),
676
+ new Promise((resolve2) => {
677
+ setTimeout(() => resolve2(null), 5e3);
678
+ })
679
+ ]);
680
+ if (!results) {
681
+ return {
682
+ name: "API Providers",
683
+ status: "warning",
684
+ message: "Health check timeout"
685
+ };
686
+ }
687
+ const healthyCount = results.filter((r) => r.result.success).length;
688
+ if (healthyCount === 0) {
689
+ return {
690
+ name: "API Providers",
691
+ status: "error",
692
+ message: "All providers unavailable",
693
+ fix: "Check your network connection"
694
+ };
695
+ }
696
+ if (healthyCount < providers.length) {
697
+ return {
698
+ name: "API Providers",
699
+ status: "warning",
700
+ message: `${healthyCount}/${providers.length} providers healthy`
701
+ };
702
+ }
703
+ return {
704
+ name: "API Providers",
705
+ status: "ok",
706
+ message: `${healthyCount} providers healthy`
707
+ };
708
+ } catch {
709
+ return {
710
+ name: "API Providers",
711
+ status: "warning",
712
+ message: "Health check failed"
713
+ };
714
+ }
715
+ }
716
+ async function doctor(options = {}) {
652
717
  const isZh = i18n.language === "zh-CN";
653
718
  console.log("");
654
719
  console.log(ansis.bold.cyan("\u{1F50D} CCJK Health Check"));
@@ -663,6 +728,9 @@ async function doctor() {
663
728
  checkCcr,
664
729
  checkOutputStyles
665
730
  ];
731
+ if (options.checkProviders) {
732
+ checks.push(() => checkProviders(options.codeType));
733
+ }
666
734
  let hasErrors = false;
667
735
  let hasWarnings = false;
668
736
  for (const check of checks) {
@@ -688,6 +756,26 @@ async function doctor() {
688
756
  console.log(ansis.green("\u2705 All checks passed - CCJK is properly configured!"));
689
757
  }
690
758
  console.log("");
759
+ if (!options.checkProviders) {
760
+ const { checkProvidersNow } = await inquirer.prompt({
761
+ type: "confirm",
762
+ name: "checkProvidersNow",
763
+ message: isZh ? "\u662F\u5426\u68C0\u67E5 API \u4F9B\u5E94\u5546\u5065\u5EB7\u72B6\u6001\uFF1F" : "Check API provider health status?",
764
+ default: false
765
+ });
766
+ if (checkProvidersNow) {
767
+ console.log("");
768
+ console.log(ansis.dim(isZh ? "\u6B63\u5728\u68C0\u67E5\u4F9B\u5E94\u5546..." : "Checking providers..."));
769
+ const providerResult = await checkProviders(options.codeType);
770
+ const statusIcon = providerResult.status === "ok" ? ansis.green("\u2705") : providerResult.status === "warning" ? ansis.yellow("\u26A0\uFE0F") : ansis.red("\u274C");
771
+ const statusColor = providerResult.status === "ok" ? ansis.green : providerResult.status === "warning" ? ansis.yellow : ansis.red;
772
+ console.log(`${statusIcon} ${ansis.bold(providerResult.name)}: ${statusColor(providerResult.message)}`);
773
+ if (providerResult.fix) {
774
+ console.log(ansis.dim(` \u{1F4A1} Fix: ${providerResult.fix}`));
775
+ }
776
+ console.log("");
777
+ }
778
+ }
691
779
  const { runWorkspace } = await inquirer.prompt({
692
780
  type: "confirm",
693
781
  name: "runWorkspace",
@@ -1,14 +1,15 @@
1
1
  import ansis from 'ansis';
2
2
  import inquirer from 'inquirer';
3
- import { a8 as applyAiLanguageDirective, a6 as getExistingModelConfig, a3 as updateCustomModel, a4 as updateDefaultModel, e as readMcpConfig, k as fixWindowsMcpConfig, f as writeMcpConfig, ac as selectMcpServices, h as backupMcpConfig, ad as getMcpServices, j as buildMcpServerConfig, i as mergeMcpServers, a7 as getExistingApiConfig, aa as promptApiConfigurationAction, a1 as configureApi, a9 as switchToOfficialLogin } from './codex.mjs';
3
+ import { N as selectMcpServices, O as getMcpServices } from './codex.mjs';
4
4
  import { SUPPORTED_LANGS, LANG_LABELS } from './constants.mjs';
5
5
  import { ensureI18nInitialized, i18n, changeLanguage } from './index2.mjs';
6
- import { u as updateZcfConfig, a as readZcfConfig } from './ccjk-config.mjs';
6
+ import { updateZcfConfig, readZcfConfig } from './ccjk-config.mjs';
7
7
  import { q as isCcrInstalled, t as installCcr, E as setupCcrConfiguration } from './init.mjs';
8
- import { a as configureOutputStyle, m as modifyApiConfigPartially, v as validateApiKey, f as formatApiKeyDisplay } from '../shared/ccjk.CGTmRqsu.mjs';
8
+ import { y as applyAiLanguageDirective, v as getExistingModelConfig, u as updateCustomModel, q as updateDefaultModel, r as readMcpConfig, f as fixWindowsMcpConfig, w as writeMcpConfig, b as backupMcpConfig, d as buildMcpServerConfig, a as mergeMcpServers, x as getExistingApiConfig, A as promptApiConfigurationAction, o as configureApi, z as switchToOfficialLogin } from './config.mjs';
9
+ import { a as configureOutputStyle, m as modifyApiConfigPartially, v as validateApiKey, f as formatApiKeyDisplay } from '../shared/ccjk.rLRHmcqD.mjs';
9
10
  import { isWindows } from './platform.mjs';
10
11
  import { a as addNumbersToChoices, p as promptBoolean } from '../shared/ccjk.DhBeLRzf.mjs';
11
- import { o as openSettingsJson, a as importRecommendedPermissions, i as importRecommendedEnv } from '../shared/ccjk.ByTIGCUC.mjs';
12
+ import { o as openSettingsJson, a as importRecommendedPermissions, i as importRecommendedEnv } from '../shared/ccjk.Dut3wyoP.mjs';
12
13
  import 'node:process';
13
14
  import 'node:url';
14
15
  import 'dayjs';
@@ -21,6 +22,7 @@ import './fs-operations.mjs';
21
22
  import 'node:crypto';
22
23
  import 'node:fs';
23
24
  import 'node:fs/promises';
25
+ import './json-config.mjs';
24
26
  import './prompts.mjs';
25
27
  import './package.mjs';
26
28
  import 'node:os';
@@ -28,12 +30,13 @@ import 'i18next';
28
30
  import 'i18next-fs-backend';
29
31
  import 'inquirer-toggle';
30
32
  import 'node:child_process';
33
+ import './workflows2.mjs';
31
34
  import '../shared/ccjk.BhKlRJ0h.mjs';
32
35
  import 'node:util';
33
36
  import './auto-updater.mjs';
34
37
  import './version-checker.mjs';
35
38
  import 'node:path';
36
- import '../shared/ccjk.CURU8gbR.mjs';
39
+ import '../shared/ccjk.CUdzQluX.mjs';
37
40
  import '../shared/ccjk.tB4-Y4Qb.mjs';
38
41
 
39
42
  async function handleCancellation() {
@@ -402,7 +405,7 @@ async function changeScriptLanguageFeature(currentLang) {
402
405
  }
403
406
  async function configureCodexDefaultModelFeature() {
404
407
  ensureI18nInitialized();
405
- const { readCodexConfig } = await import('./codex.mjs').then(function (n) { return n.ai; });
408
+ const { readCodexConfig } = await import('./codex.mjs').then(function (n) { return n.Q; });
406
409
  const existingConfig = readCodexConfig();
407
410
  const currentModel = existingConfig?.model;
408
411
  if (currentModel) {
@@ -511,14 +514,14 @@ ${ansis.blue(`\u2139 ${i18n.t("configuration:existingLanguageConfig") || "Existi
511
514
  } else if (option === "systemPrompt") {
512
515
  const zcfConfig = readZcfConfig();
513
516
  const currentLang = zcfConfig?.aiOutputLang || "English";
514
- const { runCodexSystemPromptSelection } = await import('./codex.mjs').then(function (n) { return n.ai; });
517
+ const { runCodexSystemPromptSelection } = await import('./codex.mjs').then(function (n) { return n.Q; });
515
518
  await runCodexSystemPromptSelection();
516
519
  await ensureLanguageDirectiveInAgents(currentLang);
517
520
  console.log(ansis.green(`\u2714 ${i18n.t("configuration:systemPromptConfigured")}`));
518
521
  }
519
522
  }
520
523
  async function updateCodexModelProvider(modelProvider) {
521
- const { readCodexConfig, writeCodexConfig, backupCodexConfig, getBackupMessage } = await import('./codex.mjs').then(function (n) { return n.ai; });
524
+ const { readCodexConfig, writeCodexConfig, backupCodexConfig, getBackupMessage } = await import('./codex.mjs').then(function (n) { return n.Q; });
522
525
  const backupPath = backupCodexConfig();
523
526
  if (backupPath) {
524
527
  console.log(ansis.gray(getBackupMessage(backupPath)));
@@ -557,7 +560,7 @@ async function ensureLanguageDirectiveInAgents(aiOutputLang) {
557
560
  const langLabel = languageLabels[aiOutputLang] || aiOutputLang;
558
561
  const hasLanguageDirective = /\*\*Most Important:\s*Always respond in [^*]+\*\*/i.test(content);
559
562
  if (!hasLanguageDirective) {
560
- const { backupCodexAgents, getBackupMessage } = await import('./codex.mjs').then(function (n) { return n.ai; });
563
+ const { backupCodexAgents, getBackupMessage } = await import('./codex.mjs').then(function (n) { return n.Q; });
561
564
  const backupPath = backupCodexAgents();
562
565
  if (backupPath) {
563
566
  console.log(ansis.gray(getBackupMessage(backupPath)));
@@ -575,7 +578,7 @@ async function ensureLanguageDirectiveInAgents(aiOutputLang) {
575
578
  }
576
579
  async function updateCodexLanguageDirective(aiOutputLang) {
577
580
  const { readFile, writeFileAtomic, exists } = await import('./fs-operations.mjs');
578
- const { backupCodexAgents, getBackupMessage } = await import('./codex.mjs').then(function (n) { return n.ai; });
581
+ const { backupCodexAgents, getBackupMessage } = await import('./codex.mjs').then(function (n) { return n.Q; });
579
582
  const { homedir } = await import('node:os');
580
583
  const { join } = await import('pathe');
581
584
  const CODEX_AGENTS_FILE = join(homedir(), ".codex", "AGENTS.md");