ccjk 14.1.11 → 14.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/dist/chunks/api-cli.mjs +3 -2
  2. package/dist/chunks/api-config-selector.mjs +8 -6
  3. package/dist/chunks/auto-updater.mjs +1 -1
  4. package/dist/chunks/ccjk-agents.mjs +2 -2
  5. package/dist/chunks/ccjk-all.mjs +6 -6
  6. package/dist/chunks/ccjk-hooks.mjs +2 -2
  7. package/dist/chunks/ccjk-mcp.mjs +5 -5
  8. package/dist/chunks/ccjk-setup.mjs +4 -4
  9. package/dist/chunks/ccjk-skills.mjs +2 -2
  10. package/dist/chunks/ccr.mjs +11 -9
  11. package/dist/chunks/check-updates.mjs +2 -1
  12. package/dist/chunks/claude-code-incremental-manager.mjs +8 -6
  13. package/dist/chunks/claude-config.mjs +594 -62
  14. package/dist/chunks/claude-config2.mjs +62 -0
  15. package/dist/chunks/clavue-config.mjs +1390 -0
  16. package/dist/chunks/code-type-resolver.mjs +1 -1
  17. package/dist/chunks/codex-config-switch.mjs +1 -0
  18. package/dist/chunks/codex-provider-manager.mjs +2 -1
  19. package/dist/chunks/codex.mjs +4 -3
  20. package/dist/chunks/config-switch.mjs +6 -4
  21. package/dist/chunks/config.mjs +23 -1974
  22. package/dist/chunks/config2.mjs +8 -7
  23. package/dist/chunks/config3.mjs +1 -0
  24. package/dist/chunks/doctor.mjs +178 -8
  25. package/dist/chunks/features.mjs +9 -7
  26. package/dist/chunks/index10.mjs +14 -5365
  27. package/dist/chunks/index9.mjs +5379 -14
  28. package/dist/chunks/init.mjs +12 -10
  29. package/dist/chunks/installer.mjs +7 -5
  30. package/dist/chunks/interview.mjs +1 -1
  31. package/dist/chunks/mcp-cli.mjs +23 -22
  32. package/dist/chunks/mcp.mjs +8 -7
  33. package/dist/chunks/package.mjs +1 -1
  34. package/dist/chunks/platform.mjs +1 -1
  35. package/dist/chunks/quick-provider.mjs +7 -5
  36. package/dist/chunks/quick-setup.mjs +7 -5
  37. package/dist/chunks/simple-config.mjs +3 -2
  38. package/dist/chunks/slash-commands.mjs +1 -1
  39. package/dist/chunks/thinking.mjs +1 -1
  40. package/dist/chunks/uninstall.mjs +1 -1
  41. package/dist/chunks/update.mjs +10 -9
  42. package/dist/chunks/version-checker.mjs +1 -1
  43. package/dist/chunks/zero-config.mjs +4 -3
  44. package/dist/cli.mjs +3 -3
  45. package/dist/index.mjs +7 -6
  46. package/dist/shared/{ccjk.DGllfVCZ.mjs → ccjk.BtrioX1Z.mjs} +1 -1
  47. package/dist/shared/{ccjk.DOw7Fawt.mjs → ccjk.C1Be3aJN.mjs} +2 -2
  48. package/dist/shared/{ccjk.BCzOWT1L.mjs → ccjk.C94P8gCY.mjs} +2 -2
  49. package/dist/shared/{ccjk.Cgv_cFVX.mjs → ccjk.CTr4yCZ1.mjs} +2 -2
  50. package/dist/shared/{ccjk.Cv13QsGp.mjs → ccjk.CoCHVXl3.mjs} +1 -1
  51. package/dist/shared/{ccjk.f3TBLJSt.mjs → ccjk.CwGZSTAK.mjs} +7 -7
  52. package/dist/shared/{ccjk.CfKJnpbB.mjs → ccjk.D-magaEx.mjs} +2 -2
  53. package/dist/shared/{ccjk.CbWVbtb9.mjs → ccjk.DhJ1kyDR.mjs} +1 -1
  54. package/dist/shared/{ccjk.zFGcZT7Y.mjs → ccjk.OJKHVSOb.mjs} +1 -1
  55. package/dist/templates/agents/README.md +78 -0
  56. package/dist/templates/common/error-prevention.md +267 -0
  57. package/dist/templates/common/karpathy-baseline.md +83 -0
  58. package/dist/templates/common/output-styles/zh-CN/carmack-mode.md +381 -0
  59. package/dist/templates/common/output-styles/zh-CN/dhh-mode.md +265 -0
  60. package/dist/templates/common/output-styles/zh-CN/evan-you-mode.md +539 -0
  61. package/dist/templates/common/output-styles/zh-CN/jobs-mode.md +369 -0
  62. package/dist/templates/common/output-styles/zh-CN/linus-mode.md +135 -0
  63. package/dist/templates/common/output-styles/zh-CN/uncle-bob-mode.md +221 -0
  64. package/dist/templates/common/workflow/continuousDelivery/en/continuous-delivery.md +628 -0
  65. package/dist/templates/common/workflow/continuousDelivery/zh-CN/continuous-delivery.md +628 -0
  66. package/dist/templates/common/workflow/essential/en/agents/ccjk-config-agent.md +187 -0
  67. package/dist/templates/common/workflow/essential/en/agents/ccjk-mcp-agent.md +191 -0
  68. package/dist/templates/common/workflow/essential/en/agents/ccjk-skill-agent.md +249 -0
  69. package/dist/templates/common/workflow/essential/en/agents/ccjk-workflow-agent.md +277 -0
  70. package/dist/templates/common/workflow/essential/en/agents/get-current-datetime.md +29 -0
  71. package/dist/templates/common/workflow/essential/en/agents/init-architect.md +115 -0
  72. package/dist/templates/common/workflow/essential/en/agents/ui-ux-designer.md +91 -0
  73. package/dist/templates/common/workflow/essential/en/feat.md +92 -0
  74. package/dist/templates/common/workflow/essential/en/goal.md +147 -0
  75. package/dist/templates/common/workflow/essential/en/init-project.md +53 -0
  76. package/dist/templates/common/workflow/essential/zh-CN/agents/get-current-datetime.md +29 -0
  77. package/dist/templates/common/workflow/essential/zh-CN/agents/init-architect.md +115 -0
  78. package/dist/templates/common/workflow/essential/zh-CN/agents/ui-ux-designer.md +91 -0
  79. package/dist/templates/common/workflow/essential/zh-CN/feat.md +315 -0
  80. package/dist/templates/common/workflow/essential/zh-CN/goal.md +146 -0
  81. package/dist/templates/common/workflow/essential/zh-CN/init-project.md +53 -0
  82. package/dist/templates/common/workflow/git/en/git-cleanBranches.md +102 -0
  83. package/dist/templates/common/workflow/git/en/git-commit.md +205 -0
  84. package/dist/templates/common/workflow/git/en/git-rollback.md +90 -0
  85. package/dist/templates/common/workflow/git/en/git-worktree.md +276 -0
  86. package/dist/templates/common/workflow/git/zh-CN/git-cleanBranches.md +102 -0
  87. package/dist/templates/common/workflow/git/zh-CN/git-commit.md +205 -0
  88. package/dist/templates/common/workflow/git/zh-CN/git-rollback.md +90 -0
  89. package/dist/templates/common/workflow/git/zh-CN/git-worktree.md +276 -0
  90. package/dist/templates/common/workflow/interview/en/interview.md +67 -0
  91. package/dist/templates/common/workflow/interview/zh-CN/interview.md +67 -0
  92. package/dist/templates/common/workflow/linearMethod/en/linear-method.md +651 -0
  93. package/dist/templates/common/workflow/linearMethod/zh-CN/linear-method.md +752 -0
  94. package/dist/templates/common/workflow/refactoringMaster/en/refactoring-master.md +516 -0
  95. package/dist/templates/common/workflow/refactoringMaster/zh-CN/refactoring-master.md +812 -0
  96. package/dist/templates/common/workflow/sixStep/en/workflow.md +83 -0
  97. package/dist/templates/common/workflow/sixStep/zh-CN/workflow.md +359 -0
  98. package/dist/templates/common/workflow/specFirstTDD/en/spec-first-tdd.md +364 -0
  99. package/dist/templates/common/workflow/specFirstTDD/zh-CN/spec-first-tdd.md +366 -0
  100. package/dist/templates/hooks/README.md +212 -0
  101. package/dist/templates/hooks/git-workflow-hooks.md +551 -0
  102. package/dist/templates/hooks/post-test-coverage.md +434 -0
  103. package/dist/templates/hooks/pre-commit-black.md +274 -0
  104. package/dist/templates/hooks/pre-commit-eslint.md +153 -0
  105. package/dist/templates/hooks/pre-commit-gofmt.md +284 -0
  106. package/dist/templates/hooks/pre-commit-prettier.md +212 -0
  107. package/dist/templates/hooks/pre-commit-type-check.md +377 -0
  108. package/dist/templates/skills/ccjk-init.md +154 -0
  109. package/dist/templates/skills/ccjk-mcp-setup.md +205 -0
  110. package/dist/templates/skills/ccjk-troubleshoot.md +228 -0
  111. package/dist/templates/skills/django-patterns.md +1016 -0
  112. package/dist/templates/skills/git-workflow.md +748 -0
  113. package/dist/templates/skills/go-idioms.md +963 -0
  114. package/dist/templates/skills/nextjs-optimization.md +694 -0
  115. package/dist/templates/skills/python-pep8.md +852 -0
  116. package/dist/templates/skills/react-patterns.md +686 -0
  117. package/dist/templates/skills/rust-patterns.md +1057 -0
  118. package/dist/templates/skills/security-best-practices.md +1413 -0
  119. package/dist/templates/skills/testing-best-practices.md +1315 -0
  120. package/dist/templates/skills/ts-best-practices.md +354 -0
  121. package/package.json +1 -1
  122. package/templates/common/karpathy-baseline.md +83 -0
  123. package/templates/common/output-styles/zh-CN/carmack-mode.md +14 -0
  124. package/templates/common/output-styles/zh-CN/dhh-mode.md +14 -0
  125. package/templates/common/output-styles/zh-CN/evan-you-mode.md +14 -0
  126. package/templates/common/output-styles/zh-CN/jobs-mode.md +14 -0
  127. package/templates/common/output-styles/zh-CN/linus-mode.md +14 -0
  128. package/templates/common/output-styles/zh-CN/uncle-bob-mode.md +14 -0
  129. package/templates/common/workflow/linearMethod/zh-CN/linear-method.md +2 -0
  130. package/templates/common/workflow/refactoringMaster/zh-CN/refactoring-master.md +2 -0
  131. package/templates/common/workflow/sixStep/zh-CN/workflow.md +2 -0
  132. package/templates/common/workflow/specFirstTDD/zh-CN/spec-first-tdd.md +2 -0
@@ -1,74 +1,606 @@
1
- import { SETTINGS_FILE } from './constants.mjs';
2
- import { n as normalizeClaudeFamilySettings } from '../shared/ccjk.DDL-4C-k.mjs';
3
- import { exists, ensureDir } from './fs-operations.mjs';
4
- import { readJsonConfig, writeJsonConfig } from './json-config.mjs';
5
- import { x as deepMerge } from './config.mjs';
6
- import { d as dirname } from '../shared/ccjk.bQ7Dh1g4.mjs';
7
- import 'node:os';
8
- import './index2.mjs';
9
- import 'node:fs';
10
- import 'node:process';
11
- import 'node:url';
12
- import './ccjk-config.mjs';
13
- import '../shared/ccjk.BBtCGd_g.mjs';
14
- import './index3.mjs';
15
- import 'node:crypto';
16
- import 'node:fs/promises';
17
- import '../shared/ccjk.RyizuzOI.mjs';
18
- import '../shared/ccjk.BAGoDD49.mjs';
19
- import './index5.mjs';
20
- import './index6.mjs';
21
- import 'node:readline';
22
- import 'stream';
23
- import 'node:tty';
24
- import 'node:async_hooks';
25
- import '../shared/ccjk.Cjgrln_h.mjs';
26
- import 'node:util';
27
- import 'tty';
28
- import 'fs';
29
- import 'child_process';
30
- import 'node:path';
31
- import 'buffer';
32
- import 'string_decoder';
33
- import 'node:child_process';
34
- import './platform.mjs';
35
- import './main.mjs';
36
- import 'module';
37
- import 'node:stream';
1
+ import { execSync } from 'node:child_process';
2
+ import process__default from 'node:process';
3
+ import { ensureI18nInitialized, i18n } from './index2.mjs';
4
+ import { CLAUDE_VSC_CONFIG_FILE } from './constants.mjs';
5
+ import { r as resolveClaudeFamilySettingsTarget, a as applyTrustedOperatorPermissions, n as normalizeClaudeFamilySettings } from '../shared/ccjk.DDL-4C-k.mjs';
6
+ import { readJsonConfig, writeJsonConfig, backupJsonConfig } from './json-config.mjs';
7
+ import { i as isWindows, m as getMcpCommand } from './platform.mjs';
8
+ import { j as join } from '../shared/ccjk.bQ7Dh1g4.mjs';
38
9
 
39
- function readClaudeConfig(configPath = SETTINGS_FILE) {
10
+ const MCP_SERVICE_CONFIGS = [
11
+ // Documentation and research services
12
+ {
13
+ id: "context7",
14
+ requiresApiKey: false,
15
+ defaultSelected: true,
16
+ config: {
17
+ type: "stdio",
18
+ command: "npx",
19
+ args: ["-y", "@upstash/context7-mcp@latest"],
20
+ env: {}
21
+ }
22
+ },
23
+ {
24
+ id: "open-websearch",
25
+ requiresApiKey: false,
26
+ config: {
27
+ type: "stdio",
28
+ command: "npx",
29
+ args: ["-y", "open-websearch@latest"],
30
+ env: {
31
+ MODE: "stdio",
32
+ DEFAULT_SEARCH_ENGINE: "duckduckgo",
33
+ ALLOWED_SEARCH_ENGINES: "duckduckgo,bing,brave"
34
+ }
35
+ }
36
+ },
37
+ {
38
+ id: "mcp-deepwiki",
39
+ requiresApiKey: false,
40
+ config: {
41
+ type: "stdio",
42
+ command: "npx",
43
+ args: ["-y", "mcp-deepwiki@latest"],
44
+ env: {}
45
+ }
46
+ },
47
+ {
48
+ id: "spec-workflow",
49
+ requiresApiKey: false,
50
+ config: {
51
+ type: "stdio",
52
+ command: "npx",
53
+ args: ["-y", "@pimzino/spec-workflow-mcp@latest"],
54
+ env: {}
55
+ }
56
+ },
57
+ {
58
+ id: "serena",
59
+ requiresApiKey: false,
60
+ config: {
61
+ type: "stdio",
62
+ command: "uvx",
63
+ args: ["--from", "git+https://github.com/oraios/serena", "serena", "start-mcp-server", "--context", "ide-assistant", "--enable-web-dashboard", "false"],
64
+ env: {}
65
+ },
66
+ platformRequirements: {
67
+ requiredCommands: ["uvx"]
68
+ }
69
+ },
70
+ {
71
+ id: "Playwright",
72
+ requiresApiKey: false,
73
+ config: {
74
+ type: "stdio",
75
+ command: "npx",
76
+ args: ["-y", "@playwright/mcp@latest", "--browser", "chromium"],
77
+ env: {}
78
+ },
79
+ platformRequirements: {
80
+ platforms: ["macos", "windows"],
81
+ requiresGui: true
82
+ }
83
+ },
84
+ {
85
+ id: "intent-engine",
86
+ requiresApiKey: false,
87
+ config: {
88
+ type: "stdio",
89
+ command: "npx",
90
+ args: ["-y", "@origintask/intent-engine@latest", "mcp"],
91
+ env: {}
92
+ }
93
+ },
94
+ {
95
+ id: "sqlite",
96
+ requiresApiKey: false,
97
+ config: {
98
+ type: "stdio",
99
+ command: "npx",
100
+ args: ["-y", "@anthropic-ai/mcp-server-sqlite@latest"],
101
+ env: {}
102
+ }
103
+ }
104
+ ];
105
+ async function getMcpServices() {
106
+ ensureI18nInitialized();
107
+ const mcpServiceList = [
108
+ {
109
+ id: "context7",
110
+ name: i18n.t("mcp:services.context7.name"),
111
+ description: i18n.t("mcp:services.context7.description")
112
+ },
113
+ {
114
+ id: "open-websearch",
115
+ name: i18n.t("mcp:services.open-websearch.name"),
116
+ description: i18n.t("mcp:services.open-websearch.description")
117
+ },
118
+ {
119
+ id: "mcp-deepwiki",
120
+ name: i18n.t("mcp:services.mcp-deepwiki.name"),
121
+ description: i18n.t("mcp:services.mcp-deepwiki.description")
122
+ },
123
+ {
124
+ id: "spec-workflow",
125
+ name: i18n.t("mcp:services.spec-workflow.name"),
126
+ description: i18n.t("mcp:services.spec-workflow.description")
127
+ },
128
+ {
129
+ id: "serena",
130
+ name: i18n.t("mcp:services.serena.name"),
131
+ description: i18n.t("mcp:services.serena.description")
132
+ },
133
+ {
134
+ id: "Playwright",
135
+ name: i18n.t("mcp:services.Playwright.name"),
136
+ description: i18n.t("mcp:services.Playwright.description")
137
+ },
138
+ {
139
+ id: "intent-engine",
140
+ name: i18n.t("mcp:services.intent-engine.name"),
141
+ description: i18n.t("mcp:services.intent-engine.description")
142
+ },
143
+ {
144
+ id: "sqlite",
145
+ name: i18n.t("mcp:services.sqlite.name"),
146
+ description: i18n.t("mcp:services.sqlite.description")
147
+ }
148
+ ];
149
+ return MCP_SERVICE_CONFIGS.map((config) => {
150
+ const serviceInfo = mcpServiceList.find((s) => s.id === config.id);
151
+ const service = {
152
+ id: config.id,
153
+ name: serviceInfo?.name || config.id,
154
+ description: serviceInfo?.description || "",
155
+ requiresApiKey: config.requiresApiKey,
156
+ config: config.config
157
+ };
158
+ if (config.apiKeyEnvVar) {
159
+ service.apiKeyEnvVar = config.apiKeyEnvVar;
160
+ }
161
+ return service;
162
+ });
163
+ }
164
+ async function getMcpService(id) {
165
+ const services = await getMcpServices();
166
+ return services.find((service) => service.id === id);
167
+ }
168
+ function detectPlatform() {
169
+ const platform = process__default.platform;
170
+ const env = process__default.env;
171
+ const isWsl = !!(env.WSL_DISTRO_NAME || env.WSLENV || env.PATH && env.PATH.includes("/mnt/c/"));
172
+ const isTermux = !!(env.TERMUX_VERSION || env.PREFIX?.includes("com.termux"));
173
+ const isHeadless = !!(env.SSH_CLIENT || env.SSH_TTY || env.SSH_CONNECTION || !env.DISPLAY && platform === "linux");
174
+ const hasGui = (() => {
175
+ if (platform === "darwin")
176
+ return true;
177
+ if (platform === "win32")
178
+ return !isHeadless;
179
+ if (isWsl || isTermux)
180
+ return false;
181
+ if (platform === "linux")
182
+ return !!env.DISPLAY || !!env.WAYLAND_DISPLAY;
183
+ return false;
184
+ })();
185
+ let detectedPlatform;
186
+ if (platform === "darwin") {
187
+ detectedPlatform = "macos";
188
+ } else if (platform === "win32") {
189
+ detectedPlatform = "windows";
190
+ } else if (isWsl) {
191
+ detectedPlatform = "wsl";
192
+ } else if (isTermux) {
193
+ detectedPlatform = "termux";
194
+ } else if (platform === "linux") {
195
+ detectedPlatform = "linux";
196
+ } else {
197
+ detectedPlatform = "unknown";
198
+ }
199
+ return {
200
+ platform: detectedPlatform,
201
+ hasGui,
202
+ isHeadless
203
+ };
204
+ }
205
+ function isCommandAvailable(command) {
40
206
  try {
41
- if (!exists(configPath)) {
42
- return null;
207
+ execSync(`which ${command}`, { stdio: "ignore" });
208
+ return true;
209
+ } catch {
210
+ return false;
211
+ }
212
+ }
213
+ function isMcpServiceCompatible(serviceId) {
214
+ const config = MCP_SERVICE_CONFIGS.find((c) => c.id === serviceId);
215
+ if (!config) {
216
+ return { compatible: false, reason: "Service not found" };
217
+ }
218
+ const requirements = config.platformRequirements;
219
+ if (!requirements) {
220
+ return { compatible: true };
221
+ }
222
+ const { platform, hasGui } = detectPlatform();
223
+ if (requirements.platforms && requirements.platforms.length > 0) {
224
+ if (platform !== "unknown" && !requirements.platforms.includes(platform)) {
225
+ return {
226
+ compatible: false,
227
+ reason: `Not supported on ${platform}. Requires: ${requirements.platforms.join(", ")}`
228
+ };
229
+ }
230
+ }
231
+ if (requirements.requiresGui && !hasGui) {
232
+ return {
233
+ compatible: false,
234
+ reason: "Requires GUI environment (X11/Wayland/Desktop)"
235
+ };
236
+ }
237
+ if (requirements.requiredCommands) {
238
+ for (const cmd of requirements.requiredCommands) {
239
+ if (!isCommandAvailable(cmd)) {
240
+ return {
241
+ compatible: false,
242
+ reason: `Required command not found: ${cmd}`
243
+ };
244
+ }
43
245
  }
44
- return readJsonConfig(configPath) || null;
246
+ }
247
+ return { compatible: true };
248
+ }
249
+ async function getMcpServicesWithCompatibility() {
250
+ const allServices = await getMcpServices();
251
+ return allServices.map((service) => {
252
+ const { compatible, reason } = isMcpServiceCompatible(service.id);
253
+ return {
254
+ ...service,
255
+ compatible,
256
+ incompatibleReason: reason
257
+ };
258
+ });
259
+ }
260
+ const DEFAULT_MCP_TOOL_SEARCH_CONFIG = {
261
+ mcpAutoEnableThreshold: 10,
262
+ excludedServices: ["mcp-search", "context7"]
263
+ };
264
+ function getMcpToolSearchConfig() {
265
+ const env = process__default.env;
266
+ return {
267
+ mcpAutoEnableThreshold: env.MCP_AUTO_THRESHOLD || DEFAULT_MCP_TOOL_SEARCH_CONFIG.mcpAutoEnableThreshold,
268
+ dynamicServiceDiscovery: env.MCP_DYNAMIC_DISCOVERY !== "false",
269
+ listChangedNotifications: env.MCP_LIST_CHANGED !== "false",
270
+ excludedServices: env.MCP_EXCLUDED_SERVICES?.split(",").map((s) => s.trim()).filter(Boolean) || DEFAULT_MCP_TOOL_SEARCH_CONFIG.excludedServices
271
+ };
272
+ }
273
+ class DynamicMcpServiceRegistry {
274
+ _services = /* @__PURE__ */ new Map();
275
+ _listeners = /* @__PURE__ */ new Set();
276
+ _enabled = false;
277
+ /**
278
+ * Enable dynamic service discovery
279
+ */
280
+ enable() {
281
+ this._enabled = true;
282
+ }
283
+ /**
284
+ * Disable dynamic service discovery
285
+ */
286
+ disable() {
287
+ this._enabled = false;
288
+ }
289
+ /**
290
+ * Check if dynamic discovery is enabled
291
+ */
292
+ isEnabled() {
293
+ return this._enabled;
294
+ }
295
+ /**
296
+ * Add a service dynamically
297
+ */
298
+ addService(serviceId, config) {
299
+ if (!this._enabled) {
300
+ return false;
301
+ }
302
+ const isUpdate = this._services.has(serviceId);
303
+ this._services.set(serviceId, config);
304
+ this._notify({
305
+ type: isUpdate ? "updated" : "added",
306
+ serviceId,
307
+ timestamp: Date.now(),
308
+ config
309
+ });
310
+ return true;
311
+ }
312
+ /**
313
+ * Remove a service dynamically
314
+ */
315
+ removeService(serviceId) {
316
+ if (!this._enabled || !this._services.has(serviceId)) {
317
+ return false;
318
+ }
319
+ const config = this._services.get(serviceId);
320
+ this._services.delete(serviceId);
321
+ this._notify({
322
+ type: "removed",
323
+ serviceId,
324
+ timestamp: Date.now(),
325
+ config
326
+ });
327
+ return true;
328
+ }
329
+ /**
330
+ * Get a service configuration
331
+ */
332
+ getService(serviceId) {
333
+ return this._services.get(serviceId);
334
+ }
335
+ /**
336
+ * List all dynamically registered services
337
+ */
338
+ listServices() {
339
+ return new Map(this._services);
340
+ }
341
+ /**
342
+ * Subscribe to list change notifications
343
+ */
344
+ subscribe(listener) {
345
+ this._listeners.add(listener);
346
+ return () => this._listeners.delete(listener);
347
+ }
348
+ /**
349
+ * Notify all listeners of a change
350
+ */
351
+ _notify(notification) {
352
+ const toolSearchConfig = getMcpToolSearchConfig();
353
+ if (toolSearchConfig.listChangedNotifications) {
354
+ for (const listener of Array.from(this._listeners)) {
355
+ try {
356
+ listener(notification);
357
+ } catch (error) {
358
+ console.error("Error notifying MCP list change listener:", error);
359
+ }
360
+ }
361
+ }
362
+ }
363
+ }
364
+ const dynamicMcpRegistry = new DynamicMcpServiceRegistry();
365
+
366
+ function mergeArraysUnique(arr1, arr2) {
367
+ const combined = [...arr1 || [], ...arr2 || []];
368
+ return [...new Set(combined)];
369
+ }
370
+ function isPlainObject(value) {
371
+ return value !== null && typeof value === "object" && value.constructor === Object && Object.prototype.toString.call(value) === "[object Object]";
372
+ }
373
+ function deepMerge(target, source, options = {}) {
374
+ const { mergeArrays = false, arrayMergeStrategy = "replace" } = options;
375
+ const result = { ...target };
376
+ for (const key in source) {
377
+ const sourceValue = source[key];
378
+ const targetValue = result[key];
379
+ if (sourceValue === void 0) {
380
+ continue;
381
+ }
382
+ if (isPlainObject(sourceValue) && isPlainObject(targetValue)) {
383
+ result[key] = deepMerge(targetValue, sourceValue, options);
384
+ } else if (Array.isArray(sourceValue)) {
385
+ if (!mergeArrays || !Array.isArray(targetValue)) {
386
+ result[key] = sourceValue;
387
+ } else {
388
+ switch (arrayMergeStrategy) {
389
+ case "concat":
390
+ result[key] = [...targetValue, ...sourceValue];
391
+ break;
392
+ case "unique":
393
+ result[key] = mergeArraysUnique(targetValue, sourceValue);
394
+ break;
395
+ case "replace":
396
+ default:
397
+ result[key] = sourceValue;
398
+ break;
399
+ }
400
+ }
401
+ } else {
402
+ result[key] = sourceValue;
403
+ }
404
+ }
405
+ return result;
406
+ }
407
+ function deepClone(obj) {
408
+ if (obj === null || typeof obj !== "object") {
409
+ return obj;
410
+ }
411
+ if (obj instanceof Date) {
412
+ return new Date(obj.getTime());
413
+ }
414
+ if (Array.isArray(obj)) {
415
+ return obj.map((item) => deepClone(item));
416
+ }
417
+ if (isPlainObject(obj)) {
418
+ const cloned = {};
419
+ for (const key in obj) {
420
+ cloned[key] = deepClone(obj[key]);
421
+ }
422
+ return cloned;
423
+ }
424
+ return obj;
425
+ }
426
+
427
+ function readMcpConfig(codeTool) {
428
+ return readJsonConfig(resolveClaudeFamilySettingsTarget(codeTool).runtimeConfigFile);
429
+ }
430
+ function writeMcpConfig(config, codeTool) {
431
+ writeJsonConfig(resolveClaudeFamilySettingsTarget(codeTool).runtimeConfigFile, config);
432
+ }
433
+ function backupMcpConfig(codeTool) {
434
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
435
+ const backupBaseDir = join(target.configDir, target.runtimeBackupDirName);
436
+ return backupJsonConfig(target.runtimeConfigFile, backupBaseDir);
437
+ }
438
+ function mergeMcpServers(existing, newServers) {
439
+ const config = existing || { mcpServers: {} };
440
+ if (!config.mcpServers) {
441
+ config.mcpServers = {};
442
+ }
443
+ Object.assign(config.mcpServers, newServers);
444
+ return config;
445
+ }
446
+ function replaceMcpServers(existing, newServers) {
447
+ const config = existing ? { ...existing } : { mcpServers: {} };
448
+ config.mcpServers = { ...newServers };
449
+ return config;
450
+ }
451
+ function applyPlatformCommand(config) {
452
+ if (isWindows() && config.command) {
453
+ const mcpCmd = getMcpCommand(config.command);
454
+ if (mcpCmd[0] === "cmd") {
455
+ config.command = mcpCmd[0];
456
+ config.args = [...mcpCmd.slice(1), ...config.args || []];
457
+ }
458
+ }
459
+ }
460
+ function buildMcpServerConfig(baseConfig, apiKey, placeholder = "YOUR_EXA_API_KEY", envVarName) {
461
+ const config = deepClone(baseConfig);
462
+ applyPlatformCommand(config);
463
+ if (!apiKey) {
464
+ return config;
465
+ }
466
+ if (envVarName && config.env) {
467
+ config.env[envVarName] = apiKey;
468
+ return config;
469
+ }
470
+ if (config.args) {
471
+ config.args = config.args.map((arg) => arg.replace(placeholder, apiKey));
472
+ }
473
+ if (config.url) {
474
+ config.url = config.url.replace(placeholder, apiKey);
475
+ }
476
+ return config;
477
+ }
478
+ function fixWindowsMcpConfig(config) {
479
+ if (!isWindows() || !config.mcpServers) {
480
+ return config;
481
+ }
482
+ const fixed = { ...config };
483
+ for (const [, serverConfig] of Object.entries(fixed.mcpServers)) {
484
+ if (serverConfig && typeof serverConfig === "object" && "command" in serverConfig) {
485
+ applyPlatformCommand(serverConfig);
486
+ }
487
+ }
488
+ return fixed;
489
+ }
490
+ function addCompletedOnboarding(codeTool) {
491
+ try {
492
+ let config = readMcpConfig(codeTool);
493
+ if (!config) {
494
+ config = { mcpServers: {} };
495
+ }
496
+ if (config.hasCompletedOnboarding === true) {
497
+ return;
498
+ }
499
+ config.hasCompletedOnboarding = true;
500
+ writeMcpConfig(config, codeTool);
501
+ } catch (error) {
502
+ console.error("Failed to add onboarding flag", error);
503
+ throw error;
504
+ }
505
+ }
506
+ function ensureApiKeyApproved(config, apiKey) {
507
+ if (!apiKey || typeof apiKey !== "string" || apiKey.trim() === "") {
508
+ return config;
509
+ }
510
+ const truncatedApiKey = apiKey.substring(0, 20);
511
+ const updatedConfig = { ...config };
512
+ if (!updatedConfig.customApiKeyResponses) {
513
+ updatedConfig.customApiKeyResponses = {
514
+ approved: [],
515
+ rejected: []
516
+ };
517
+ }
518
+ if (!Array.isArray(updatedConfig.customApiKeyResponses.approved)) {
519
+ updatedConfig.customApiKeyResponses.approved = [];
520
+ }
521
+ if (!Array.isArray(updatedConfig.customApiKeyResponses.rejected)) {
522
+ updatedConfig.customApiKeyResponses.rejected = [];
523
+ }
524
+ const rejectedIndex = updatedConfig.customApiKeyResponses.rejected.indexOf(truncatedApiKey);
525
+ if (rejectedIndex > -1) {
526
+ updatedConfig.customApiKeyResponses.rejected.splice(rejectedIndex, 1);
527
+ }
528
+ if (!updatedConfig.customApiKeyResponses.approved.includes(truncatedApiKey)) {
529
+ updatedConfig.customApiKeyResponses.approved.push(truncatedApiKey);
530
+ }
531
+ return updatedConfig;
532
+ }
533
+ function manageApiKeyApproval(apiKey, codeTool) {
534
+ try {
535
+ let config = readMcpConfig(codeTool);
536
+ if (!config) {
537
+ config = { mcpServers: {} };
538
+ }
539
+ const updatedConfig = ensureApiKeyApproved(config, apiKey);
540
+ writeMcpConfig(updatedConfig, codeTool);
45
541
  } catch (error) {
46
- console.error(`Failed to read Claude config from ${configPath}:`, error);
47
- return null;
542
+ ensureI18nInitialized();
543
+ console.error(i18n.t("mcp:apiKeyApprovalFailed"), error);
48
544
  }
49
545
  }
50
- function writeClaudeConfig(config, options = {}, configPath = SETTINGS_FILE) {
546
+ function setPrimaryApiKey(codeTool) {
51
547
  try {
52
- ensureDir(dirname(configPath));
53
- normalizeClaudeFamilySettings(config);
54
- writeJsonConfig(configPath, config, {
55
- atomic: options.atomic !== false,
56
- pretty: true,
57
- backup: options.backup
58
- });
548
+ if (resolveClaudeFamilySettingsTarget(codeTool).codeTool !== "claude-code") {
549
+ return;
550
+ }
551
+ let config = readJsonConfig(CLAUDE_VSC_CONFIG_FILE);
552
+ if (!config) {
553
+ config = {};
554
+ }
555
+ config.primaryApiKey = "ccjk";
556
+ writeJsonConfig(CLAUDE_VSC_CONFIG_FILE, config);
59
557
  } catch (error) {
60
- console.error(`Failed to write Claude config to ${configPath}:`, error);
61
- throw new Error(`Failed to write Claude config: ${error instanceof Error ? error.message : String(error)}`);
558
+ ensureI18nInitialized();
559
+ console.error(i18n.t("mcp:primaryApiKeySetFailed"), error);
62
560
  }
63
561
  }
64
- function updateClaudeConfig(updates, options = {}, configPath = SETTINGS_FILE) {
65
- const existingConfig = readClaudeConfig(configPath) || {};
66
- const mergedConfig = deepMerge(existingConfig, updates, {
67
- mergeArrays: options.merge === "preserve",
68
- arrayMergeStrategy: "unique"
69
- });
70
- writeClaudeConfig(mergedConfig, options, configPath);
71
- return mergedConfig;
562
+ function getKnownMcpServiceIds() {
563
+ return new Set(MCP_SERVICE_CONFIGS.map((service) => service.id));
72
564
  }
565
+ function getMcpPermission(serviceId) {
566
+ return `mcp__${serviceId.toLowerCase().replace(/-/g, "_")}__*`;
567
+ }
568
+ function syncMcpPermissions(codeTool) {
569
+ const target = resolveClaudeFamilySettingsTarget(codeTool);
570
+ const mcpConfig = readMcpConfig(target.codeTool);
571
+ const knownServiceIds = getKnownMcpServiceIds();
572
+ const managedMcpServerIds = Object.keys(mcpConfig?.mcpServers || {}).filter((id) => knownServiceIds.has(id));
573
+ const settingsPath = target.settingsFile;
574
+ const settings = readJsonConfig(settingsPath) || {};
575
+ const allow = Array.isArray(settings.permissions?.allow) ? settings.permissions.allow.filter((permission) => typeof permission === "string") : [];
576
+ const managedMcpPermissions = new Set(
577
+ [...knownServiceIds].map(getMcpPermission)
578
+ );
579
+ const nonManagedPerms = allow.filter((permission) => !managedMcpPermissions.has(permission));
580
+ const mcpPerms = managedMcpServerIds.map(getMcpPermission);
581
+ settings.permissions = {
582
+ ...settings.permissions || {},
583
+ allow: [...nonManagedPerms, ...mcpPerms]
584
+ };
585
+ applyTrustedOperatorPermissions(settings);
586
+ normalizeClaudeFamilySettings(settings);
587
+ writeJsonConfig(settingsPath, settings);
588
+ }
589
+
590
+ const claudeConfig = {
591
+ __proto__: null,
592
+ addCompletedOnboarding: addCompletedOnboarding,
593
+ backupMcpConfig: backupMcpConfig,
594
+ buildMcpServerConfig: buildMcpServerConfig,
595
+ ensureApiKeyApproved: ensureApiKeyApproved,
596
+ fixWindowsMcpConfig: fixWindowsMcpConfig,
597
+ manageApiKeyApproval: manageApiKeyApproval,
598
+ mergeMcpServers: mergeMcpServers,
599
+ readMcpConfig: readMcpConfig,
600
+ replaceMcpServers: replaceMcpServers,
601
+ setPrimaryApiKey: setPrimaryApiKey,
602
+ syncMcpPermissions: syncMcpPermissions,
603
+ writeMcpConfig: writeMcpConfig
604
+ };
73
605
 
74
- export { readClaudeConfig, updateClaudeConfig, writeClaudeConfig };
606
+ export { MCP_SERVICE_CONFIGS as M, getMcpService as a, buildMcpServerConfig as b, backupMcpConfig as c, dynamicMcpRegistry as d, deepMerge as e, fixWindowsMcpConfig as f, getMcpServices as g, setPrimaryApiKey as h, addCompletedOnboarding as i, isMcpServiceCompatible as j, getMcpServicesWithCompatibility as k, replaceMcpServers as l, mergeMcpServers as m, claudeConfig as n, readMcpConfig as r, syncMcpPermissions as s, writeMcpConfig as w };