ccjk 9.4.13 → 9.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 (42) hide show
  1. package/dist/chunks/agent.mjs +2 -2
  2. package/dist/chunks/api-config-selector.mjs +2 -2
  3. package/dist/chunks/auto-updater.mjs +1 -1
  4. package/dist/chunks/ccjk-agents.mjs +38 -32
  5. package/dist/chunks/ccjk-all.mjs +16 -16
  6. package/dist/chunks/ccjk-config.mjs +4 -1
  7. package/dist/chunks/ccjk-hooks.mjs +14 -14
  8. package/dist/chunks/ccjk-setup.mjs +1 -1
  9. package/dist/chunks/ccjk-skills.mjs +15 -7
  10. package/dist/chunks/ccr.mjs +4 -4
  11. package/dist/chunks/check-updates.mjs +6 -6
  12. package/dist/chunks/claude-code-config-manager.mjs +1 -1
  13. package/dist/chunks/claude-code-incremental-manager.mjs +2 -2
  14. package/dist/chunks/claude-config.mjs +28 -1
  15. package/dist/chunks/cleanup-migration.mjs +20 -0
  16. package/dist/chunks/{smart-defaults.mjs → code-type-resolver.mjs} +84 -6
  17. package/dist/chunks/codex-config-switch.mjs +1 -1
  18. package/dist/chunks/codex-provider-manager.mjs +1 -1
  19. package/dist/chunks/codex.mjs +1 -1
  20. package/dist/chunks/config-switch.mjs +1 -1
  21. package/dist/chunks/config2.mjs +3 -3
  22. package/dist/chunks/features.mjs +2 -2
  23. package/dist/chunks/init.mjs +50 -7
  24. package/dist/chunks/installer.mjs +3 -3
  25. package/dist/chunks/mcp-gatekeeper.mjs +183 -0
  26. package/dist/chunks/mcp-market.mjs +1 -1
  27. package/dist/chunks/mcp-server.mjs +2 -2
  28. package/dist/chunks/mcp.mjs +2 -2
  29. package/dist/chunks/menu.mjs +7 -7
  30. package/dist/chunks/package.mjs +1 -1
  31. package/dist/chunks/prompts.mjs +1 -1
  32. package/dist/chunks/quick-setup.mjs +18 -7
  33. package/dist/chunks/skill.mjs +2 -2
  34. package/dist/{shared/ccjk.DHbrGcgg.mjs → chunks/toggle-prompt.mjs} +1 -1
  35. package/dist/chunks/tools.mjs +1 -1
  36. package/dist/chunks/uninstall.mjs +4 -2
  37. package/dist/chunks/update.mjs +2 -2
  38. package/dist/shared/{ccjk.Drzxa8gd.mjs → ccjk.BsXQugfY.mjs} +1 -1
  39. package/dist/shared/{ccjk.6uSMSDCL.mjs → ccjk.Bvoex4TZ.mjs} +1 -1
  40. package/dist/shared/{ccjk.CS0ybJCf.mjs → ccjk.D3OsxOco.mjs} +1 -1
  41. package/package.json +1 -1
  42. package/dist/shared/ccjk.CUdzQluX.mjs +0 -46
@@ -2,8 +2,8 @@ import ansis from 'ansis';
2
2
  import { existsSync, readFileSync, mkdirSync, writeFileSync, readdirSync } from 'node:fs';
3
3
  import { join } from 'pathe';
4
4
  import { CCJK_CONFIG_DIR } from './constants.mjs';
5
- import { w as writeAgentFile } from '../shared/ccjk.6uSMSDCL.mjs';
6
- import { g as getPluginManager } from '../shared/ccjk.Drzxa8gd.mjs';
5
+ import { w as writeAgentFile } from '../shared/ccjk.Bvoex4TZ.mjs';
6
+ import { g as getPluginManager } from '../shared/ccjk.BsXQugfY.mjs';
7
7
  import { homedir } from 'node:os';
8
8
  import './index2.mjs';
9
9
  import 'node:process';
@@ -23,9 +23,9 @@ import './config.mjs';
23
23
  import './claude-config.mjs';
24
24
  import './platform.mjs';
25
25
  import 'tinyexec';
26
- import '../shared/ccjk.CS0ybJCf.mjs';
26
+ import '../shared/ccjk.D3OsxOco.mjs';
27
27
  import '../shared/ccjk.BFQ7yr5S.mjs';
28
- import '../shared/ccjk.DHbrGcgg.mjs';
28
+ import './toggle-prompt.mjs';
29
29
  import 'inquirer-toggle';
30
30
  import './simple-config.mjs';
31
31
  import './codex.mjs';
@@ -3,7 +3,7 @@ import ora from 'ora';
3
3
  import { exec } from 'tinyexec';
4
4
  import { ensureI18nInitialized, i18n, format } from './index2.mjs';
5
5
  import { s as shouldUseSudoForGlobalInstall } from './platform.mjs';
6
- import { p as promptBoolean } from '../shared/ccjk.DHbrGcgg.mjs';
6
+ import { promptBoolean } from './toggle-prompt.mjs';
7
7
  import { checkClaudeCodeVersion, fixBrokenNpmSymlink, checkCcrVersion, handleDuplicateInstallations, checkCometixLineVersion } from './version-checker.mjs';
8
8
  import 'node:fs';
9
9
  import 'node:process';
@@ -5,7 +5,7 @@ import { i18n } from './index2.mjs';
5
5
  import { existsSync, readFileSync, writeFileSync, readdirSync } from 'node:fs';
6
6
  import { join, dirname } from 'pathe';
7
7
  import { CLAUDE_AGENTS_DIR } from './constants.mjs';
8
- import { w as writeAgentFile } from '../shared/ccjk.6uSMSDCL.mjs';
8
+ import { w as writeAgentFile } from '../shared/ccjk.Bvoex4TZ.mjs';
9
9
  import { fileURLToPath } from 'node:url';
10
10
  import { e as extractDisplayName, a as extractString } from '../shared/ccjk.AqnXPAzw.mjs';
11
11
  import 'tinyglobby';
@@ -165,46 +165,52 @@ async function ccjkAgents(options = {}) {
165
165
  }
166
166
  consola.log("");
167
167
  consola.info(isZh ? "\u{1F4CB} \u83B7\u53D6\u63A8\u8350\u4E2D..." : "\u{1F4CB} Getting recommendations...");
168
- let recommendations = [];
168
+ const allTemplates = await loadAgentTemplates();
169
+ let recommendations = allTemplates.filter(
170
+ (t) => t.skills.some(
171
+ (skill) => frameworks.includes(skill) || languages.includes(skill) || projectType.includes(skill)
172
+ ) || t.capabilities.some(
173
+ (cap) => frameworks.includes(cap) || languages.includes(cap) || projectType.includes(cap)
174
+ )
175
+ );
176
+ if (recommendations.length === 0) {
177
+ consola.warn(isZh ? "\u672A\u627E\u5230\u5408\u9002\u7684\u4EE3\u7406\uFF0C\u4F7F\u7528\u6240\u6709\u6A21\u677F" : "No suitable agents found, using all templates");
178
+ recommendations = allTemplates;
179
+ }
169
180
  try {
170
181
  const templatesClient = getTemplatesClient({ language: isZh ? "zh-CN" : "en" });
171
- const cloudAgents = await templatesClient.getSpecialistAgents();
182
+ const cloudAgents = await Promise.race([
183
+ templatesClient.getSpecialistAgents(),
184
+ new Promise((_, reject) => setTimeout(() => reject(new Error("timeout")), 3e3))
185
+ ]);
172
186
  const relevantAgents = cloudAgents.filter((agent) => {
173
187
  const tags = agent.tags || [];
174
188
  const category = agent.category || "";
175
189
  const compatibility = agent.compatibility || {};
176
190
  return frameworks.some((fw) => tags.includes(fw.toLowerCase()) || category.includes(fw.toLowerCase())) || languages.some((lang) => tags.includes(lang.toLowerCase()) || (compatibility.languages || []).includes(lang.toLowerCase())) || tags.includes(projectType.toLowerCase());
177
191
  });
178
- recommendations = (relevantAgents.length > 0 ? relevantAgents : cloudAgents.slice(0, 10)).map((agent) => ({
179
- id: agent.id,
180
- name: agent.name_zh_cn && isZh ? agent.name_zh_cn : agent.name_en,
181
- description: agent.description_zh_cn && isZh ? agent.description_zh_cn : agent.description_en || "",
182
- skills: agent.tags || [],
183
- mcpServers: [],
184
- persona: agent.name_en,
185
- capabilities: [],
186
- confidence: agent.rating_average / 5 || 0.8,
187
- reason: `${isZh ? "\u63A8\u8350\u7406\u7531" : "Recommended"}: ${agent.category}`
188
- }));
189
- if (recommendations.length > 0) {
190
- consola.success(isZh ? `\u4ECE\u4E91\u7AEF\u83B7\u53D6 ${recommendations.length} \u4E2A\u4E13\u4E1A\u4EE3\u7406` : `Fetched ${recommendations.length} specialist agents from cloud`);
192
+ const localAgentNames = new Set(recommendations.map((a) => (typeof a.name === "string" ? a.name : "").toLowerCase()));
193
+ const cloudToAdd = relevantAgents.length > 0 ? relevantAgents : cloudAgents.slice(0, 10);
194
+ for (const agent of cloudToAdd) {
195
+ const agentName = (agent.name_zh_cn && isZh ? agent.name_zh_cn : agent.name_en).toLowerCase();
196
+ if (localAgentNames.has(agentName)) {
197
+ continue;
198
+ }
199
+ recommendations.push({
200
+ name: agent.name_zh_cn && isZh ? agent.name_zh_cn : agent.name_en,
201
+ description: agent.description_zh_cn && isZh ? agent.description_zh_cn : agent.description_en || "",
202
+ skills: agent.tags || [],
203
+ mcpServers: [],
204
+ persona: agent.name_en,
205
+ capabilities: [],
206
+ confidence: agent.rating_average / 5 || 0.8,
207
+ reason: `${isZh ? "\u63A8\u8350\u7406\u7531" : "Recommended"}: ${agent.category}`
208
+ });
191
209
  }
192
- } catch (_error) {
193
- consola.warn(isZh ? "\u4E91\u7AEF\u83B7\u53D6\u5931\u8D25\uFF0C\u4F7F\u7528\u672C\u5730\u6A21\u677F" : "Cloud fetch failed, using local templates");
194
- }
195
- if (!recommendations || recommendations.length === 0) {
196
- const templates = await loadAgentTemplates();
197
- recommendations = templates.filter(
198
- (t) => t.skills.some(
199
- (skill) => frameworks.includes(skill) || languages.includes(skill) || projectType.includes(skill)
200
- ) || t.capabilities.some(
201
- (cap) => frameworks.includes(cap) || languages.includes(cap) || projectType.includes(cap)
202
- )
203
- );
204
- }
205
- if (recommendations.length === 0) {
206
- consola.warn(isZh ? "\u672A\u627E\u5230\u5408\u9002\u7684\u4EE3\u7406\uFF0C\u4F7F\u7528\u6240\u6709\u6A21\u677F" : "No suitable agents found, using all templates");
207
- recommendations = await loadAgentTemplates();
210
+ if (cloudToAdd.length > 0) {
211
+ consola.success(isZh ? `\u4ECE\u4E91\u7AEF\u83B7\u53D6 ${cloudToAdd.length} \u4E2A\u4E13\u4E1A\u4EE3\u7406` : `Fetched ${cloudToAdd.length} specialist agents from cloud`);
212
+ }
213
+ } catch {
208
214
  }
209
215
  consola.log("");
210
216
  consola.info(`${isZh ? "\u627E\u5230" : "Found"} ${recommendations.length} ${isZh ? "\u4E2A\u63A8\u8350\u4EE3\u7406" : "recommended agent(s)"}:`);
@@ -21,7 +21,7 @@ import 'tinyglobby';
21
21
  import 'smol-toml';
22
22
  import './constants.mjs';
23
23
  import 'node:os';
24
- import '../shared/ccjk.6uSMSDCL.mjs';
24
+ import '../shared/ccjk.Bvoex4TZ.mjs';
25
25
  import 'node:perf_hooks';
26
26
  import 'inquirer';
27
27
  import 'node:child_process';
@@ -976,7 +976,7 @@ class FallbackCloudClient {
976
976
  id: "typescript-workflow",
977
977
  name: { "en": "TypeScript Workflow", "zh-CN": "TypeScript \u5DE5\u4F5C\u6D41" },
978
978
  description: { "en": "Enhanced TypeScript support", "zh-CN": "\u589E\u5F3A\u7684 TypeScript \u652F\u6301" },
979
- category: "workflow",
979
+ category: "skill",
980
980
  relevanceScore: 0.9,
981
981
  installCommand: "ccjk config switch typescript",
982
982
  tags: ["typescript", "type-checking"]
@@ -987,7 +987,7 @@ class FallbackCloudClient {
987
987
  id: "react-workflow",
988
988
  name: { "en": "React Workflow", "zh-CN": "React \u5DE5\u4F5C\u6D41" },
989
989
  description: { "en": "React development tools", "zh-CN": "React \u5F00\u53D1\u5DE5\u5177" },
990
- category: "workflow",
990
+ category: "skill",
991
991
  relevanceScore: 0.95,
992
992
  installCommand: "ccjk config switch react",
993
993
  tags: ["react", "jsx", "frontend"]
@@ -998,7 +998,7 @@ class FallbackCloudClient {
998
998
  id: "nodejs-workflow",
999
999
  name: { "en": "Node.js Workflow", "zh-CN": "Node.js \u5DE5\u4F5C\u6D41" },
1000
1000
  description: { "en": "Node.js development tools", "zh-CN": "Node.js \u5F00\u53D1\u5DE5\u5177" },
1001
- category: "workflow",
1001
+ category: "skill",
1002
1002
  relevanceScore: 0.9,
1003
1003
  installCommand: "ccjk config switch nodejs",
1004
1004
  tags: ["nodejs", "backend", "server"]
@@ -1009,7 +1009,7 @@ class FallbackCloudClient {
1009
1009
  id: "git-workflow",
1010
1010
  name: { "en": "Git Workflow", "zh-CN": "Git \u5DE5\u4F5C\u6D41" },
1011
1011
  description: { "en": "Git best practices", "zh-CN": "Git \u6700\u4F73\u5B9E\u8DF5" },
1012
- category: "workflow",
1012
+ category: "skill",
1013
1013
  relevanceScore: 0.8,
1014
1014
  installCommand: "ccjk config switch git",
1015
1015
  tags: ["git", "vcs"]
@@ -1256,10 +1256,10 @@ class CloudSetupOrchestrator {
1256
1256
  const response = await this.cloudClient.analyzeProject(request);
1257
1257
  const fingerprint = this.generateProjectFingerprint(analysis);
1258
1258
  const recommendations = {
1259
- skills: response.recommendations.filter((r) => r.category === "workflow"),
1259
+ skills: response.recommendations.filter((r) => r.category === "skill"),
1260
1260
  mcpServices: response.recommendations.filter((r) => r.category === "mcp"),
1261
1261
  agents: response.recommendations.filter((r) => r.category === "agent"),
1262
- hooks: response.recommendations.filter((r) => r.category === "tool"),
1262
+ hooks: response.recommendations.filter((r) => r.category === "hook"),
1263
1263
  confidence: this.calculateConfidence(response.recommendations),
1264
1264
  fingerprint,
1265
1265
  insights: this.extractInsights(response)
@@ -1328,7 +1328,7 @@ class CloudSetupOrchestrator {
1328
1328
  id: "ts-best-practices",
1329
1329
  name: { "en": "TypeScript Best Practices", "zh-CN": "TypeScript \u6700\u4F73\u5B9E\u8DF5" },
1330
1330
  description: { "en": "Essential for TypeScript 5.3+ strict mode", "zh-CN": "TypeScript 5.3+ \u4E25\u683C\u6A21\u5F0F\u5FC5\u5907" },
1331
- category: "workflow",
1331
+ category: "skill",
1332
1332
  relevanceScore: 0.98,
1333
1333
  tags: ["typescript", "type-checking"]
1334
1334
  });
@@ -1338,7 +1338,7 @@ class CloudSetupOrchestrator {
1338
1338
  id: "react-design-patterns",
1339
1339
  name: { "en": "React Design Patterns", "zh-CN": "React \u8BBE\u8BA1\u6A21\u5F0F" },
1340
1340
  description: { "en": "React 18+ hooks and composition", "zh-CN": "React 18+ Hooks \u548C\u7EC4\u5408" },
1341
- category: "workflow",
1341
+ category: "skill",
1342
1342
  relevanceScore: 0.95,
1343
1343
  tags: ["react", "hooks", "frontend"]
1344
1344
  });
@@ -1348,7 +1348,7 @@ class CloudSetupOrchestrator {
1348
1348
  id: "nextjs-optimization",
1349
1349
  name: { "en": "Next.js Optimization", "zh-CN": "Next.js \u4F18\u5316" },
1350
1350
  description: { "en": "App router and server components", "zh-CN": "App Router \u548C\u670D\u52A1\u5668\u7EC4\u4EF6" },
1351
- category: "workflow",
1351
+ category: "skill",
1352
1352
  relevanceScore: 0.92,
1353
1353
  tags: ["nextjs", "ssr", "performance"]
1354
1354
  });
@@ -1358,7 +1358,7 @@ class CloudSetupOrchestrator {
1358
1358
  id: "vue-design-patterns",
1359
1359
  name: { "en": "Vue Design Patterns", "zh-CN": "Vue \u8BBE\u8BA1\u6A21\u5F0F" },
1360
1360
  description: { "en": "Vue 3 Composition API patterns", "zh-CN": "Vue 3 \u7EC4\u5408\u5F0F API \u6A21\u5F0F" },
1361
- category: "workflow",
1361
+ category: "skill",
1362
1362
  relevanceScore: 0.95,
1363
1363
  tags: ["vue", "composition-api", "frontend"]
1364
1364
  });
@@ -1368,7 +1368,7 @@ class CloudSetupOrchestrator {
1368
1368
  id: "nodejs-workflow",
1369
1369
  name: { "en": "Node.js Workflow", "zh-CN": "Node.js \u5DE5\u4F5C\u6D41" },
1370
1370
  description: { "en": "Node.js development tools", "zh-CN": "Node.js \u5F00\u53D1\u5DE5\u5177" },
1371
- category: "workflow",
1371
+ category: "skill",
1372
1372
  relevanceScore: 0.9,
1373
1373
  tags: ["nodejs", "backend"]
1374
1374
  });
@@ -1378,7 +1378,7 @@ class CloudSetupOrchestrator {
1378
1378
  id: "nestjs-workflow",
1379
1379
  name: { "en": "NestJS Workflow", "zh-CN": "NestJS \u5DE5\u4F5C\u6D41" },
1380
1380
  description: { "en": "NestJS backend development", "zh-CN": "NestJS \u540E\u7AEF\u5F00\u53D1" },
1381
- category: "workflow",
1381
+ category: "skill",
1382
1382
  relevanceScore: 0.92,
1383
1383
  tags: ["nestjs", "backend", "typescript"]
1384
1384
  });
@@ -1388,17 +1388,17 @@ class CloudSetupOrchestrator {
1388
1388
  id: "python-workflow",
1389
1389
  name: { "en": "Python Workflow", "zh-CN": "Python \u5DE5\u4F5C\u6D41" },
1390
1390
  description: { "en": "Python development best practices", "zh-CN": "Python \u5F00\u53D1\u6700\u4F73\u5B9E\u8DF5" },
1391
- category: "workflow",
1391
+ category: "skill",
1392
1392
  relevanceScore: 0.88,
1393
1393
  tags: ["python", "backend"]
1394
1394
  });
1395
1395
  }
1396
1396
  const fingerprint = this.generateProjectFingerprint(analysis);
1397
1397
  return {
1398
- skills: recommendations.filter((r) => r.category === "workflow"),
1398
+ skills: recommendations.filter((r) => r.category === "skill"),
1399
1399
  mcpServices: recommendations.filter((r) => r.category === "mcp"),
1400
1400
  agents: recommendations.filter((r) => r.category === "agent"),
1401
- hooks: recommendations.filter((r) => r.category === "tool"),
1401
+ hooks: recommendations.filter((r) => r.category === "hook"),
1402
1402
  confidence: 0.7,
1403
1403
  // Local fallback has lower confidence
1404
1404
  fingerprint,
@@ -254,8 +254,11 @@ function updateZcfConfig(updates) {
254
254
  };
255
255
  writeZcfConfig(newConfig);
256
256
  }
257
+ async function saveZcfConfig(config) {
258
+ writeZcfConfig(config);
259
+ }
257
260
  function readDefaultTomlConfig() {
258
261
  return readTomlConfig(ZCF_CONFIG_FILE);
259
262
  }
260
263
 
261
- export { createDefaultTomlConfig, migrateFromJsonConfig, migrateZcfConfigIfNeeded, readDefaultTomlConfig, readTomlConfig, readZcfConfig, readZcfConfigAsync, updateTomlConfig, updateZcfConfig, writeTomlConfig, writeZcfConfig };
264
+ export { createDefaultTomlConfig, migrateFromJsonConfig, migrateZcfConfigIfNeeded, readDefaultTomlConfig, readTomlConfig, readZcfConfig, readZcfConfigAsync, saveZcfConfig, updateTomlConfig, updateZcfConfig, writeTomlConfig, writeZcfConfig };
@@ -824,11 +824,17 @@ async function ccjkHooks(options = {}) {
824
824
  framework
825
825
  }));
826
826
  }
827
- let recommendedHooks = [];
828
827
  const isZh = i18n.language === "zh-CN";
828
+ const allHookTemplates = await loadHookTemplates();
829
+ let recommendedHooks = allHookTemplates.filter(
830
+ (template) => template.projectTypes.includes(projectType)
831
+ );
829
832
  try {
830
833
  const templatesClient = getTemplatesClient({ language: isZh ? "zh-CN" : "en" });
831
- const cloudHooks = await templatesClient.getHooks();
834
+ const cloudHooks = await Promise.race([
835
+ templatesClient.getHooks(),
836
+ new Promise((_, reject) => setTimeout(() => reject(new Error("timeout")), 3e3))
837
+ ]);
832
838
  if (cloudHooks.length > 0) {
833
839
  consola.success(isZh ? `\u4ECE\u4E91\u7AEF\u83B7\u53D6 ${cloudHooks.length} \u4E2A\u94A9\u5B50` : `Fetched ${cloudHooks.length} hooks from cloud`);
834
840
  const languages = projectInfo.languages?.map((l) => l.language.toLowerCase()) || [];
@@ -839,7 +845,12 @@ async function ccjkHooks(options = {}) {
839
845
  const compatibility = hook.compatibility || {};
840
846
  return tags.some((tag) => languages.includes(tag) || frameworks.includes(tag) || projectType.includes(tag)) || (compatibility.languages || []).some((lang) => languages.includes(lang.toLowerCase())) || (compatibility.frameworks || []).some((fw) => frameworks.includes(fw.toLowerCase())) || category === "pre-commit" || category === "commit-msg";
841
847
  });
848
+ const localHookNames = new Set(recommendedHooks.map((h) => h.name.toLowerCase()));
842
849
  for (const hook of relevantHooks.length > 0 ? relevantHooks : cloudHooks.slice(0, 10)) {
850
+ const hookName = (hook.name_zh_cn && isZh ? hook.name_zh_cn : hook.name_en).toLowerCase();
851
+ if (localHookNames.has(hookName)) {
852
+ continue;
853
+ }
843
854
  const hookConfig = {
844
855
  name: hook.name_zh_cn && isZh ? hook.name_zh_cn : hook.name_en,
845
856
  description: hook.description_zh_cn && isZh ? hook.description_zh_cn : hook.description_en || "",
@@ -861,18 +872,7 @@ async function ccjkHooks(options = {}) {
861
872
  recommendedHooks.push(hookConfig);
862
873
  }
863
874
  }
864
- } catch (_error) {
865
- consola.warn(isZh ? "\u4E91\u7AEF\u83B7\u53D6\u5931\u8D25\uFF0C\u4F7F\u7528\u672C\u5730\u6A21\u677F" : "Cloud fetch failed, using local templates");
866
- const templates = await loadHookTemplates();
867
- recommendedHooks = templates.filter(
868
- (template) => template.projectTypes.includes(projectType)
869
- );
870
- }
871
- if (recommendedHooks.length === 0) {
872
- const templates = await loadHookTemplates();
873
- recommendedHooks = templates.filter(
874
- (template) => template.projectTypes.includes(projectType)
875
- );
875
+ } catch {
876
876
  }
877
877
  const filteredHooks = filterHooks(recommendedHooks, options);
878
878
  if (filteredHooks.length === 0) {
@@ -19,7 +19,7 @@ import 'i18next';
19
19
  import 'i18next-fs-backend';
20
20
  import './constants.mjs';
21
21
  import 'node:os';
22
- import '../shared/ccjk.6uSMSDCL.mjs';
22
+ import '../shared/ccjk.Bvoex4TZ.mjs';
23
23
  import '../shared/ccjk.AqnXPAzw.mjs';
24
24
  import 'inquirer';
25
25
  import 'node:child_process';
@@ -151,12 +151,18 @@ async function getRecommendedSkills(analysis, options) {
151
151
  const languages = analysis.languages.map((l) => l.language.toLowerCase());
152
152
  const frameworks = analysis.frameworks.map((f) => f.name.toLowerCase());
153
153
  const projectType = analysis.projectType?.toLowerCase() || "";
154
+ const localSkills = await getLocalRecommendations(analysis);
155
+ recommendations.push(...localSkills);
154
156
  try {
155
157
  const templatesClient = getTemplatesClient({ language: isZh ? "zh-CN" : "en" });
156
158
  logger.info("Fetching cloud recommendations...");
157
- const cloudSkills = await templatesClient.getSkills();
159
+ const cloudSkills = await Promise.race([
160
+ templatesClient.getSkills(),
161
+ new Promise((_, reject) => setTimeout(() => reject(new Error("timeout")), 3e3))
162
+ ]);
158
163
  if (cloudSkills.length > 0) {
159
164
  logger.success(isZh ? `\u4ECE\u4E91\u7AEF\u83B7\u53D6 ${cloudSkills.length} \u4E2A\u6280\u80FD` : `Fetched ${cloudSkills.length} skills from cloud`);
165
+ const localSkillIds = new Set(recommendations.map((s) => s.id));
160
166
  const relevantSkills = cloudSkills.filter((skill) => {
161
167
  const tags = skill.tags || [];
162
168
  const _category = skill.category || "";
@@ -164,8 +170,12 @@ async function getRecommendedSkills(analysis, options) {
164
170
  return tags.some((tag) => languages.includes(tag) || frameworks.includes(tag) || projectType.includes(tag)) || (compatibility.languages || []).some((lang) => languages.includes(lang.toLowerCase())) || (compatibility.frameworks || []).some((fw) => frameworks.includes(fw.toLowerCase()));
165
171
  });
166
172
  for (const skill of relevantSkills.length > 0 ? relevantSkills : cloudSkills.slice(0, 10)) {
173
+ const skillId = skill.id || skill.name_en.toLowerCase().replace(/\s+/g, "-");
174
+ if (localSkillIds.has(skillId)) {
175
+ continue;
176
+ }
167
177
  recommendations.push({
168
- id: skill.id || skill.name_en.toLowerCase().replace(/\s+/g, "-"),
178
+ id: skillId,
169
179
  name: {
170
180
  "en": skill.name_en,
171
181
  "zh-CN": skill.name_zh_cn || skill.name_en
@@ -178,17 +188,15 @@ async function getRecommendedSkills(analysis, options) {
178
188
  priority: skill.rating_average ? skill.rating_average * 2 : 7,
179
189
  source: "cloud",
180
190
  tags: skill.tags || [],
181
- templatePath: skill.id || skill.name_en.toLowerCase().replace(/\s+/g, "-"),
191
+ templatePath: skillId,
182
192
  // Store template content from V8 API response
183
193
  templateContent: skill.template_content || skill.content
184
194
  });
185
195
  }
186
196
  }
187
- } catch (error) {
188
- logger.warn("Cloud recommendations failed, using local fallback:", error);
197
+ } catch {
198
+ logger.debug("Cloud recommendations unavailable, using local templates only");
189
199
  }
190
- const localSkills = await getLocalRecommendations(analysis);
191
- recommendations.push(...localSkills);
192
200
  const seen = /* @__PURE__ */ new Set();
193
201
  const unique = [];
194
202
  for (const skill of recommendations) {
@@ -27,7 +27,7 @@ import 'node:fs/promises';
27
27
  import './platform.mjs';
28
28
  import 'tinyexec';
29
29
  import './config.mjs';
30
- import '../shared/ccjk.DHbrGcgg.mjs';
30
+ import './toggle-prompt.mjs';
31
31
  import 'inquirer-toggle';
32
32
  import '../shared/ccjk.BaEp4UHQ.mjs';
33
33
  import './auto-updater.mjs';
@@ -37,9 +37,9 @@ import 'node:path';
37
37
  import 'semver';
38
38
  import './ccjk-config.mjs';
39
39
  import 'smol-toml';
40
- import '../shared/ccjk.CUdzQluX.mjs';
40
+ import './code-type-resolver.mjs';
41
41
  import './features.mjs';
42
- import '../shared/ccjk.CS0ybJCf.mjs';
42
+ import '../shared/ccjk.D3OsxOco.mjs';
43
43
  import '../shared/ccjk.BFQ7yr5S.mjs';
44
44
  import './simple-config.mjs';
45
45
  import './api-config-selector.mjs';
@@ -52,7 +52,7 @@ import 'consola';
52
52
  import '../shared/ccjk.BNwRnWYx.mjs';
53
53
  import 'tinyglobby';
54
54
  import 'ofetch';
55
- import '../shared/ccjk.6uSMSDCL.mjs';
55
+ import '../shared/ccjk.Bvoex4TZ.mjs';
56
56
  import '../shared/ccjk.AqnXPAzw.mjs';
57
57
  import './ccjk-mcp.mjs';
58
58
  import './ccjk-skills.mjs';
@@ -1,7 +1,7 @@
1
1
  import process__default from 'node:process';
2
2
  import ansis from 'ansis';
3
3
  import { ensureI18nInitialized, i18n } from './index2.mjs';
4
- import { r as resolveCodeType } from '../shared/ccjk.CUdzQluX.mjs';
4
+ import { r as resolveCodeType } from './code-type-resolver.mjs';
5
5
  import { checkAndUpdateTools } from './auto-updater.mjs';
6
6
  import { c as runCodexUpdate } from './codex.mjs';
7
7
  import 'node:fs';
@@ -9,8 +9,11 @@ import 'node:url';
9
9
  import 'i18next';
10
10
  import 'i18next-fs-backend';
11
11
  import 'pathe';
12
- import './constants.mjs';
12
+ import 'node:child_process';
13
13
  import 'node:os';
14
+ import './platform.mjs';
15
+ import 'tinyexec';
16
+ import './constants.mjs';
14
17
  import './ccjk-config.mjs';
15
18
  import 'smol-toml';
16
19
  import './fs-operations.mjs';
@@ -19,12 +22,9 @@ import 'node:fs/promises';
19
22
  import './json-config.mjs';
20
23
  import 'dayjs';
21
24
  import 'ora';
22
- import 'tinyexec';
23
- import './platform.mjs';
24
- import '../shared/ccjk.DHbrGcgg.mjs';
25
+ import './toggle-prompt.mjs';
25
26
  import 'inquirer-toggle';
26
27
  import './version-checker.mjs';
27
- import 'node:child_process';
28
28
  import 'node:path';
29
29
  import 'node:util';
30
30
  import 'semver';
@@ -242,7 +242,7 @@ class ClaudeCodeConfigManager {
242
242
  clearModelEnv(settings.env);
243
243
  }
244
244
  writeJsonConfig(SETTINGS_FILE, settings);
245
- const { setPrimaryApiKey, addCompletedOnboarding } = await import('./claude-config.mjs').then(function (n) { return n.e; });
245
+ const { setPrimaryApiKey, addCompletedOnboarding } = await import('./claude-config.mjs').then(function (n) { return n.h; });
246
246
  setPrimaryApiKey();
247
247
  addCompletedOnboarding();
248
248
  if (shouldRestartCcr) {
@@ -3,8 +3,8 @@ import inquirer from 'inquirer';
3
3
  import { ensureI18nInitialized, i18n } from './index2.mjs';
4
4
  import { ClaudeCodeConfigManager } from './claude-code-config-manager.mjs';
5
5
  import { a as addNumbersToChoices } from '../shared/ccjk.BFQ7yr5S.mjs';
6
- import { p as promptBoolean } from '../shared/ccjk.DHbrGcgg.mjs';
7
- import { v as validateApiKey } from '../shared/ccjk.CS0ybJCf.mjs';
6
+ import { promptBoolean } from './toggle-prompt.mjs';
7
+ import { v as validateApiKey } from '../shared/ccjk.D3OsxOco.mjs';
8
8
  import 'node:fs';
9
9
  import 'node:process';
10
10
  import 'node:url';
@@ -1,3 +1,4 @@
1
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
1
2
  import { join } from 'pathe';
2
3
  import { CLAUDE_VSC_CONFIG_FILE, CLAUDE_DIR, ClAUDE_CONFIG_FILE } from './constants.mjs';
3
4
  import { ensureI18nInitialized, i18n } from './index2.mjs';
@@ -83,6 +84,11 @@ function mergeMcpServers(existing, newServers) {
83
84
  Object.assign(config.mcpServers, newServers);
84
85
  return config;
85
86
  }
87
+ function replaceMcpServers(existing, newServers) {
88
+ const config = existing ? { ...existing } : { mcpServers: {} };
89
+ config.mcpServers = { ...newServers };
90
+ return config;
91
+ }
86
92
  function applyPlatformCommand(config) {
87
93
  if (isWindows() && config.command) {
88
94
  const mcpCmd = getMcpCommand(config.command);
@@ -191,6 +197,25 @@ function setPrimaryApiKey() {
191
197
  console.error(i18n.t("mcp:primaryApiKeySetFailed"), error);
192
198
  }
193
199
  }
200
+ function syncMcpPermissions() {
201
+ const mcpConfig = readMcpConfig();
202
+ const mcpServerIds = Object.keys(mcpConfig?.mcpServers || {});
203
+ const settingsPath = join(CLAUDE_DIR, "settings.json");
204
+ if (!existsSync(settingsPath))
205
+ return;
206
+ try {
207
+ const settings = JSON.parse(readFileSync(settingsPath, "utf-8"));
208
+ if (!settings.permissions?.allow)
209
+ return;
210
+ const nonMcpPerms = settings.permissions.allow.filter(
211
+ (p) => !p.startsWith("mcp__")
212
+ );
213
+ const mcpPerms = mcpServerIds.map((id) => `mcp__${id}`);
214
+ settings.permissions.allow = [...nonMcpPerms, ...mcpPerms];
215
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2), "utf-8");
216
+ } catch {
217
+ }
218
+ }
194
219
 
195
220
  const claudeConfig = {
196
221
  __proto__: null,
@@ -202,8 +227,10 @@ const claudeConfig = {
202
227
  manageApiKeyApproval: manageApiKeyApproval,
203
228
  mergeMcpServers: mergeMcpServers,
204
229
  readMcpConfig: readMcpConfig,
230
+ replaceMcpServers: replaceMcpServers,
205
231
  setPrimaryApiKey: setPrimaryApiKey,
232
+ syncMcpPermissions: syncMcpPermissions,
206
233
  writeMcpConfig: writeMcpConfig
207
234
  };
208
235
 
209
- export { addCompletedOnboarding as a, backupMcpConfig as b, buildMcpServerConfig as c, deepMerge as d, claudeConfig as e, fixWindowsMcpConfig as f, mergeMcpServers as m, readMcpConfig as r, setPrimaryApiKey as s, writeMcpConfig as w };
236
+ export { addCompletedOnboarding as a, backupMcpConfig as b, buildMcpServerConfig as c, deepMerge as d, replaceMcpServers as e, fixWindowsMcpConfig as f, syncMcpPermissions as g, claudeConfig as h, mergeMcpServers as m, readMcpConfig as r, setPrimaryApiKey as s, writeMcpConfig as w };
@@ -0,0 +1,20 @@
1
+ import { existsSync, rmSync } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ import { join } from 'pathe';
4
+
5
+ function cleanupZcfNamespace() {
6
+ const removed = [];
7
+ const dirs = [
8
+ join(homedir(), ".claude", "commands", "zcf"),
9
+ join(homedir(), ".claude", "agents", "zcf")
10
+ ];
11
+ for (const dir of dirs) {
12
+ if (existsSync(dir)) {
13
+ rmSync(dir, { recursive: true, force: true });
14
+ removed.push(dir);
15
+ }
16
+ }
17
+ return { removed };
18
+ }
19
+
20
+ export { cleanupZcfNamespace };