ccg-workflow 1.7.91 → 1.7.92

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import cac from 'cac';
3
3
  import ansis from 'ansis';
4
- import { z as diagnoseMcpConfig, A as isWindows, B as readClaudeCodeConfig, C as fixWindowsMcpConfig, D as writeClaudeCodeConfig, r as readCcgConfig, b as initI18n, a as i18n, s as showMainMenu, i as init, E as configMcp, F as version } from './shared/ccg-workflow.tdovFwH0.mjs';
4
+ import { z as diagnoseMcpConfig, A as isWindows, B as readClaudeCodeConfig, C as fixWindowsMcpConfig, D as writeClaudeCodeConfig, r as readCcgConfig, b as initI18n, a as i18n, s as showMainMenu, i as init, E as configMcp, F as version } from './shared/ccg-workflow.OR5BVUam.mjs';
5
5
  import 'inquirer';
6
6
  import 'node:child_process';
7
7
  import 'node:util';
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { c as changeLanguage, x as checkForUpdates, y as compareVersions, d as createDefaultConfig, e as createDefaultRouting, g as getCcgDir, f as getConfigPath, t as getCurrentVersion, v as getLatestVersion, j as getWorkflowById, h as getWorkflowConfigs, a as i18n, i as init, b as initI18n, l as installAceTool, m as installAceToolRs, k as installWorkflows, p as migrateToV1_4_0, q as needsMigration, r as readCcgConfig, s as showMainMenu, o as uninstallAceTool, n as uninstallWorkflows, u as update, w as writeCcgConfig } from './shared/ccg-workflow.tdovFwH0.mjs';
1
+ export { c as changeLanguage, x as checkForUpdates, y as compareVersions, d as createDefaultConfig, e as createDefaultRouting, g as getCcgDir, f as getConfigPath, t as getCurrentVersion, v as getLatestVersion, j as getWorkflowById, h as getWorkflowConfigs, a as i18n, i as init, b as initI18n, l as installAceTool, m as installAceToolRs, k as installWorkflows, p as migrateToV1_4_0, q as needsMigration, r as readCcgConfig, s as showMainMenu, o as uninstallAceTool, n as uninstallWorkflows, u as update, w as writeCcgConfig } from './shared/ccg-workflow.OR5BVUam.mjs';
2
2
  import 'ansis';
3
3
  import 'inquirer';
4
4
  import 'node:child_process';
@@ -10,7 +10,7 @@ import { parse, stringify } from 'smol-toml';
10
10
  import i18next from 'i18next';
11
11
  import ora from 'ora';
12
12
 
13
- const version = "1.7.91";
13
+ const version = "1.7.92";
14
14
 
15
15
  function cmd(id, order, category, name, nameEn, description, descriptionEn, cmdOverride) {
16
16
  return {
@@ -554,51 +554,30 @@ async function syncMcpToGemini() {
554
554
  }
555
555
  }
556
556
 
557
- const FAST_CONTEXT_PROMPT = `# fast-context MCP \u5DE5\u5177\u4F7F\u7528\u6307\u5357
557
+ const FAST_CONTEXT_PROMPT_PRIMARY = `# fast-context MCP \u5DE5\u5177\u4F7F\u7528\u6307\u5357
558
558
 
559
559
  ## \u6838\u5FC3\u539F\u5219
560
560
 
561
- **\u4EFB\u4F55\u9700\u8981\u7406\u89E3\u4EE3\u7801\u4E0A\u4E0B\u6587\u3001\u63A2\u7D22\u6027\u641C\u7D22\u3001\u6216\u81EA\u7136\u8BED\u8A00\u5B9A\u4F4D\u4EE3\u7801\u7684\u573A\u666F\uFF0C\u4F18\u5148\u4F7F\u7528 \`mcp__fast-context__fast_context_search\`**
561
+ **\u4EFB\u4F55\u9700\u8981\u7406\u89E3\u4EE3\u7801\u4E0A\u4E0B\u6587\u3001\u63A2\u7D22\u6027\u641C\u7D22\u3001\u6216\u81EA\u7136\u8BED\u8A00\u5B9A\u4F4D\u4EE3\u7801\u7684\u573A\u666F\uFF0C\u4F18\u5148\u4F7F\u7528 \`mcp__fast-context__fast_context_search\`**`;
562
+ const FAST_CONTEXT_PROMPT_AUXILIARY = `# fast-context MCP \u5DE5\u5177\u4F7F\u7528\u6307\u5357\uFF08\u8F85\u52A9\u6A21\u5F0F\uFF09
562
563
 
563
- ## \u4F7F\u7528\u573A\u666F
564
-
565
- ### \u5FC5\u987B\u7528 fast_context_search
566
- - \u63A2\u7D22\u6027\u641C\u7D22\uFF08\u4E0D\u786E\u5B9A\u4EE3\u7801\u5728\u54EA\u4E2A\u6587\u4EF6/\u76EE\u5F55\uFF09
567
- - \u7528\u81EA\u7136\u8BED\u8A00\u63CF\u8FF0\u8981\u627E\u7684\u903B\u8F91\uFF08\u5982"\u90E8\u7F72\u6D41\u7A0B"\u3001"\u4E8B\u4EF6\u5904\u7406"\uFF09
568
- - \u7406\u89E3\u4E1A\u52A1\u903B\u8F91\u548C\u8C03\u7528\u94FE\u8DEF
569
- - \u8DE8\u6A21\u5757\u3001\u8DE8\u5C42\u7EA7\u67E5\u8BE2\uFF08\u5982\u4ECE router \u8FFD\u5230 service \u5230 model\uFF09
570
- - \u65B0\u4EFB\u52A1\u5F00\u59CB\u524D\u7684\u4EE3\u7801\u8C03\u7814\u548C\u67B6\u6784\u7406\u89E3
571
- - \u4E2D\u6587\u8BED\u4E49\u641C\u7D22\uFF08\u5DE5\u5177\u652F\u6301\u4E2D\u82F1\u6587\u53CC\u8BED\u67E5\u8BE2\uFF09
572
-
573
- ### \u6839\u636E\u9700\u6C42\u9009\u62E9\u5DE5\u5177
574
- - **\u8BED\u4E49\u641C\u7D22 / \u4E0D\u786E\u5B9A\u4F4D\u7F6E** \u2192 \`mcp__fast-context__fast_context_search\`\uFF08\u8FD4\u56DE\u6587\u4EF6+\u884C\u53F7\u8303\u56F4+grep\u5173\u952E\u8BCD\u5EFA\u8BAE\uFF09
575
- - **\u7CBE\u786E\u5173\u952E\u8BCD\u641C\u7D22** \u2192 Grep
576
- - **\u5DF2\u77E5\u6587\u4EF6\u8DEF\u5F84\uFF0C\u67E5\u770B\u5185\u5BB9** \u2192 Read
577
- - **\u6309\u6587\u4EF6\u540D\u6A21\u5F0F\u67E5\u627E** \u2192 Glob
578
- - **\u7F16\u8F91\u5DF2\u6709\u6587\u4EF6** \u2192 Edit
579
-
580
- ### fast_context_search \u53C2\u6570\u8C03\u4F18
581
- - \`tree_depth=1, max_turns=1\` \u2014 \u5FEB\u901F\u7C97\u67E5\uFF0C\u9002\u5408\u5C0F\u9879\u76EE\u6216\u521D\u6B65\u5B9A\u4F4D
582
- - \`tree_depth=3, max_turns=3\`\uFF08\u9ED8\u8BA4\uFF09\u2014 \u5E73\u8861\u7CBE\u5EA6\u4E0E\u901F\u5EA6\uFF0C\u9002\u5408\u5927\u591A\u6570\u573A\u666F
583
- - \`max_turns=5\` \u2014 \u6DF1\u5EA6\u641C\u7D22\uFF0C\u9002\u5408\u590D\u6742\u8C03\u7528\u94FE\u8FFD\u8E2A
584
- - \`project_path\` \u2014 \u6307\u5B9A\u641C\u7D22\u7684\u9879\u76EE\u6839\u76EE\u5F55\uFF0C\u9ED8\u8BA4\u4E3A\u5F53\u524D\u5DE5\u4F5C\u76EE\u5F55
564
+ ## \u6838\u5FC3\u539F\u5219
585
565
 
586
- ### \u7981\u6B62\u884C\u4E3A
587
- - \u274C \u731C\u6D4B\u4EE3\u7801\u4F4D\u7F6E\uFF08"\u5E94\u8BE5\u5728 service/firmware \u91CC"\uFF09
588
- - \u274C \u8DF3\u8FC7\u641C\u7D22\u76F4\u63A5\u56DE\u7B54\uFF08"\u6839\u636E\u6846\u67B6\u60EF\u4F8B\uFF0C\u5E94\u8BE5\u662F..."\uFF09
589
- - \u274C \u9047\u5230\u641C\u7D22\u5C31\u542F\u52A8\u5B50\u4EE3\u7406\uFF08fast-context + Grep \u7EC4\u5408\u4F18\u5148\uFF09
566
+ **\u4E3B\u68C0\u7D22\u5DE5\u5177\u4E3A ace-tool\uFF08\`mcp__ace-tool__search_context\`\uFF09\u3002\u5F53 ace-tool \u65E0\u6CD5\u6EE1\u8DB3\u8BED\u4E49\u641C\u7D22\u9700\u6C42\u65F6\uFF0C\u4F7F\u7528 \`mcp__fast-context__fast_context_search\` \u4F5C\u4E3A\u8865\u5145\u3002**
590
567
 
591
- ### \u5B50\u4EE3\u7406\u4F7F\u7528\u6761\u4EF6
592
- \u4EC5\u5F53\u9700\u8981\u8BFB\u53D6 10+ \u6587\u4EF6\u4EA4\u53C9\u6BD4\u5BF9\u3001\u6216\u591A\u8F6E\u641C\u7D22\u4F1A\u6491\u7206\u4E0A\u4E0B\u6587\u65F6\uFF0C\u624D\u542F\u52A8\u5B50\u4EE3\u7406\u3002
593
- `;
568
+ \u9002\u5408\u4F7F\u7528 fast-context \u7684\u573A\u666F\uFF1A
569
+ - \u7528\u81EA\u7136\u8BED\u8A00\u63CF\u8FF0\u8981\u627E\u7684\u903B\u8F91\uFF08\u5982"\u90E8\u7F72\u6D41\u7A0B"\u3001"\u4E8B\u4EF6\u5904\u7406"\uFF09
570
+ - \u8DE8\u6A21\u5757\u3001\u8DE8\u5C42\u7EA7\u7684\u8C03\u7528\u94FE\u8DEF\u8FFD\u8E2A
571
+ - \u4E2D\u6587\u8BED\u4E49\u641C\u7D22\uFF08\u5DE5\u5177\u652F\u6301\u4E2D\u82F1\u6587\u53CC\u8BED\u67E5\u8BE2\uFF09`;
594
572
  const FC_MARKER_START = "<!-- CCG-FAST-CONTEXT-START -->";
595
573
  const FC_MARKER_END = "<!-- CCG-FAST-CONTEXT-END -->";
596
- async function writeFastContextPrompt() {
574
+ async function writeFastContextPrompt(auxiliaryMode = false) {
575
+ const promptContent = auxiliaryMode ? FAST_CONTEXT_PROMPT_AUXILIARY : FAST_CONTEXT_PROMPT_PRIMARY;
597
576
  const markerStart = FC_MARKER_START;
598
577
  const markerEnd = FC_MARKER_END;
599
578
  const markedBlock = `
600
579
  ${markerStart}
601
- ${FAST_CONTEXT_PROMPT}
580
+ ${promptContent}
602
581
  ${markerEnd}
603
582
  `;
604
583
  const markerRegex = new RegExp(
@@ -621,7 +600,7 @@ ${markerEnd}
621
600
  }
622
601
  const rulesDir = join(homedir(), ".claude", "rules");
623
602
  await fs.ensureDir(rulesDir);
624
- await fs.writeFile(join(rulesDir, "ccg-fast-context.md"), FAST_CONTEXT_PROMPT, "utf-8");
603
+ await fs.writeFile(join(rulesDir, "ccg-fast-context.md"), promptContent, "utf-8");
625
604
  await injectIntoFile(join(homedir(), ".codex", "AGENTS.md"));
626
605
  await injectIntoFile(join(homedir(), ".gemini", "GEMINI.md"));
627
606
  }
@@ -1555,6 +1534,14 @@ const zhCN = {
1555
1534
  mcp: {
1556
1535
  title: "MCP \u4EE3\u7801\u68C0\u7D22\u5DE5\u5177\u914D\u7F6E",
1557
1536
  selectProvider: "\u9009\u62E9\u4EE3\u7801\u68C0\u7D22 MCP \u5DE5\u5177",
1537
+ selectTools: "\u9009\u62E9\u8981\u5B89\u88C5\u7684 MCP \u5DE5\u5177\uFF08\u7A7A\u683C\u9009\u62E9\uFF0C\u56DE\u8F66\u786E\u8BA4\uFF09",
1538
+ fcAutoExtract: "\u672C\u5730\u88C5\u4E86 Windsurf \u5E76\u767B\u5F55\u53EF\u81EA\u52A8\u63D0\u53D6 Key",
1539
+ fcLeaveEmpty: "\u7559\u7A7A\u5219\u542F\u52A8\u65F6\u81EA\u52A8\u63D0\u53D6",
1540
+ fcSnippetMode: "\u8FD4\u56DE\u5185\u5BB9\u6A21\u5F0F",
1541
+ fcPathOnly: "\u4EC5\u8DEF\u5F84 + \u884C\u53F7",
1542
+ fcSaveToken: "\u66F4\u7701 token",
1543
+ fcFullSnippet: "\u5B8C\u6574\u4EE3\u7801\u7247\u6BB5",
1544
+ fcPromptInjected: "\u641C\u7D22\u63D0\u793A\u8BCD\u5DF2\u6CE8\u5165",
1558
1545
  contextweaver: "\u672C\u5730\u5411\u91CF\u5E93\uFF0C\u6DF7\u5408\u641C\u7D22 + Rerank",
1559
1546
  aceToolPaid: "Augment \u5B98\u65B9",
1560
1547
  aceToolRsPaid: "\u66F4\u8F7B\u91CF",
@@ -1596,6 +1583,11 @@ const zhCN = {
1596
1583
  api: {
1597
1584
  title: "Claude Code API \u914D\u7F6E",
1598
1585
  configurePrompt: "\u662F\u5426\u914D\u7F6E\u81EA\u5B9A\u4E49 API\uFF1F\uFF08\u4F7F\u7528\u5B98\u65B9\u8D26\u53F7\u53EF\u8DF3\u8FC7\uFF09",
1586
+ providerPrompt: "\u9009\u62E9 API \u63D0\u4F9B\u65B9",
1587
+ officialOption: "Anthropic \u5B98\u65B9\uFF08\u5DF2\u6709\u8D26\u53F7 / Claude Pro / Max \u8BA2\u9605\uFF09",
1588
+ thirdPartyOption: "\u7B2C\u4E09\u65B9 API \u4EE3\u7406\uFF08\u81EA\u5B9A\u4E49 URL + Key\uFF09",
1589
+ sponsorSlot: "\u8D5E\u52A9\u5546\u5408\u4F5C\u4F4D\uFF08\u7B49\u5F85\u91D1\u4E3B\u7238\u7238\u6295\u5582\uFF09",
1590
+ sponsorDisabled: "\u7B49\u5F85\u91D1\u4E3B\u7238\u7238\u6295\u5582",
1599
1591
  urlPrompt: "API URL",
1600
1592
  urlRequired: "\u5FC5\u586B",
1601
1593
  keyPrompt: "API Key",
@@ -1610,6 +1602,12 @@ const zhCN = {
1610
1602
  prompt: "\u542F\u7528 Web UI \u5B9E\u65F6\u8F93\u51FA\uFF1F",
1611
1603
  disableHint: "\u7981\u7528\u53EF\u52A0\u901F\u54CD\u5E94"
1612
1604
  },
1605
+ perf: {
1606
+ title: "\u6027\u80FD\u6A21\u5F0F",
1607
+ selectMode: "\u9009\u62E9\u6027\u80FD\u6A21\u5F0F",
1608
+ standardOption: "\u6807\u51C6\u6A21\u5F0F\uFF08\u542B Web UI \u5B9E\u65F6\u76D1\u63A7\uFF09",
1609
+ liteOption: "\u8F7B\u91CF\u6A21\u5F0F\uFF08\u65E0 Web UI\uFF0C\u54CD\u5E94\u66F4\u5FEB\uFF09"
1610
+ },
1613
1611
  hooks: {
1614
1612
  title: "codeagent-wrapper \u81EA\u52A8\u6388\u6743",
1615
1613
  description: "\u4F7F\u7528 Hook \u81EA\u52A8\u6388\u6743 codeagent-wrapper \u547D\u4EE4",
@@ -1779,11 +1777,21 @@ const zhCN = {
1779
1777
  api: {
1780
1778
  title: "\u914D\u7F6E Claude Code API",
1781
1779
  currentConfig: "\u5F53\u524D\u914D\u7F6E:",
1780
+ providerPrompt: "\u9009\u62E9 API \u63D0\u4F9B\u65B9",
1781
+ officialOption: "Anthropic \u5B98\u65B9\uFF08\u4F7F\u7528\u5B98\u65B9\u8D26\u53F7\u767B\u5F55\uFF09",
1782
+ thirdPartyOption: "\u7B2C\u4E09\u65B9 API \u4EE3\u7406\uFF08\u81EA\u5B9A\u4E49 URL + Key\uFF09",
1783
+ sponsorSlot: "\u8D5E\u52A9\u5546\u5408\u4F5C\u4F4D\uFF08\u7B49\u5F85\u91D1\u4E3B\u7238\u7238\u6295\u5582\uFF09",
1784
+ sponsorDisabled: "\u7B49\u5F85\u91D1\u4E3B\u7238\u7238\u6295\u5582",
1782
1785
  urlPrompt: "API URL",
1786
+ urlRequired: "\u5FC5\u586B",
1783
1787
  keyPrompt: "API Key",
1788
+ keyRequired: "\u5FC5\u586B",
1789
+ enterUrl: "\u8BF7\u8F93\u5165 API URL",
1790
+ enterKey: "\u8BF7\u8F93\u5165 API Key",
1784
1791
  leaveEmptyOfficial: "\u7559\u7A7A\u4F7F\u7528\u5B98\u65B9",
1785
1792
  leaveEmptySkip: "\u7559\u7A7A\u8DF3\u8FC7",
1786
- saved: "API \u914D\u7F6E\u5DF2\u4FDD\u5B58"
1793
+ saved: "API \u914D\u7F6E\u5DF2\u4FDD\u5B58",
1794
+ clearedForOfficial: "\u5DF2\u6E05\u9664\u7B2C\u4E09\u65B9 API \u914D\u7F6E\uFF0C\u5C06\u4F7F\u7528\u5B98\u65B9\u767B\u5F55"
1787
1795
  },
1788
1796
  style: {
1789
1797
  title: "\u914D\u7F6E\u8F93\u51FA\u98CE\u683C",
@@ -1978,6 +1986,14 @@ const en = {
1978
1986
  mcp: {
1979
1987
  title: "MCP Code Retrieval Tool",
1980
1988
  selectProvider: "Select code retrieval MCP tool",
1989
+ selectTools: "Select MCP tools to install (space to select, enter to confirm)",
1990
+ fcAutoExtract: "Auto-extracts key from local Windsurf installation",
1991
+ fcLeaveEmpty: "Leave empty for auto-extraction",
1992
+ fcSnippetMode: "Response content mode",
1993
+ fcPathOnly: "Path + line numbers only",
1994
+ fcSaveToken: "saves tokens",
1995
+ fcFullSnippet: "Full code snippets",
1996
+ fcPromptInjected: "Search prompt injected",
1981
1997
  contextweaver: "Local vector DB, hybrid search + Rerank",
1982
1998
  aceToolPaid: "Augment official",
1983
1999
  aceToolRsPaid: "Lighter weight",
@@ -2019,6 +2035,11 @@ const en = {
2019
2035
  api: {
2020
2036
  title: "Claude Code API Configuration",
2021
2037
  configurePrompt: "Configure custom API? (skip if using official account)",
2038
+ providerPrompt: "Select API provider",
2039
+ officialOption: "Anthropic Official (existing account / Claude Pro / Max subscription)",
2040
+ thirdPartyOption: "Third-party API proxy (custom URL + Key)",
2041
+ sponsorSlot: "Sponsor slot (awaiting generous sponsors)",
2042
+ sponsorDisabled: "Awaiting sponsors",
2022
2043
  urlPrompt: "API URL",
2023
2044
  urlRequired: "Required",
2024
2045
  keyPrompt: "API Key",
@@ -2033,6 +2054,12 @@ const en = {
2033
2054
  prompt: "Enable Web UI real-time output?",
2034
2055
  disableHint: "Disabling can speed up response"
2035
2056
  },
2057
+ perf: {
2058
+ title: "Performance Mode",
2059
+ selectMode: "Select performance mode",
2060
+ standardOption: "Standard (with Web UI real-time monitoring)",
2061
+ liteOption: "Lite (no Web UI, faster response)"
2062
+ },
2036
2063
  hooks: {
2037
2064
  title: "codeagent-wrapper auto-authorization",
2038
2065
  description: "Use Hook to auto-authorize codeagent-wrapper commands",
@@ -2202,11 +2229,21 @@ const en = {
2202
2229
  api: {
2203
2230
  title: "Configure Claude Code API",
2204
2231
  currentConfig: "Current config:",
2232
+ providerPrompt: "Select API provider",
2233
+ officialOption: "Anthropic Official (use official account login)",
2234
+ thirdPartyOption: "Third-party API proxy (custom URL + Key)",
2235
+ sponsorSlot: "Sponsor slot (awaiting generous sponsors)",
2236
+ sponsorDisabled: "Awaiting sponsors",
2205
2237
  urlPrompt: "API URL",
2238
+ urlRequired: "Required",
2206
2239
  keyPrompt: "API Key",
2240
+ keyRequired: "Required",
2241
+ enterUrl: "Please enter API URL",
2242
+ enterKey: "Please enter API Key",
2207
2243
  leaveEmptyOfficial: "Leave empty for official",
2208
2244
  leaveEmptySkip: "Leave empty to skip",
2209
- saved: "API configuration saved"
2245
+ saved: "API configuration saved",
2246
+ clearedForOfficial: "Third-party API config cleared, will use official login"
2210
2247
  },
2211
2248
  style: {
2212
2249
  title: "Configure Output Style",
@@ -2602,192 +2639,171 @@ async function init(options = {}) {
2602
2639
  let contextWeaverApiKey = "";
2603
2640
  let fastContextApiKey = "";
2604
2641
  let fastContextIncludeSnippets = false;
2642
+ let wantFastContext = false;
2643
+ let wantGrokSearch = false;
2644
+ let tavilyKey = "";
2645
+ let firecrawlKey = "";
2646
+ let grokApiUrl = "";
2647
+ let grokApiKey = "";
2648
+ let apiUrl = "";
2649
+ let apiKey = "";
2650
+ if (!options.skipPrompt) {
2651
+ console.log();
2652
+ console.log(ansis.cyan.bold(` \u{1F511} Step 1/3 \u2014 ${i18n.t("init:api.title")}`));
2653
+ console.log();
2654
+ const { apiProvider } = await inquirer.prompt([{
2655
+ type: "list",
2656
+ name: "apiProvider",
2657
+ message: i18n.t("init:api.providerPrompt"),
2658
+ choices: [
2659
+ { name: `${ansis.green("\u25CF")} ${i18n.t("init:api.officialOption")}`, value: "official" },
2660
+ { name: `${ansis.cyan("\u25CF")} ${i18n.t("init:api.thirdPartyOption")}`, value: "thirdparty" },
2661
+ { name: ansis.gray(`\u25CB ${i18n.t("init:api.sponsorSlot")}`), value: "sponsor", disabled: i18n.t("init:api.sponsorDisabled") }
2662
+ ]
2663
+ }]);
2664
+ if (apiProvider === "thirdparty") {
2665
+ const apiAnswers = await inquirer.prompt([
2666
+ {
2667
+ type: "input",
2668
+ name: "url",
2669
+ message: `API URL ${ansis.gray(`(${i18n.t("init:api.urlRequired")})`)}`,
2670
+ validate: (v) => v.trim() !== "" || i18n.t("init:api.enterUrl")
2671
+ },
2672
+ {
2673
+ type: "password",
2674
+ name: "key",
2675
+ message: `API Key ${ansis.gray(`(${i18n.t("init:api.keyRequired")})`)}`,
2676
+ mask: "*",
2677
+ validate: (v) => v.trim() !== "" || i18n.t("init:api.enterKey")
2678
+ }
2679
+ ]);
2680
+ apiUrl = apiAnswers.url?.trim() || "";
2681
+ apiKey = apiAnswers.key?.trim() || "";
2682
+ }
2683
+ }
2605
2684
  if (options.skipMcp) {
2606
2685
  mcpProvider = "skip";
2607
2686
  } else if (!options.skipPrompt) {
2608
2687
  console.log();
2609
- console.log(ansis.cyan.bold(` \u{1F527} ${i18n.t("init:mcp.title")}`));
2688
+ console.log(ansis.cyan.bold(` \u{1F527} Step 2/3 \u2014 ${i18n.t("init:mcp.title")}`));
2610
2689
  console.log();
2611
- const { selectedMcp } = await inquirer.prompt([{
2612
- type: "list",
2613
- name: "selectedMcp",
2614
- message: i18n.t("init:mcp.selectProvider"),
2690
+ const { selectedTools } = await inquirer.prompt([{
2691
+ type: "checkbox",
2692
+ name: "selectedTools",
2693
+ message: i18n.t("init:mcp.selectTools"),
2615
2694
  choices: [
2616
2695
  {
2617
- name: `fast-context ${ansis.green(`(${i18n.t("common:info")})`)} ${ansis.gray("- Windsurf Fast Context, AI \u9A71\u52A8\u641C\u7D22")}`,
2618
- value: "fast-context"
2696
+ name: `ace-tool ${ansis.green(`(${i18n.t("common:info")})`)} ${ansis.gray("\u2014 search_context \u4EE3\u7801\u68C0\u7D22")}`,
2697
+ value: "ace-tool",
2698
+ checked: true
2619
2699
  },
2620
2700
  {
2621
- name: `ace-tool ${ansis.gray("- search_context (enhance_prompt N/A)")}`,
2622
- value: "ace-tool"
2701
+ name: `fast-context ${ansis.gray("\u2014 AI \u9A71\u52A8\u8BED\u4E49\u641C\u7D22")}`,
2702
+ value: "fast-context"
2623
2703
  },
2624
2704
  {
2625
- name: `ace-tool-rs ${ansis.gray("(Rust) - search_context")}`,
2626
- value: "ace-tool-rs"
2705
+ name: `context7 ${ansis.green("(free)")} ${ansis.gray("\u2014 \u5E93\u6587\u6863\u67E5\u8BE2")}`,
2706
+ value: "context7",
2707
+ checked: true
2627
2708
  },
2628
2709
  {
2629
- name: `contextweaver ${ansis.gray(`- ${i18n.t("init:mcp.contextweaver")}`)}`,
2630
- value: "contextweaver"
2710
+ name: `grok-search ${ansis.gray("\u2014 \u8054\u7F51\u641C\u7D22 (\u9700 API Key)")}`,
2711
+ value: "grok-search"
2631
2712
  },
2632
2713
  {
2633
- name: `${i18n.t("init:mcp.skipLater")} ${ansis.gray(`- ${i18n.t("init:mcp.configManually")}`)}`,
2634
- value: "skip"
2714
+ name: `contextweaver ${ansis.gray("\u2014 \u7845\u57FA\u6D41\u52A8\u5D4C\u5165\u68C0\u7D22 (\u9700 API Key)")}`,
2715
+ value: "contextweaver"
2635
2716
  }
2636
- ],
2637
- default: "fast-context"
2717
+ ]
2638
2718
  }]);
2639
- mcpProvider = selectedMcp;
2640
- if (selectedMcp === "ace-tool" || selectedMcp === "ace-tool-rs") {
2641
- const toolName = selectedMcp === "ace-tool-rs" ? "ace-tool-rs" : "ace-tool";
2642
- const toolDesc = selectedMcp === "ace-tool-rs" ? i18n.t("init:aceToolRs.description") : i18n.t("init:aceTool.description");
2643
- console.log();
2644
- console.log(ansis.cyan.bold(` \u{1F527} ${toolName} MCP`));
2645
- console.log(ansis.gray(` ${toolDesc}`));
2719
+ const hasAceTool = selectedTools.includes("ace-tool");
2720
+ const hasFastContext = selectedTools.includes("fast-context");
2721
+ const hasContextWeaver = selectedTools.includes("contextweaver");
2722
+ wantFastContext = hasFastContext;
2723
+ wantGrokSearch = selectedTools.includes("grok-search");
2724
+ if (hasAceTool) {
2725
+ mcpProvider = "ace-tool";
2726
+ } else if (hasFastContext) {
2727
+ mcpProvider = "fast-context";
2728
+ } else if (hasContextWeaver) {
2729
+ mcpProvider = "contextweaver";
2730
+ } else {
2731
+ mcpProvider = "skip";
2732
+ }
2733
+ if (hasAceTool) {
2646
2734
  console.log();
2647
- const { skipToken } = await inquirer.prompt([{
2648
- type: "confirm",
2649
- name: "skipToken",
2650
- message: i18n.t("init:mcp.skipTokenPrompt"),
2651
- default: false
2652
- }]);
2653
- if (!skipToken) {
2654
- console.log();
2655
- console.log(ansis.cyan(` \u{1F4D6} ${i18n.t("init:mcp.getAccess")}`));
2656
- console.log();
2657
- console.log(` ${ansis.gray("\u2022")} ${ansis.cyan(i18n.t("init:mcp.officialService"))}: ${ansis.underline("https://augmentcode.com/")}`);
2658
- console.log(` ${ansis.gray(i18n.t("init:mcp.registerForToken"))}`);
2659
- console.log();
2660
- console.log(` ${ansis.gray("\u2022")} ${ansis.cyan(i18n.t("init:mcp.proxyService"))} ${ansis.yellow(`(${i18n.t("init:mcp.noSignup")})`)}: ${ansis.underline("https://acemcp.heroman.wtf/")}`);
2661
- console.log(` ${ansis.gray(i18n.t("init:mcp.communityProxy"))}`);
2662
- console.log();
2663
- const aceAnswers = await inquirer.prompt([
2664
- {
2665
- type: "input",
2666
- name: "baseUrl",
2667
- message: `Base URL ${ansis.gray(`(${i18n.t("init:mcp.baseUrlHint")})`)}`,
2668
- default: ""
2669
- },
2670
- {
2671
- type: "password",
2672
- name: "token",
2673
- message: `Token ${ansis.gray(`(${i18n.t("init:mcp.tokenRequired")})`)}`,
2674
- mask: "*",
2675
- validate: (input) => input.trim() !== "" || i18n.t("init:mcp.enterToken")
2676
- }
2677
- ]);
2678
- aceToolBaseUrl = aceAnswers.baseUrl || "";
2679
- aceToolToken = aceAnswers.token || "";
2680
- } else {
2681
- console.log();
2682
- console.log(ansis.yellow(` \u2139\uFE0F ${i18n.t("init:mcp.tokenSkipped")}`));
2683
- console.log(ansis.gray(` \u2022 ${toolName} MCP ${i18n.t("init:mcp.notInstalled")}`));
2684
- console.log(ansis.gray(` \u2022 ${i18n.t("init:mcp.configLater", { cmd: ansis.cyan("npx ccg config mcp") })}`));
2685
- console.log();
2686
- }
2687
- } else if (selectedMcp === "fast-context") {
2735
+ console.log(ansis.cyan.bold(` \u{1F527} ace-tool MCP`));
2688
2736
  console.log();
2689
- console.log(ansis.cyan.bold(` \u{1F527} Fast Context MCP`));
2690
- console.log(ansis.gray(` Windsurf Fast Context \u2014 AI \u9A71\u52A8\u4EE3\u7801\u641C\u7D22\uFF0C\u65E0\u9700\u5168\u91CF\u7D22\u5F15`));
2737
+ console.log(` ${ansis.gray("\u2022")} ${ansis.cyan(i18n.t("init:mcp.officialService"))}: ${ansis.underline("https://augmentcode.com/")}`);
2738
+ console.log(` ${ansis.gray("\u2022")} ${ansis.cyan(i18n.t("init:mcp.proxyService"))} ${ansis.yellow(`(${i18n.t("init:mcp.noSignup")})`)}: ${ansis.underline("https://acemcp.heroman.wtf/")}`);
2691
2739
  console.log();
2692
- const { skipKey } = await inquirer.prompt([{
2693
- type: "confirm",
2694
- name: "skipKey",
2695
- message: "\u8DF3\u8FC7 API Key \u914D\u7F6E\uFF1F\uFF08\u672C\u5730\u88C5\u4E86 Windsurf \u5E76\u767B\u5F55\u53EF\u81EA\u52A8\u63D0\u53D6\uFF09",
2696
- default: false
2697
- }]);
2698
- if (!skipKey) {
2699
- console.log();
2700
- console.log(ansis.cyan(` \u{1F4D6} \u83B7\u53D6 WINDSURF_API_KEY\uFF1A`));
2701
- console.log();
2702
- console.log(` ${ansis.gray("\u2022")} \u5B89\u88C5 Windsurf \u7F16\u8F91\u5668 \u2192 \u767B\u5F55 \u2192 Key \u81EA\u52A8\u5B58\u5165\u672C\u5730 SQLite`);
2703
- console.log(` ${ansis.gray("\u2022")} \u4E5F\u53EF\u624B\u52A8\u4ECE SQLite \u63D0\u53D6\uFF08AI \u53EF\u8C03\u7528 extract_windsurf_key \u5DE5\u5177\uFF09`);
2704
- console.log();
2705
- const fcAnswers = await inquirer.prompt([
2706
- {
2707
- type: "input",
2708
- name: "apiKey",
2709
- message: `WINDSURF_API_KEY ${ansis.gray("(\u7559\u7A7A\u5219\u542F\u52A8\u65F6\u81EA\u52A8\u63D0\u53D6)")}`,
2710
- default: ""
2711
- },
2712
- {
2713
- type: "confirm",
2714
- name: "includeSnippets",
2715
- message: `\u8FD4\u56DE\u5B8C\u6574\u4EE3\u7801\u7247\u6BB5\uFF1F${ansis.gray("(\u5426\u5219\u4EC5\u8DEF\u5F84+\u884C\u53F7\uFF0C\u66F4\u7701 token)")}`,
2716
- default: false
2717
- }
2718
- ]);
2719
- fastContextApiKey = fcAnswers.apiKey?.trim() || "";
2720
- fastContextIncludeSnippets = fcAnswers.includeSnippets;
2721
- } else {
2722
- console.log();
2723
- console.log(ansis.yellow(` \u2139\uFE0F API Key \u5DF2\u8DF3\u8FC7`));
2724
- console.log(ansis.gray(` \u2022 fast-context MCP \u5C06\u4E0D\u5E26 Key \u5B89\u88C5\uFF08\u542F\u52A8\u65F6\u81EA\u52A8\u4ECE\u672C\u5730 Windsurf \u63D0\u53D6\uFF09`));
2725
- console.log();
2726
- }
2727
- } else if (selectedMcp === "contextweaver") {
2740
+ const aceAnswers = await inquirer.prompt([
2741
+ {
2742
+ type: "input",
2743
+ name: "baseUrl",
2744
+ message: `Base URL ${ansis.gray(`(${i18n.t("init:mcp.baseUrlHint")})`)}`,
2745
+ default: ""
2746
+ },
2747
+ {
2748
+ type: "password",
2749
+ name: "token",
2750
+ message: `Token ${ansis.gray(`(${i18n.t("init:mcp.tokenRequired")})`)}`,
2751
+ mask: "*",
2752
+ validate: (input) => input.trim() !== "" || i18n.t("init:mcp.enterToken")
2753
+ }
2754
+ ]);
2755
+ aceToolBaseUrl = aceAnswers.baseUrl || "";
2756
+ aceToolToken = aceAnswers.token || "";
2757
+ }
2758
+ if (hasFastContext) {
2728
2759
  console.log();
2729
- console.log(ansis.cyan.bold(` \u{1F527} ContextWeaver MCP`));
2730
- console.log(ansis.gray(` ${i18n.t("init:mcp.localEngine")}`));
2760
+ console.log(ansis.cyan.bold(` \u{1F527} fast-context MCP`));
2761
+ console.log(ansis.gray(` Windsurf Fast Context \u2014 ${i18n.t("init:mcp.fcAutoExtract")}`));
2731
2762
  console.log();
2732
- const { skipKey } = await inquirer.prompt([{
2733
- type: "confirm",
2734
- name: "skipKey",
2735
- message: i18n.t("init:mcp.skipKeyPrompt"),
2736
- default: false
2737
- }]);
2738
- if (!skipKey) {
2739
- console.log();
2740
- console.log(ansis.cyan(` \u{1F4D6} ${i18n.t("init:mcp.getApiKey")}`));
2741
- console.log();
2742
- console.log(` ${ansis.gray("1.")} ${i18n.t("init:mcp.siliconflowStep1", { url: ansis.underline("https://siliconflow.cn/") })}`);
2743
- console.log(` ${ansis.gray("2.")} ${i18n.t("init:mcp.siliconflowStep2")}`);
2744
- console.log(` ${ansis.gray("3.")} ${i18n.t("init:mcp.siliconflowStep3")}`);
2745
- console.log();
2746
- const cwAnswers = await inquirer.prompt([{
2747
- type: "password",
2763
+ const fcAnswers = await inquirer.prompt([
2764
+ {
2765
+ type: "input",
2748
2766
  name: "apiKey",
2749
- message: `SiliconFlow API Key ${ansis.gray("(sk-xxx)")}`,
2750
- mask: "*",
2751
- validate: (input) => input.trim() !== "" || i18n.t("init:mcp.enterApiKey")
2752
- }]);
2753
- contextWeaverApiKey = cwAnswers.apiKey || "";
2754
- } else {
2755
- console.log();
2756
- console.log(ansis.yellow(` \u2139\uFE0F ${i18n.t("init:mcp.keySkipped")}`));
2757
- console.log(ansis.gray(` \u2022 ContextWeaver MCP ${i18n.t("init:mcp.notInstalled")}`));
2758
- console.log(ansis.gray(` \u2022 ${i18n.t("init:mcp.configLater", { cmd: ansis.cyan("npx ccg config mcp") })}`));
2759
- console.log();
2760
- }
2761
- } else {
2767
+ message: `WINDSURF_API_KEY ${ansis.gray(`(${i18n.t("init:mcp.fcLeaveEmpty")})`)}`,
2768
+ default: ""
2769
+ },
2770
+ {
2771
+ type: "list",
2772
+ name: "includeSnippets",
2773
+ message: i18n.t("init:mcp.fcSnippetMode"),
2774
+ choices: [
2775
+ { name: `${i18n.t("init:mcp.fcPathOnly")} ${ansis.gray(`(${i18n.t("init:mcp.fcSaveToken")})`)}`, value: false },
2776
+ { name: i18n.t("init:mcp.fcFullSnippet"), value: true }
2777
+ ]
2778
+ }
2779
+ ]);
2780
+ fastContextApiKey = fcAnswers.apiKey?.trim() || "";
2781
+ fastContextIncludeSnippets = fcAnswers.includeSnippets;
2782
+ }
2783
+ if (hasContextWeaver) {
2784
+ console.log();
2785
+ console.log(ansis.cyan.bold(` \u{1F527} ContextWeaver MCP`));
2762
2786
  console.log();
2763
- console.log(ansis.yellow(` \u2139\uFE0F ${i18n.t("init:mcp.mcpSkipped")}`));
2764
- console.log(ansis.gray(` \u2022 ${i18n.t("init:mcp.configManually")}`));
2787
+ console.log(` ${ansis.gray("1.")} ${i18n.t("init:mcp.siliconflowStep1", { url: ansis.underline("https://siliconflow.cn/") })}`);
2788
+ console.log(` ${ansis.gray("2.")} ${i18n.t("init:mcp.siliconflowStep2")}`);
2789
+ console.log(` ${ansis.gray("3.")} ${i18n.t("init:mcp.siliconflowStep3")}`);
2765
2790
  console.log();
2791
+ const cwAnswers = await inquirer.prompt([{
2792
+ type: "password",
2793
+ name: "apiKey",
2794
+ message: `SiliconFlow API Key ${ansis.gray("(sk-xxx)")}`,
2795
+ mask: "*",
2796
+ validate: (input) => input.trim() !== "" || i18n.t("init:mcp.enterApiKey")
2797
+ }]);
2798
+ contextWeaverApiKey = cwAnswers.apiKey || "";
2766
2799
  }
2767
- }
2768
- let wantGrokSearch = false;
2769
- let tavilyKey = "";
2770
- let firecrawlKey = "";
2771
- let grokApiUrl = "";
2772
- let grokApiKey = "";
2773
- if (!options.skipPrompt && !options.skipMcp) {
2774
- console.log();
2775
- console.log(ansis.cyan.bold(` \u{1F50D} ${i18n.t("init:grok.title")}`));
2776
- console.log();
2777
- const { wantGrok } = await inquirer.prompt([{
2778
- type: "confirm",
2779
- name: "wantGrok",
2780
- message: i18n.t("init:grok.installPrompt"),
2781
- default: false
2782
- }]);
2783
- if (wantGrok) {
2784
- wantGrokSearch = true;
2800
+ if (wantGrokSearch) {
2785
2801
  console.log();
2802
+ console.log(ansis.cyan.bold(` \u{1F50D} grok-search MCP`));
2786
2803
  console.log();
2787
- console.log(ansis.cyan(` \u{1F4D6} ${i18n.t("init:grok.getKeys")}`));
2788
- console.log(` Tavily: ${ansis.underline("https://www.tavily.com/")} ${ansis.gray(`(${i18n.t("init:grok.tavilyHint")})`)}`);
2789
- console.log(` Firecrawl: ${ansis.underline("https://www.firecrawl.dev/")} ${ansis.gray(`(${i18n.t("init:grok.firecrawlHint")})`)}`);
2790
- console.log(` Grok API: ${ansis.gray(i18n.t("init:grok.grokHint"))}`);
2804
+ console.log(` Tavily: ${ansis.underline("https://www.tavily.com/")} ${ansis.gray(`(${i18n.t("init:grok.tavilyHint")})`)}`);
2805
+ console.log(` Firecrawl: ${ansis.underline("https://www.firecrawl.dev/")} ${ansis.gray(`(${i18n.t("init:grok.firecrawlHint")})`)}`);
2806
+ console.log(` Grok API: ${ansis.gray(i18n.t("init:grok.grokHint"))}`);
2791
2807
  console.log();
2792
2808
  const grokAnswers = await inquirer.prompt([
2793
2809
  { type: "input", name: "grokApiUrl", message: `GROK_API_URL ${ansis.gray(`(${i18n.t("init:grok.optional")})`)}`, default: "" },
@@ -2801,49 +2817,23 @@ async function init(options = {}) {
2801
2817
  grokApiKey = grokAnswers.grokApiKey?.trim() || "";
2802
2818
  }
2803
2819
  }
2804
- let apiUrl = "";
2805
- let apiKey = "";
2806
- if (!options.skipPrompt) {
2807
- console.log();
2808
- console.log(ansis.cyan.bold(` \u{1F511} ${i18n.t("init:api.title")}`));
2809
- console.log();
2810
- const { configureApi } = await inquirer.prompt([{
2811
- type: "confirm",
2812
- name: "configureApi",
2813
- message: i18n.t("init:api.configurePrompt"),
2814
- default: false
2815
- }]);
2816
- if (configureApi) {
2817
- const apiAnswers = await inquirer.prompt([
2818
- {
2819
- type: "input",
2820
- name: "url",
2821
- message: `API URL ${ansis.gray(`(${i18n.t("init:api.urlRequired")})`)}`,
2822
- validate: (v) => v.trim() !== "" || i18n.t("init:api.enterUrl")
2823
- },
2824
- {
2825
- type: "password",
2826
- name: "key",
2827
- message: `API Key ${ansis.gray(`(${i18n.t("init:api.keyRequired")})`)}`,
2828
- mask: "*",
2829
- validate: (v) => v.trim() !== "" || i18n.t("init:api.enterKey")
2830
- }
2831
- ]);
2832
- apiUrl = apiAnswers.url?.trim() || "";
2833
- apiKey = apiAnswers.key?.trim() || "";
2834
- }
2835
- }
2836
2820
  if (!options.skipPrompt) {
2837
2821
  const existingConfig = await readCcgConfig();
2838
2822
  const currentLiteMode = existingConfig?.performance?.liteMode || false;
2839
2823
  console.log();
2840
- const { enableWebUI } = await inquirer.prompt([{
2841
- type: "confirm",
2842
- name: "enableWebUI",
2843
- message: `${i18n.t("init:webui.prompt")} ${ansis.gray(`(${i18n.t("init:webui.disableHint")})`)}`,
2844
- default: !currentLiteMode
2824
+ console.log(ansis.cyan.bold(` \u26A1 Step 3/3 \u2014 ${i18n.t("init:perf.title")}`));
2825
+ console.log();
2826
+ const { perfMode } = await inquirer.prompt([{
2827
+ type: "list",
2828
+ name: "perfMode",
2829
+ message: i18n.t("init:perf.selectMode"),
2830
+ choices: [
2831
+ { name: `${ansis.green("\u25CF")} ${i18n.t("init:perf.standardOption")}`, value: "standard" },
2832
+ { name: `${ansis.cyan("\u25CF")} ${i18n.t("init:perf.liteOption")}`, value: "lite" }
2833
+ ],
2834
+ default: currentLiteMode ? "lite" : "standard"
2845
2835
  }]);
2846
- liteMode = !enableWebUI;
2836
+ liteMode = perfMode === "lite";
2847
2837
  } else {
2848
2838
  const existingConfig = await readCcgConfig();
2849
2839
  if (existingConfig?.performance?.liteMode !== void 0) {
@@ -2943,68 +2933,37 @@ async function init(options = {}) {
2943
2933
  liteMode,
2944
2934
  mcpProvider
2945
2935
  });
2946
- if ((mcpProvider === "ace-tool" || mcpProvider === "ace-tool-rs") && aceToolToken) {
2947
- const toolName = mcpProvider === "ace-tool-rs" ? "ace-tool-rs" : "ace-tool";
2948
- const installFn = mcpProvider === "ace-tool-rs" ? installAceToolRs : installAceTool;
2949
- spinner.text = mcpProvider === "ace-tool-rs" ? i18n.t("init:aceToolRs.installing") : i18n.t("init:aceTool.installing");
2950
- const aceResult = await installFn({
2951
- baseUrl: aceToolBaseUrl,
2952
- token: aceToolToken
2953
- });
2936
+ spinner.succeed(ansis.green(i18n.t("init:installSuccess")));
2937
+ if (aceToolToken) {
2938
+ spinner.text = i18n.t("init:aceTool.installing");
2939
+ const aceResult = await installAceTool({ baseUrl: aceToolBaseUrl, token: aceToolToken });
2954
2940
  if (aceResult.success) {
2955
- spinner.succeed(ansis.green(i18n.t("init:installSuccess")));
2956
- console.log();
2957
- console.log(` ${ansis.green("\u2713")} ${toolName} MCP ${ansis.gray(`\u2192 ${aceResult.configPath}`)}`);
2941
+ console.log(` ${ansis.green("\u2713")} ace-tool MCP ${ansis.gray(`\u2192 ${aceResult.configPath}`)}`);
2958
2942
  } else {
2959
- spinner.warn(ansis.yellow(mcpProvider === "ace-tool-rs" ? i18n.t("init:aceToolRs.failed") : i18n.t("init:aceTool.failed")));
2960
- console.log(ansis.gray(` ${aceResult.message}`));
2943
+ console.log(` ${ansis.yellow("\u26A0")} ace-tool: ${ansis.gray(aceResult.message)}`);
2961
2944
  }
2962
- } else if (mcpProvider === "fast-context") {
2963
- spinner.text = "Configuring fast-context MCP...";
2945
+ }
2946
+ if (wantFastContext) {
2964
2947
  const fcResult = await installFastContext({
2965
2948
  apiKey: fastContextApiKey || void 0,
2966
2949
  includeSnippets: fastContextIncludeSnippets
2967
2950
  });
2968
2951
  if (fcResult.success) {
2969
- spinner.succeed(ansis.green(i18n.t("init:installSuccess")));
2970
- console.log();
2971
2952
  console.log(` ${ansis.green("\u2713")} fast-context MCP ${ansis.gray(`\u2192 ${fcResult.configPath}`)}`);
2972
- await writeFastContextPrompt();
2973
- console.log(` ${ansis.green("\u2713")} \u641C\u7D22\u63D0\u793A\u8BCD ${ansis.gray("\u2192 ~/.claude/rules/ + ~/.codex/AGENTS.md + ~/.gemini/GEMINI.md")}`);
2953
+ await writeFastContextPrompt(mcpProvider === "ace-tool" || mcpProvider === "ace-tool-rs");
2954
+ console.log(` ${ansis.green("\u2713")} ${i18n.t("init:mcp.fcPromptInjected")} ${ansis.gray("\u2192 ~/.claude/rules/ + ~/.codex/ + ~/.gemini/")}`);
2974
2955
  } else {
2975
- spinner.warn(ansis.yellow("fast-context MCP \u914D\u7F6E\u5931\u8D25"));
2976
- console.log(ansis.gray(` ${fcResult.message}`));
2956
+ console.log(` ${ansis.yellow("\u26A0")} fast-context: ${ansis.gray(fcResult.message)}`);
2977
2957
  }
2978
- } else if (mcpProvider === "contextweaver" && contextWeaverApiKey) {
2958
+ }
2959
+ if (contextWeaverApiKey) {
2979
2960
  spinner.text = i18n.t("init:mcp.cwConfiguring");
2980
- const cwResult = await installContextWeaver({
2981
- siliconflowApiKey: contextWeaverApiKey
2982
- });
2961
+ const cwResult = await installContextWeaver({ siliconflowApiKey: contextWeaverApiKey });
2983
2962
  if (cwResult.success) {
2984
- spinner.succeed(ansis.green(i18n.t("init:installSuccess")));
2985
- console.log();
2986
2963
  console.log(` ${ansis.green("\u2713")} ContextWeaver MCP ${ansis.gray(`\u2192 ${cwResult.configPath}`)}`);
2987
- console.log(` ${ansis.green("\u2713")} ${i18n.t("init:mcp.cwConfigFile")} ${ansis.gray("\u2192 ~/.contextweaver/.env")}`);
2988
- console.log();
2989
- console.log(ansis.cyan(` \u{1F4D6} ${i18n.t("init:mcp.cwIndexHint")}`));
2990
- console.log(ansis.gray(` cd your-project && cw index`));
2991
2964
  } else {
2992
- spinner.warn(ansis.yellow(i18n.t("init:mcp.cwFailed")));
2993
- console.log(ansis.gray(` ${cwResult.message}`));
2965
+ console.log(` ${ansis.yellow("\u26A0")} ContextWeaver: ${ansis.gray(cwResult.message)}`);
2994
2966
  }
2995
- } else if (mcpProvider === "contextweaver" && !contextWeaverApiKey) {
2996
- spinner.succeed(ansis.green(i18n.t("init:installSuccess")));
2997
- console.log();
2998
- console.log(` ${ansis.yellow("\u26A0")} ContextWeaver MCP ${i18n.t("init:mcp.notInstalled")} ${ansis.gray(`(${i18n.t("init:mcp.keyNotProvided")})`)}`);
2999
- console.log(` ${ansis.gray("\u2192")} ${i18n.t("init:mcp.configLater", { cmd: ansis.cyan("npx ccg config mcp") })}`);
3000
- } else if ((mcpProvider === "ace-tool" || mcpProvider === "ace-tool-rs") && !aceToolToken) {
3001
- const toolName = mcpProvider === "ace-tool-rs" ? "ace-tool-rs" : "ace-tool";
3002
- spinner.succeed(ansis.green(i18n.t("init:installSuccess")));
3003
- console.log();
3004
- console.log(` ${ansis.yellow("\u26A0")} ${toolName} MCP ${i18n.t("init:mcp.notInstalled")} ${ansis.gray(`(${i18n.t("init:mcp.tokenNotProvided")})`)}`);
3005
- console.log(` ${ansis.gray("\u2192")} ${i18n.t("init:mcp.configLater", { cmd: ansis.cyan("npx ccg config mcp") })}`);
3006
- } else {
3007
- spinner.succeed(ansis.green(i18n.t("init:installSuccess")));
3008
2967
  }
3009
2968
  const settingsPath = join(installDir, "settings.json");
3010
2969
  if (apiUrl && apiKey) {
@@ -3015,8 +2974,8 @@ async function init(options = {}) {
3015
2974
  if (!settings.env)
3016
2975
  settings.env = {};
3017
2976
  settings.env.ANTHROPIC_BASE_URL = apiUrl;
3018
- settings.env.ANTHROPIC_API_KEY = apiKey;
3019
- delete settings.env.ANTHROPIC_AUTH_TOKEN;
2977
+ settings.env.ANTHROPIC_AUTH_TOKEN = apiKey;
2978
+ delete settings.env.ANTHROPIC_API_KEY;
3020
2979
  settings.env.DISABLE_TELEMETRY = "1";
3021
2980
  settings.env.DISABLE_ERROR_REPORTING = "1";
3022
2981
  settings.env.CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC = "1";
@@ -3789,7 +3748,7 @@ async function configApi() {
3789
3748
  settings = await fs.readJson(settingsPath);
3790
3749
  }
3791
3750
  const currentUrl = settings.env?.ANTHROPIC_BASE_URL;
3792
- const currentKey = settings.env?.ANTHROPIC_API_KEY || settings.env?.ANTHROPIC_AUTH_TOKEN;
3751
+ const currentKey = settings.env?.ANTHROPIC_AUTH_TOKEN || settings.env?.ANTHROPIC_API_KEY;
3793
3752
  if (currentUrl || currentKey) {
3794
3753
  console.log(ansis.gray(` ${i18n.t("menu:api.currentConfig")}`));
3795
3754
  if (currentUrl)
@@ -3798,32 +3757,44 @@ async function configApi() {
3798
3757
  console.log(ansis.gray(` Key: ${currentKey.slice(0, 8)}...${currentKey.slice(-4)}`));
3799
3758
  console.log();
3800
3759
  }
3801
- const answers = await inquirer.prompt([
3802
- {
3803
- type: "input",
3804
- name: "url",
3805
- message: `${i18n.t("menu:api.urlPrompt")} ${ansis.gray(`(${i18n.t("menu:api.leaveEmptyOfficial")})`)}`,
3806
- default: currentUrl || ""
3807
- },
3808
- {
3809
- type: "password",
3810
- name: "key",
3811
- message: `${i18n.t("menu:api.keyPrompt")} ${ansis.gray(`(${i18n.t("menu:api.leaveEmptySkip")})`)}`,
3812
- mask: "*"
3813
- }
3814
- ]);
3815
- if (!answers.url && !answers.key) {
3816
- console.log(ansis.gray(i18n.t("common:configNotModified")));
3817
- return;
3818
- }
3819
- if (!settings.env)
3820
- settings.env = {};
3821
- if (answers.url?.trim()) {
3822
- settings.env.ANTHROPIC_BASE_URL = answers.url.trim();
3823
- }
3824
- if (answers.key?.trim()) {
3825
- settings.env.ANTHROPIC_API_KEY = answers.key.trim();
3760
+ const { apiProvider } = await inquirer.prompt([{
3761
+ type: "list",
3762
+ name: "apiProvider",
3763
+ message: i18n.t("menu:api.providerPrompt"),
3764
+ choices: [
3765
+ { name: `${ansis.green("\u25CF")} ${i18n.t("menu:api.officialOption")}`, value: "official" },
3766
+ { name: `${ansis.cyan("\u25CF")} ${i18n.t("menu:api.thirdPartyOption")}`, value: "thirdparty" },
3767
+ { name: ansis.gray(`\u25CB ${i18n.t("menu:api.sponsorSlot")}`), value: "sponsor", disabled: i18n.t("menu:api.sponsorDisabled") }
3768
+ ]
3769
+ }]);
3770
+ if (apiProvider === "official") {
3771
+ if (!settings.env)
3772
+ settings.env = {};
3773
+ delete settings.env.ANTHROPIC_BASE_URL;
3826
3774
  delete settings.env.ANTHROPIC_AUTH_TOKEN;
3775
+ delete settings.env.ANTHROPIC_API_KEY;
3776
+ } else {
3777
+ const answers = await inquirer.prompt([
3778
+ {
3779
+ type: "input",
3780
+ name: "url",
3781
+ message: `API URL ${ansis.gray(`(${i18n.t("menu:api.urlRequired")})`)}`,
3782
+ default: currentUrl || "",
3783
+ validate: (v) => v.trim() !== "" || i18n.t("menu:api.enterUrl")
3784
+ },
3785
+ {
3786
+ type: "password",
3787
+ name: "key",
3788
+ message: `API Key ${ansis.gray(`(${i18n.t("menu:api.keyRequired")})`)}`,
3789
+ mask: "*",
3790
+ validate: (v) => v.trim() !== "" || i18n.t("menu:api.enterKey")
3791
+ }
3792
+ ]);
3793
+ if (!settings.env)
3794
+ settings.env = {};
3795
+ settings.env.ANTHROPIC_BASE_URL = answers.url.trim();
3796
+ settings.env.ANTHROPIC_AUTH_TOKEN = answers.key.trim();
3797
+ delete settings.env.ANTHROPIC_API_KEY;
3827
3798
  }
3828
3799
  settings.env.DISABLE_TELEMETRY = "1";
3829
3800
  settings.env.DISABLE_ERROR_REPORTING = "1";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccg-workflow",
3
- "version": "1.7.91",
3
+ "version": "1.7.92",
4
4
  "description": "Claude + Codex + Gemini multi-model collaboration system - smart routing development workflow",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.17.1",