ccjk 9.5.6 → 9.7.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 (103) hide show
  1. package/dist/chunks/agent.mjs +1 -1
  2. package/dist/chunks/api-providers.mjs +1 -1
  3. package/dist/chunks/api.mjs +3 -3
  4. package/dist/chunks/auto-bootstrap.mjs +1 -1
  5. package/dist/chunks/auto-updater.mjs +1 -1
  6. package/dist/chunks/boost.mjs +160 -0
  7. package/dist/chunks/ccjk-agents.mjs +1 -1
  8. package/dist/chunks/ccjk-all.mjs +1 -1
  9. package/dist/chunks/ccjk-config.mjs +1 -1
  10. package/dist/chunks/ccjk-hooks.mjs +1 -1
  11. package/dist/chunks/ccjk-mcp.mjs +2 -2
  12. package/dist/chunks/ccjk-setup.mjs +1 -1
  13. package/dist/chunks/ccjk-skills.mjs +1 -1
  14. package/dist/chunks/ccr.mjs +25 -30
  15. package/dist/chunks/ccu.mjs +1 -1
  16. package/dist/chunks/check-updates.mjs +3 -4
  17. package/dist/chunks/claude-code-config-manager.mjs +7 -7
  18. package/dist/chunks/claude-code-incremental-manager.mjs +2 -2
  19. package/dist/chunks/claude-config.mjs +4 -4
  20. package/dist/chunks/claude-wrapper.mjs +2 -2
  21. package/dist/chunks/codex-config-switch.mjs +4 -5
  22. package/dist/chunks/codex-provider-manager.mjs +2 -3
  23. package/dist/chunks/codex-uninstaller.mjs +2 -2
  24. package/dist/chunks/codex.mjs +207 -6
  25. package/dist/chunks/commands.mjs +391 -88
  26. package/dist/chunks/commands2.mjs +88 -391
  27. package/dist/chunks/completion.mjs +1 -1
  28. package/dist/chunks/config-consolidator.mjs +2 -2
  29. package/dist/chunks/config-switch.mjs +3 -4
  30. package/dist/chunks/config.mjs +78 -7
  31. package/dist/chunks/config2.mjs +400 -410
  32. package/dist/chunks/config3.mjs +410 -400
  33. package/dist/chunks/constants.mjs +1 -1
  34. package/dist/chunks/doctor.mjs +4 -4
  35. package/dist/chunks/features.mjs +24 -17
  36. package/dist/chunks/index.mjs +178 -7
  37. package/dist/chunks/index2.mjs +1162 -169
  38. package/dist/chunks/index3.mjs +910 -1076
  39. package/dist/chunks/index4.mjs +137 -947
  40. package/dist/chunks/index5.mjs +635 -167
  41. package/dist/chunks/init.mjs +141 -99
  42. package/dist/chunks/installer.mjs +147 -649
  43. package/dist/chunks/installer2.mjs +649 -147
  44. package/dist/chunks/interview.mjs +2 -2
  45. package/dist/chunks/marketplace.mjs +1 -1
  46. package/dist/chunks/mcp.mjs +1058 -17
  47. package/dist/chunks/menu.mjs +147 -56
  48. package/dist/chunks/monitor.mjs +2 -2
  49. package/dist/chunks/notification.mjs +1 -1
  50. package/dist/chunks/onboarding.mjs +2 -2
  51. package/dist/chunks/package.mjs +2 -210
  52. package/dist/chunks/permission-manager.mjs +2 -2
  53. package/dist/chunks/permissions.mjs +1 -1
  54. package/dist/chunks/platform.mjs +1 -1
  55. package/dist/chunks/plugin.mjs +1 -1
  56. package/dist/chunks/prompts.mjs +1 -1
  57. package/dist/chunks/providers.mjs +1 -1
  58. package/dist/chunks/quick-setup.mjs +16 -20
  59. package/dist/chunks/silent-updater.mjs +1 -1
  60. package/dist/chunks/simple-config.mjs +2 -2
  61. package/dist/chunks/skill.mjs +1 -1
  62. package/dist/chunks/skills-sync.mjs +1 -1
  63. package/dist/chunks/skills.mjs +1 -1
  64. package/dist/chunks/startup.mjs +1 -1
  65. package/dist/chunks/stats.mjs +1 -1
  66. package/dist/chunks/status.mjs +159 -0
  67. package/dist/chunks/team.mjs +1 -1
  68. package/dist/chunks/thinking.mjs +2 -2
  69. package/dist/chunks/uninstall.mjs +6 -6
  70. package/dist/chunks/update.mjs +6 -9
  71. package/dist/chunks/upgrade-manager.mjs +2 -2
  72. package/dist/chunks/version-checker.mjs +3 -3
  73. package/dist/chunks/vim.mjs +1 -1
  74. package/dist/chunks/workflows.mjs +616 -215
  75. package/dist/cli.mjs +70 -121
  76. package/dist/index.d.mts +17 -1482
  77. package/dist/index.d.ts +17 -1482
  78. package/dist/index.mjs +950 -4740
  79. package/dist/shared/{ccjk.zCqdxT2Y.mjs → ccjk.Br91zBIG.mjs} +2 -2
  80. package/dist/shared/ccjk.CSkyCZIM.mjs +638 -0
  81. package/dist/shared/{ccjk.BKoi8-Hy.mjs → ccjk.DE91nClQ.mjs} +1 -1
  82. package/dist/shared/{ccjk.f40us0yY.mjs → ccjk.DvIrK0wz.mjs} +2 -2
  83. package/dist/shared/ccjk.LsPZ2PYo.mjs +1048 -0
  84. package/dist/shared/{ccjk.DRweXU5F.mjs → ccjk.q1koQxEE.mjs} +2 -2
  85. package/package.json +1 -1
  86. package/templates/claude-code/common/settings.json +15 -111
  87. package/dist/chunks/api-adapter.mjs +0 -180
  88. package/dist/chunks/cli.mjs +0 -2227
  89. package/dist/chunks/context-menu.mjs +0 -913
  90. package/dist/chunks/hooks-sync.mjs +0 -1627
  91. package/dist/chunks/index6.mjs +0 -663
  92. package/dist/chunks/mcp-market.mjs +0 -1077
  93. package/dist/chunks/mcp-server.mjs +0 -776
  94. package/dist/chunks/project-detector.mjs +0 -131
  95. package/dist/chunks/provider-registry.mjs +0 -92
  96. package/dist/chunks/setup-wizard.mjs +0 -362
  97. package/dist/chunks/tools.mjs +0 -143
  98. package/dist/chunks/workflows2.mjs +0 -633
  99. package/dist/shared/ccjk.BM_HZogn.mjs +0 -347
  100. package/dist/shared/ccjk.BaEp4UHQ.mjs +0 -75
  101. package/dist/shared/ccjk.CS0ybJCf.mjs +0 -490
  102. package/dist/shared/ccjk.CZgIwikC.mjs +0 -209
  103. package/dist/shared/ccjk.tO8zeFh1.mjs +0 -397
@@ -1,490 +0,0 @@
1
- import ansis from 'ansis';
2
- import inquirer from 'inquirer';
3
- import { CLAUDE_DIR, SETTINGS_FILE } from '../chunks/constants.mjs';
4
- import { ensureI18nInitialized, i18n } from '../chunks/index2.mjs';
5
- import { m as mergeAndCleanPermissions, e as getExistingApiConfig, f as configureApi, s as switchToOfficialLogin, b as backupExistingConfig, a as applyAiLanguageDirective } from '../chunks/config.mjs';
6
- import { fileURLToPath } from 'node:url';
7
- import { join, dirname } from 'pathe';
8
- import { updateZcfConfig } from '../chunks/ccjk-config.mjs';
9
- import { exists, removeFile, ensureDir, copyFile } from '../chunks/fs-operations.mjs';
10
- import { readJsonConfig, writeJsonConfig } from '../chunks/json-config.mjs';
11
- import { a as addNumbersToChoices } from './ccjk.BFQ7yr5S.mjs';
12
- import { p as promptBoolean } from './ccjk.DHbrGcgg.mjs';
13
-
14
- const OUTPUT_STYLES = [
15
- // Custom styles (have template files) - 大神模式
16
- {
17
- id: "linus-mode",
18
- isCustom: true,
19
- filePath: "linus-mode.md"
20
- },
21
- {
22
- id: "uncle-bob-mode",
23
- isCustom: true,
24
- filePath: "uncle-bob-mode.md"
25
- },
26
- {
27
- id: "dhh-mode",
28
- isCustom: true,
29
- filePath: "dhh-mode.md"
30
- },
31
- {
32
- id: "carmack-mode",
33
- isCustom: true,
34
- filePath: "carmack-mode.md"
35
- },
36
- {
37
- id: "jobs-mode",
38
- isCustom: true,
39
- filePath: "jobs-mode.md"
40
- },
41
- {
42
- id: "evan-you-mode",
43
- isCustom: true,
44
- filePath: "evan-you-mode.md"
45
- },
46
- // Built-in styles (no template files) - Claude Code native styles
47
- {
48
- id: "default",
49
- isCustom: false
50
- },
51
- {
52
- id: "explanatory",
53
- isCustom: false
54
- },
55
- {
56
- id: "learning",
57
- isCustom: false
58
- }
59
- ];
60
- const LEGACY_FILES = ["personality.md", "rules.md", "technical-guides.md", "mcp.md", "language.md"];
61
- function getAvailableOutputStyles() {
62
- return OUTPUT_STYLES;
63
- }
64
- async function copyOutputStyles(selectedStyles, lang) {
65
- const outputStylesDir = join(CLAUDE_DIR, "output-styles");
66
- ensureDir(outputStylesDir);
67
- const currentFilePath = fileURLToPath(import.meta.url);
68
- const distDir = dirname(dirname(currentFilePath));
69
- const rootDir = dirname(distDir);
70
- const templateDir = join(rootDir, "templates", "common", "output-styles", lang);
71
- for (const styleId of selectedStyles) {
72
- const style = OUTPUT_STYLES.find((s) => s.id === styleId);
73
- if (!style || !style.isCustom || !style.filePath) {
74
- continue;
75
- }
76
- const sourcePath = join(templateDir, style.filePath);
77
- const destPath = join(outputStylesDir, style.filePath);
78
- if (exists(sourcePath)) {
79
- copyFile(sourcePath, destPath);
80
- }
81
- }
82
- }
83
- function setGlobalDefaultOutputStyle(styleId) {
84
- const templatePermissions = getTemplatePermissions();
85
- const existingSettings = readJsonConfig(SETTINGS_FILE) || {};
86
- const cleanedPermissions = mergeAndCleanPermissions(
87
- templatePermissions,
88
- existingSettings.permissions?.allow
89
- );
90
- const updatedSettings = {
91
- ...existingSettings,
92
- outputStyle: styleId,
93
- // Ensure clean permissions
94
- permissions: {
95
- allow: cleanedPermissions
96
- }
97
- };
98
- if (updatedSettings.plansDirectory === null) {
99
- delete updatedSettings.plansDirectory;
100
- }
101
- writeJsonConfig(SETTINGS_FILE, updatedSettings);
102
- }
103
- function getTemplatePermissions() {
104
- try {
105
- const { readFileSync } = require("node:fs");
106
- const { fileURLToPath: fileURLToPath2 } = require("node:url");
107
- const { dirname: dirname2, join: join2 } = require("pathe");
108
- const currentFilePath = fileURLToPath2(import.meta.url);
109
- const distDir = dirname2(dirname2(currentFilePath));
110
- const rootDir = dirname2(distDir);
111
- const templatePath = join2(rootDir, "templates", "claude-code", "common", "settings.json");
112
- if (require("node:fs").existsSync(templatePath)) {
113
- const template = JSON.parse(readFileSync(templatePath, "utf-8"));
114
- return template.permissions?.allow || [];
115
- }
116
- } catch (_error) {
117
- }
118
- return [
119
- "AllowEdit",
120
- "AllowWrite",
121
- "AllowRead",
122
- "AllowExec",
123
- "AllowCreateProcess",
124
- "AllowKillProcess",
125
- "AllowNetworkAccess",
126
- "AllowFileSystemAccess",
127
- "AllowShellAccess",
128
- "AllowHttpAccess"
129
- ];
130
- }
131
- function hasLegacyPersonalityFiles() {
132
- return LEGACY_FILES.some((filename) => exists(join(CLAUDE_DIR, filename)));
133
- }
134
- function cleanupLegacyPersonalityFiles() {
135
- LEGACY_FILES.forEach((filename) => {
136
- const filePath = join(CLAUDE_DIR, filename);
137
- if (exists(filePath)) {
138
- removeFile(filePath);
139
- }
140
- });
141
- }
142
- async function configureOutputStyle(preselectedStyles, preselectedDefault) {
143
- ensureI18nInitialized();
144
- const outputStyleList = [
145
- {
146
- id: "default",
147
- name: i18n.t("configuration:outputStyles.default.name"),
148
- description: i18n.t("configuration:outputStyles.default.description")
149
- },
150
- {
151
- id: "linus-mode",
152
- name: i18n.t("configuration:outputStyles.linus-mode.name"),
153
- description: i18n.t("configuration:outputStyles.linus-mode.description")
154
- },
155
- {
156
- id: "uncle-bob-mode",
157
- name: i18n.t("configuration:outputStyles.uncle-bob-mode.name"),
158
- description: i18n.t("configuration:outputStyles.uncle-bob-mode.description")
159
- },
160
- {
161
- id: "dhh-mode",
162
- name: i18n.t("configuration:outputStyles.dhh-mode.name"),
163
- description: i18n.t("configuration:outputStyles.dhh-mode.description")
164
- },
165
- {
166
- id: "carmack-mode",
167
- name: i18n.t("configuration:outputStyles.carmack-mode.name"),
168
- description: i18n.t("configuration:outputStyles.carmack-mode.description")
169
- },
170
- {
171
- id: "jobs-mode",
172
- name: i18n.t("configuration:outputStyles.jobs-mode.name"),
173
- description: i18n.t("configuration:outputStyles.jobs-mode.description")
174
- },
175
- {
176
- id: "evan-you-mode",
177
- name: i18n.t("configuration:outputStyles.evan-you-mode.name"),
178
- description: i18n.t("configuration:outputStyles.evan-you-mode.description")
179
- },
180
- {
181
- id: "explanatory",
182
- name: i18n.t("configuration:outputStyles.explanatory.name"),
183
- description: i18n.t("configuration:outputStyles.explanatory.description")
184
- },
185
- {
186
- id: "learning",
187
- name: i18n.t("configuration:outputStyles.learning.name"),
188
- description: i18n.t("configuration:outputStyles.learning.description")
189
- }
190
- ];
191
- const availableStyles = getAvailableOutputStyles();
192
- if (hasLegacyPersonalityFiles() && !preselectedStyles) {
193
- console.log(ansis.yellow(`\u26A0\uFE0F ${i18n.t("configuration:legacyFilesDetected")}`));
194
- const cleanupLegacy = await promptBoolean({
195
- message: i18n.t("configuration:cleanupLegacyFiles"),
196
- defaultValue: true
197
- });
198
- if (cleanupLegacy) {
199
- cleanupLegacyPersonalityFiles();
200
- console.log(ansis.green(`\u2714 ${i18n.t("configuration:legacyFilesRemoved")}`));
201
- }
202
- } else if (hasLegacyPersonalityFiles() && preselectedStyles) {
203
- cleanupLegacyPersonalityFiles();
204
- }
205
- let selectedStyles;
206
- let defaultStyle;
207
- if (preselectedStyles && preselectedDefault) {
208
- selectedStyles = preselectedStyles;
209
- defaultStyle = preselectedDefault;
210
- } else {
211
- const customStyles = availableStyles.filter((style) => style.isCustom);
212
- const { selectedStyles: promptedStyles } = await inquirer.prompt({
213
- type: "checkbox",
214
- name: "selectedStyles",
215
- message: `${i18n.t("configuration:selectOutputStyles")}${i18n.t("common:multiSelectHint")}`,
216
- choices: addNumbersToChoices(customStyles.map((style) => {
217
- const styleInfo = outputStyleList.find((s) => s.id === style.id);
218
- return {
219
- name: `${styleInfo?.name || style.id} - ${ansis.gray(styleInfo?.description || "")}`,
220
- value: style.id,
221
- checked: true
222
- // Default to all selected
223
- };
224
- })),
225
- validate: async (input) => input.length > 0 || i18n.t("configuration:selectAtLeastOne")
226
- });
227
- if (!promptedStyles || promptedStyles.length === 0) {
228
- console.log(ansis.yellow(i18n.t("common:cancelled")));
229
- return;
230
- }
231
- selectedStyles = promptedStyles;
232
- const { defaultStyle: promptedDefault } = await inquirer.prompt({
233
- type: "list",
234
- name: "defaultStyle",
235
- message: i18n.t("configuration:selectDefaultOutputStyle"),
236
- choices: addNumbersToChoices([
237
- // Show selected custom styles first (only what user actually installed)
238
- ...selectedStyles.map((styleId) => {
239
- const styleInfo = outputStyleList.find((s) => s.id === styleId);
240
- return {
241
- name: `${styleInfo?.name || styleId} - ${ansis.gray(styleInfo?.description || "")}`,
242
- value: styleId,
243
- short: styleInfo?.name || styleId
244
- };
245
- }),
246
- // Then show all built-in styles (always available)
247
- ...availableStyles.filter((style) => !style.isCustom).map((style) => {
248
- const styleInfo = outputStyleList.find((s) => s.id === style.id);
249
- return {
250
- name: `${styleInfo?.name || style.id} - ${ansis.gray(styleInfo?.description || "")}`,
251
- value: style.id,
252
- short: styleInfo?.name || style.id
253
- };
254
- })
255
- ]),
256
- default: selectedStyles.includes("linus-mode") ? "linus-mode" : selectedStyles[0]
257
- });
258
- if (!promptedDefault) {
259
- console.log(ansis.yellow(i18n.t("common:cancelled")));
260
- return;
261
- }
262
- defaultStyle = promptedDefault;
263
- }
264
- await copyOutputStyles(selectedStyles, "zh-CN");
265
- setGlobalDefaultOutputStyle(defaultStyle);
266
- updateZcfConfig({
267
- outputStyles: selectedStyles,
268
- defaultOutputStyle: defaultStyle
269
- });
270
- console.log(ansis.green(`\u2714 ${i18n.t("configuration:outputStyleInstalled")}`));
271
- console.log(ansis.gray(` ${i18n.t("configuration:selectedStyles")}: ${selectedStyles.join(", ")}`));
272
- console.log(ansis.gray(` ${i18n.t("configuration:defaultStyle")}: ${defaultStyle}`));
273
- }
274
-
275
- function validateApiKey(apiKey) {
276
- if (!apiKey || apiKey.trim() === "") {
277
- return {
278
- isValid: false,
279
- // Note: This should use i18next, but due to sync constraint in inquirer validate,
280
- // we temporarily use a generic message. This will be fixed when we refactor to async validation.
281
- error: "API key cannot be empty"
282
- };
283
- }
284
- return { isValid: true };
285
- }
286
- function formatApiKeyDisplay(apiKey) {
287
- if (!apiKey || apiKey.length < 12) {
288
- return apiKey;
289
- }
290
- return `${apiKey.substring(0, 8)}...${apiKey.substring(apiKey.length - 4)}`;
291
- }
292
-
293
- async function configureApiCompletely(preselectedAuthType) {
294
- ensureI18nInitialized();
295
- let authType = preselectedAuthType;
296
- if (!authType) {
297
- const { authType: selectedAuthType } = await inquirer.prompt({
298
- type: "list",
299
- name: "authType",
300
- message: i18n.t("api:configureApi"),
301
- choices: addNumbersToChoices([
302
- {
303
- name: i18n.t("api:useOfficialLogin"),
304
- value: "official",
305
- short: i18n.t("api:useOfficialLogin")
306
- },
307
- {
308
- name: `${i18n.t("api:useAuthToken")} - ${ansis.gray(i18n.t("api:authTokenDesc"))}`,
309
- value: "auth_token",
310
- short: i18n.t("api:useAuthToken")
311
- },
312
- {
313
- name: `${i18n.t("api:useApiKey")} - ${ansis.gray(i18n.t("api:apiKeyDesc"))}`,
314
- value: "api_key",
315
- short: i18n.t("api:useApiKey")
316
- }
317
- ])
318
- });
319
- if (!selectedAuthType) {
320
- console.log(ansis.yellow(i18n.t("common:cancelled")));
321
- return null;
322
- }
323
- authType = selectedAuthType;
324
- }
325
- if (authType === "official") {
326
- const success = switchToOfficialLogin();
327
- if (success) {
328
- return null;
329
- } else {
330
- console.log(ansis.red(i18n.t("api:officialLoginFailed")));
331
- return null;
332
- }
333
- }
334
- const { url } = await inquirer.prompt({
335
- type: "input",
336
- name: "url",
337
- message: i18n.t("api:enterApiUrl"),
338
- validate: async (value) => {
339
- if (!value)
340
- return i18n.t("api:urlRequired");
341
- try {
342
- void new URL(value);
343
- return true;
344
- } catch {
345
- return i18n.t("api:invalidUrl");
346
- }
347
- }
348
- });
349
- if (url === void 0) {
350
- console.log(ansis.yellow(i18n.t("common:cancelled")));
351
- return null;
352
- }
353
- const keyMessage = authType === "auth_token" ? i18n.t("api:enterAuthToken") : i18n.t("api:enterApiKey");
354
- const { key } = await inquirer.prompt({
355
- type: "input",
356
- name: "key",
357
- message: keyMessage,
358
- validate: async (value) => {
359
- if (!value) {
360
- return i18n.t("api:keyRequired");
361
- }
362
- const validation = validateApiKey(value);
363
- if (!validation.isValid) {
364
- return validation.error || i18n.t("api:invalidKeyFormat");
365
- }
366
- return true;
367
- }
368
- });
369
- if (key === void 0) {
370
- console.log(ansis.yellow(i18n.t("common:cancelled")));
371
- return null;
372
- }
373
- console.log(ansis.gray(` API Key: ${formatApiKeyDisplay(key)}`));
374
- return { url, key, authType };
375
- }
376
- async function modifyApiConfigPartially(existingConfig) {
377
- ensureI18nInitialized();
378
- let currentConfig = { ...existingConfig };
379
- const latestConfig = getExistingApiConfig();
380
- if (latestConfig) {
381
- currentConfig = latestConfig;
382
- }
383
- const { item } = await inquirer.prompt({
384
- type: "list",
385
- name: "item",
386
- message: i18n.t("api:selectModifyItems"),
387
- choices: addNumbersToChoices([
388
- { name: i18n.t("api:modifyApiUrl"), value: "url" },
389
- { name: i18n.t("api:modifyApiKey"), value: "key" },
390
- { name: i18n.t("api:modifyAuthType"), value: "authType" }
391
- ])
392
- });
393
- if (!item) {
394
- console.log(ansis.yellow(i18n.t("common:cancelled")));
395
- return;
396
- }
397
- if (item === "url") {
398
- const { url } = await inquirer.prompt({
399
- type: "input",
400
- name: "url",
401
- message: i18n.t("api:enterNewApiUrl").replace("{url}", currentConfig.url || i18n.t("common:none")),
402
- default: currentConfig.url,
403
- validate: async (value) => {
404
- if (!value)
405
- return i18n.t("api:urlRequired");
406
- try {
407
- void new URL(value);
408
- return true;
409
- } catch {
410
- return i18n.t("api:invalidUrl");
411
- }
412
- }
413
- });
414
- if (url === void 0) {
415
- console.log(ansis.yellow(i18n.t("common:cancelled")));
416
- return;
417
- }
418
- currentConfig.url = url;
419
- const savedConfig = configureApi(currentConfig);
420
- if (savedConfig) {
421
- console.log(ansis.green(`\u2714 ${i18n.t("api:modificationSaved")}`));
422
- console.log(ansis.gray(` ${i18n.t("api:apiConfigUrl")}: ${savedConfig.url}`));
423
- }
424
- } else if (item === "key") {
425
- const authType = currentConfig.authType || "auth_token";
426
- const keyMessage = authType === "auth_token" ? i18n.t("api:enterNewApiKey").replace("{key}", currentConfig.key ? formatApiKeyDisplay(currentConfig.key) : i18n.t("common:none")) : i18n.t("api:enterNewApiKey").replace("{key}", currentConfig.key ? formatApiKeyDisplay(currentConfig.key) : i18n.t("common:none"));
427
- const { key } = await inquirer.prompt({
428
- type: "input",
429
- name: "key",
430
- message: keyMessage,
431
- validate: async (value) => {
432
- if (!value) {
433
- return i18n.t("api:keyRequired");
434
- }
435
- const validation = validateApiKey(value);
436
- if (!validation.isValid) {
437
- return validation.error || i18n.t("api:invalidKeyFormat");
438
- }
439
- return true;
440
- }
441
- });
442
- if (key === void 0) {
443
- console.log(ansis.yellow(i18n.t("common:cancelled")));
444
- return;
445
- }
446
- currentConfig.key = key;
447
- const savedConfig = configureApi(currentConfig);
448
- if (savedConfig) {
449
- console.log(ansis.green(`\u2714 ${i18n.t("api:modificationSaved")}`));
450
- console.log(ansis.gray(` ${i18n.t("api:apiConfigKey")}: ${formatApiKeyDisplay(savedConfig.key)}`));
451
- }
452
- } else if (item === "authType") {
453
- const { authType } = await inquirer.prompt({
454
- type: "list",
455
- name: "authType",
456
- message: i18n.t("api:selectNewAuthType").replace("{type}", currentConfig.authType || i18n.t("common:none")),
457
- choices: addNumbersToChoices([
458
- { name: "Auth Token (OAuth)", value: "auth_token" },
459
- { name: "API Key", value: "api_key" }
460
- ]),
461
- default: currentConfig.authType === "api_key" ? 1 : 0
462
- });
463
- if (authType === void 0) {
464
- console.log(ansis.yellow(i18n.t("common:cancelled")));
465
- return;
466
- }
467
- currentConfig.authType = authType;
468
- const savedConfig = configureApi(currentConfig);
469
- if (savedConfig) {
470
- console.log(ansis.green(`\u2714 ${i18n.t("api:modificationSaved")}`));
471
- console.log(ansis.gray(` ${i18n.t("api:apiConfigAuthType")}: ${savedConfig.authType}`));
472
- }
473
- }
474
- }
475
- async function updatePromptOnly(aiOutputLang) {
476
- ensureI18nInitialized();
477
- const backupDir = backupExistingConfig();
478
- if (backupDir) {
479
- console.log(ansis.gray(`\u2714 ${i18n.t("configuration:backupSuccess")}: ${backupDir}`));
480
- }
481
- if (aiOutputLang) {
482
- applyAiLanguageDirective(aiOutputLang);
483
- }
484
- await configureOutputStyle();
485
- console.log(ansis.green(`\u2714 ${i18n.t("configuration:configSuccess")} ${CLAUDE_DIR}`));
486
- console.log(`
487
- ${ansis.green(i18n.t("common:complete"))}`);
488
- }
489
-
490
- export { configureApiCompletely as a, configureOutputStyle as c, formatApiKeyDisplay as f, modifyApiConfigPartially as m, updatePromptOnly as u, validateApiKey as v };
@@ -1,209 +0,0 @@
1
- import ansis from 'ansis';
2
- import inquirer from 'inquirer';
3
- import 'node:child_process';
4
- import { homedir } from 'node:os';
5
- import 'node:process';
6
- import { join } from 'pathe';
7
- import { ensureI18nInitialized, i18n } from '../chunks/index2.mjs';
8
-
9
- const PLAYWRIGHT_PROFILES_DIR = join(homedir(), ".ccjk", "playwright");
10
- function createPlaywrightMcpConfig(options = {}) {
11
- const {
12
- profile = "default",
13
- headless = false,
14
- browser = "chromium",
15
- userDataDir
16
- } = options;
17
- const resolvedUserDataDir = userDataDir || join(PLAYWRIGHT_PROFILES_DIR, profile);
18
- const args = ["-y", "@playwright/mcp@latest"];
19
- args.push("--browser", browser);
20
- args.push("--user-data-dir", resolvedUserDataDir);
21
- if (headless) {
22
- args.push("--headless");
23
- }
24
- return {
25
- type: "stdio",
26
- command: "npx",
27
- args,
28
- env: {}
29
- };
30
- }
31
- const MCP_SERVICE_CONFIGS = [
32
- // Documentation and Search Services - Universal (no GUI required)
33
- {
34
- id: "context7",
35
- requiresApiKey: false,
36
- config: {
37
- type: "stdio",
38
- command: "npx",
39
- args: ["-y", "@upstash/context7-mcp@latest"],
40
- env: {}
41
- }
42
- // Works on all platforms - no special requirements
43
- },
44
- {
45
- id: "open-websearch",
46
- requiresApiKey: false,
47
- config: {
48
- type: "stdio",
49
- command: "npx",
50
- args: ["-y", "open-websearch@latest"],
51
- env: {
52
- MODE: "stdio",
53
- DEFAULT_SEARCH_ENGINE: "duckduckgo",
54
- ALLOWED_SEARCH_ENGINES: "duckduckgo,bing,brave"
55
- }
56
- }
57
- // Works on all platforms - no special requirements
58
- },
59
- {
60
- id: "mcp-deepwiki",
61
- requiresApiKey: false,
62
- config: {
63
- type: "stdio",
64
- command: "npx",
65
- args: ["-y", "mcp-deepwiki@latest"],
66
- env: {}
67
- }
68
- // Works on all platforms - no special requirements
69
- },
70
- // Development Workflow Services
71
- {
72
- id: "spec-workflow",
73
- requiresApiKey: false,
74
- config: {
75
- type: "stdio",
76
- command: "npx",
77
- args: ["-y", "@pimzino/spec-workflow-mcp@latest"],
78
- env: {}
79
- }
80
- // Works on all platforms - no special requirements
81
- },
82
- {
83
- id: "serena",
84
- requiresApiKey: false,
85
- config: {
86
- type: "stdio",
87
- command: "uvx",
88
- args: ["--from", "git+https://github.com/oraios/serena", "serena", "start-mcp-server", "--context", "ide-assistant", "--enable-web-dashboard", "false"],
89
- env: {}
90
- },
91
- platformRequirements: {
92
- requiredCommands: ["uvx"]
93
- // Requires uv/uvx to be installed
94
- }
95
- },
96
- // Browser and Automation Services - Require GUI environment
97
- {
98
- id: "Playwright",
99
- requiresApiKey: false,
100
- config: createPlaywrightMcpConfig(),
101
- // Uses default profile with chromium browser
102
- platformRequirements: {
103
- platforms: ["macos", "windows"],
104
- // GUI required - exclude headless Linux/WSL/Termux
105
- requiresGui: true
106
- }
107
- },
108
- // Anthropic Official MCP Services - Universal
109
- // Note: Removed low-value services: filesystem (buggy), puppeteer (duplicate of Playwright),
110
- // memory (Claude has built-in memory), fetch (Claude has WebFetch), sequential-thinking (limited value)
111
- {
112
- id: "sqlite",
113
- requiresApiKey: false,
114
- config: {
115
- type: "stdio",
116
- command: "npx",
117
- args: ["-y", "@anthropic-ai/mcp-server-sqlite@latest"],
118
- env: {}
119
- }
120
- // Works on all platforms - no special requirements
121
- }
122
- ];
123
- async function getMcpServices() {
124
- ensureI18nInitialized();
125
- const mcpServiceList = [
126
- // Documentation and Search Services
127
- {
128
- id: "context7",
129
- name: i18n.t("mcp:services.context7.name"),
130
- description: i18n.t("mcp:services.context7.description")
131
- },
132
- {
133
- id: "open-websearch",
134
- name: i18n.t("mcp:services.open-websearch.name"),
135
- description: i18n.t("mcp:services.open-websearch.description")
136
- },
137
- {
138
- id: "mcp-deepwiki",
139
- name: i18n.t("mcp:services.mcp-deepwiki.name"),
140
- description: i18n.t("mcp:services.mcp-deepwiki.description")
141
- },
142
- // Development Workflow Services
143
- {
144
- id: "spec-workflow",
145
- name: i18n.t("mcp:services.spec-workflow.name"),
146
- description: i18n.t("mcp:services.spec-workflow.description")
147
- },
148
- {
149
- id: "serena",
150
- name: i18n.t("mcp:services.serena.name"),
151
- description: i18n.t("mcp:services.serena.description")
152
- },
153
- // Browser and Automation Services
154
- {
155
- id: "Playwright",
156
- name: i18n.t("mcp:services.playwright.name"),
157
- description: i18n.t("mcp:services.playwright.description")
158
- },
159
- // Anthropic Official MCP Services
160
- // Note: Removed low-value services: filesystem (buggy), puppeteer (duplicate),
161
- // memory (Claude built-in), fetch (Claude WebFetch), sequential-thinking (limited value)
162
- {
163
- id: "sqlite",
164
- name: i18n.t("mcp:services.sqlite.name"),
165
- description: i18n.t("mcp:services.sqlite.description")
166
- }
167
- ];
168
- return MCP_SERVICE_CONFIGS.map((config) => {
169
- const serviceInfo = mcpServiceList.find((s) => s.id === config.id);
170
- const service = {
171
- id: config.id,
172
- name: serviceInfo?.name || config.id,
173
- description: serviceInfo?.description || "",
174
- requiresApiKey: config.requiresApiKey,
175
- config: config.config
176
- };
177
- if (config.apiKeyEnvVar) {
178
- service.apiKeyEnvVar = config.apiKeyEnvVar;
179
- }
180
- return service;
181
- });
182
- }
183
- async function getMcpService(id) {
184
- const services = await getMcpServices();
185
- return services.find((service) => service.id === id);
186
- }
187
-
188
- async function selectMcpServices() {
189
- ensureI18nInitialized();
190
- const mcpServices = await getMcpServices();
191
- const choices = mcpServices.map((service) => ({
192
- name: `${service.name} - ${ansis.gray(service.description)}`,
193
- value: service.id,
194
- selected: false
195
- }));
196
- const { services } = await inquirer.prompt({
197
- type: "checkbox",
198
- name: "services",
199
- message: `${i18n.t("mcp:selectMcpServices")}${i18n.t("common:multiSelectHint")}`,
200
- choices
201
- });
202
- if (services === void 0) {
203
- console.log(ansis.yellow(i18n.t("common:cancelled")));
204
- return void 0;
205
- }
206
- return services;
207
- }
208
-
209
- export { MCP_SERVICE_CONFIGS as M, getMcpService as a, getMcpServices as g, selectMcpServices as s };