ccg-workflow 1.7.70 → 1.7.72

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/README.md CHANGED
@@ -225,7 +225,7 @@ npm uninstall -g ccg-workflow # npm global users need this extra step
225
225
 
226
226
  ### 1. How to auto-authorize codeagent-wrapper without manual approval?
227
227
 
228
- CCG automatically installs the Hook during setup (v1.7.70+). If you installed an older version, add this to `~/.claude/settings.json`:
228
+ CCG automatically installs the Hook during setup (v1.7.71+). If you installed an older version, add this to `~/.claude/settings.json`:
229
229
 
230
230
  ```json
231
231
  {
@@ -288,4 +288,4 @@ MIT
288
288
 
289
289
  ---
290
290
 
291
- v1.7.70 | [Issues](https://github.com/fengshao1227/ccg-workflow/issues)
291
+ v1.7.72 | [Issues](https://github.com/fengshao1227/ccg-workflow/issues)
package/README.zh-CN.md CHANGED
@@ -227,7 +227,7 @@ npm uninstall -g ccg-workflow # npm 全局用户需额外执行
227
227
 
228
228
  ### 1. 如何让 codeagent-wrapper 无需手动同意即可运行?
229
229
 
230
- v1.7.70+ 安装时会自动写入 Hook。如果你是旧版本用户,可手动在 `~/.claude/settings.json` 中添加:
230
+ v1.7.71+ 安装时会自动写入 Hook。如果你是旧版本用户,可手动在 `~/.claude/settings.json` 中添加:
231
231
 
232
232
  ```json
233
233
  {
@@ -290,4 +290,4 @@ MIT
290
290
 
291
291
  ---
292
292
 
293
- v1.7.70 | [Issues](https://github.com/fengshao1227/ccg-workflow/issues)
293
+ v1.7.72 | [Issues](https://github.com/fengshao1227/ccg-workflow/issues)
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.BPzva2Np.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.HQWqy5Tx.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.BPzva2Np.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.HQWqy5Tx.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.70";
13
+ const version = "1.7.72";
14
14
 
15
15
  function isWindows() {
16
16
  return process.platform === "win32";
@@ -1040,7 +1040,8 @@ async function configMcp() {
1040
1040
  name: "action",
1041
1041
  message: "\u9009\u62E9\u64CD\u4F5C",
1042
1042
  choices: [
1043
- { name: `${ansis.green("\u279C")} \u4EE3\u7801\u68C0\u7D22 MCP ${ansis.gray("(ContextWeaver / ace-tool)")}`, value: "code-retrieval" },
1043
+ { name: `${ansis.green("\u279C")} \u4EE3\u7801\u68C0\u7D22 MCP ${ansis.gray("(ace-tool / ContextWeaver)")}`, value: "code-retrieval" },
1044
+ { name: `${ansis.green("\u279C")} \u8054\u7F51\u641C\u7D22 MCP ${ansis.gray("(grok-search\uFF0C\u6BD4\u5185\u7F6E\u8054\u7F51\u66F4\u597D\u7528)")}`, value: "grok-search" },
1044
1045
  { name: `${ansis.blue("\u279C")} \u8F85\u52A9\u5DE5\u5177 MCP ${ansis.gray("(context7 / Playwright / exa...)")}`, value: "auxiliary" },
1045
1046
  { name: `${ansis.red("\u2715")} \u5378\u8F7D MCP`, value: "uninstall" },
1046
1047
  new inquirer.Separator(),
@@ -1051,6 +1052,8 @@ async function configMcp() {
1051
1052
  return;
1052
1053
  if (action === "code-retrieval") {
1053
1054
  await handleCodeRetrieval();
1055
+ } else if (action === "grok-search") {
1056
+ await handleGrokSearch();
1054
1057
  } else if (action === "auxiliary") {
1055
1058
  await handleAuxiliary();
1056
1059
  } else if (action === "uninstall") {
@@ -1130,6 +1133,98 @@ async function handleInstallContextWeaver() {
1130
1133
  console.log(ansis.red(`\u2717 ContextWeaver MCP \u914D\u7F6E\u5931\u8D25: ${result.message}`));
1131
1134
  }
1132
1135
  }
1136
+ const GROK_SEARCH_PROMPT = `## 0. Language and Format Standards
1137
+
1138
+ - **Interaction Language**: Tools and models must interact exclusively in **English**; user outputs must be in **Chinese**.
1139
+ - MUST ULRTA Thinking in ENGLISH!
1140
+ - **Formatting Requirements**: Use standard Markdown formatting. Code blocks and specific text results should be marked with backticks. Skilled in applying four or more \`\`\`\`markdown wrappers.
1141
+
1142
+ ## 1. Search and Evidence Standards
1143
+ Typically, the results of web searches only constitute third-party suggestions and are not directly credible; they must be cross-verified with sources to provide users with absolutely authoritative and correct answers.
1144
+
1145
+ ### Search Trigger Conditions
1146
+ Strictly distinguish between internal and external knowledge. Avoid speculation based on general internal knowledge. When uncertain, explicitly inform the user.
1147
+
1148
+ For example, when using the \\\`fastapi\\\` library to encapsulate an API endpoint, despite possessing common-sense knowledge internally, you must still rely on the latest search results or official documentation for reliable implementation.
1149
+
1150
+ ### Search Execution Guidelines
1151
+
1152
+ - Use the \\\`mcp__grok-search\\\` tool for web searches
1153
+ - Execute independent search requests in parallel; sequential execution applies only when dependencies exist
1154
+ - Evaluate search results for quality: analyze relevance, source credibility, cross-source consistency, and completeness. Conduct supplementary searches if gaps exist
1155
+
1156
+ ### Source Quality Standards
1157
+
1158
+ - Key factual claims must be supported by >=2 independent sources. If relying on a single source, explicitly state this limitation
1159
+ - Conflicting sources: Present evidence from both sides, assess credibility and timeliness, identify the stronger evidence, or declare unresolved discrepancies
1160
+ - Empirical conclusions must include confidence levels (High/Medium/Low)
1161
+ - Citation format: [Author/Organization, Year/Date, Section/URL]. Fabricated references are strictly prohibited
1162
+
1163
+ ## 2. Reasoning and Expression Principles
1164
+
1165
+ - Be concise, direct, and information-dense: Use lists for discrete items; paragraphs for arguments
1166
+ - Challenge flawed premises: When user logic contains errors, pinpoint specific issues with evidence
1167
+ - All conclusions must specify: Applicable conditions, scope boundaries, and known limitations
1168
+ - Avoid greetings, pleasantries, filler adjectives, and emotional expressions
1169
+ - When uncertain: State unknowns and reasons before presenting confirmed facts
1170
+ `;
1171
+ async function writeGrokPromptToRules() {
1172
+ const rulesDir = join(homedir(), ".claude", "rules");
1173
+ const rulePath = join(rulesDir, "ccg-grok-search.md");
1174
+ const claudeMdPath = join(homedir(), ".claude", "CLAUDE.md");
1175
+ if (await fs.pathExists(claudeMdPath)) {
1176
+ const content = await fs.readFile(claudeMdPath, "utf-8");
1177
+ if (content.includes("CCG-GROK-SEARCH-PROMPT")) {
1178
+ const cleaned = content.replace(/\n*<!-- CCG-GROK-SEARCH-PROMPT-START -->[\s\S]*?<!-- CCG-GROK-SEARCH-PROMPT-END -->\n*/g, "");
1179
+ await fs.writeFile(claudeMdPath, cleaned, "utf-8");
1180
+ }
1181
+ }
1182
+ await fs.ensureDir(rulesDir);
1183
+ await fs.writeFile(rulePath, GROK_SEARCH_PROMPT, "utf-8");
1184
+ }
1185
+ async function handleGrokSearch() {
1186
+ console.log();
1187
+ console.log(ansis.cyan.bold(" \u{1F50D} \u8054\u7F51\u641C\u7D22 MCP (grok-search)"));
1188
+ console.log(ansis.gray(" \u6BD4 Claude Code \u5185\u7F6E\u8054\u7F51\u66F4\u597D\u7528"));
1189
+ console.log();
1190
+ console.log(ansis.cyan(" \u{1F4D6} \u83B7\u53D6 API Keys\uFF1A"));
1191
+ console.log(` Tavily: ${ansis.underline("https://www.tavily.com/")} ${ansis.gray("(\u514D\u8D39\u989D\u5EA6 1000\u6B21/\u6708)")}`);
1192
+ console.log(` Firecrawl: ${ansis.underline("https://www.firecrawl.dev/")} ${ansis.gray("(\u6CE8\u518C\u5373\u9001\u989D\u5EA6)")}`);
1193
+ console.log(` Grok API: ${ansis.gray("\u9700\u81EA\u884C\u90E8\u7F72 grok2api\uFF08\u53EF\u9009\uFF09")}`);
1194
+ console.log();
1195
+ const answers = await inquirer.prompt([
1196
+ { type: "input", name: "grokApiUrl", message: `GROK_API_URL ${ansis.gray("(\u53EF\u9009)")}`, default: "" },
1197
+ { type: "password", name: "grokApiKey", message: `GROK_API_KEY ${ansis.gray("(\u53EF\u9009)")}`, mask: "*" },
1198
+ { type: "password", name: "tavilyKey", message: `TAVILY_API_KEY ${ansis.gray("(\u53EF\u9009)")}`, mask: "*" },
1199
+ { type: "password", name: "firecrawlKey", message: `FIRECRAWL_API_KEY ${ansis.gray("(\u53EF\u9009)")}`, mask: "*" }
1200
+ ]);
1201
+ const env = {};
1202
+ if (answers.grokApiUrl?.trim()) env.GROK_API_URL = answers.grokApiUrl.trim();
1203
+ if (answers.grokApiKey?.trim()) env.GROK_API_KEY = answers.grokApiKey.trim();
1204
+ if (answers.tavilyKey?.trim()) env.TAVILY_API_KEY = answers.tavilyKey.trim();
1205
+ if (answers.firecrawlKey?.trim()) env.FIRECRAWL_API_KEY = answers.firecrawlKey.trim();
1206
+ if (Object.keys(env).length === 0) {
1207
+ console.log(ansis.yellow(" \u672A\u586B\u5199\u4EFB\u4F55 Key\uFF0C\u5DF2\u8DF3\u8FC7"));
1208
+ return;
1209
+ }
1210
+ console.log();
1211
+ console.log(ansis.yellow("\u23F3 \u6B63\u5728\u5B89\u88C5 grok-search MCP..."));
1212
+ const result = await installMcpServer(
1213
+ "grok-search",
1214
+ "uvx",
1215
+ ["--from", "git+https://github.com/GuDaStudio/GrokSearch@grok-with-tavily", "grok-search"],
1216
+ env
1217
+ );
1218
+ console.log();
1219
+ if (result.success) {
1220
+ await writeGrokPromptToRules();
1221
+ console.log(ansis.green("\u2713 grok-search MCP \u914D\u7F6E\u6210\u529F\uFF01"));
1222
+ console.log(ansis.green("\u2713 \u5168\u5C40\u641C\u7D22\u63D0\u793A\u8BCD\u5DF2\u5199\u5165 ~/.claude/rules/ccg-grok-search.md"));
1223
+ console.log(ansis.gray(" \u91CD\u542F Claude Code CLI \u4F7F\u914D\u7F6E\u751F\u6548"));
1224
+ } else {
1225
+ console.log(ansis.red(`\u2717 grok-search MCP \u5B89\u88C5\u5931\u8D25: ${result.message}`));
1226
+ }
1227
+ }
1133
1228
  const AUXILIARY_MCPS = [
1134
1229
  { id: "context7", name: "Context7", desc: "\u83B7\u53D6\u6700\u65B0\u5E93\u6587\u6863", command: "npx", args: ["-y", "@upstash/context7-mcp@latest"] },
1135
1230
  { id: "Playwright", name: "Playwright", desc: "\u6D4F\u89C8\u5668\u81EA\u52A8\u5316/\u6D4B\u8BD5", command: "npx", args: ["-y", "@playwright/mcp@latest"] },
@@ -1184,6 +1279,7 @@ async function handleUninstall() {
1184
1279
  const allMcps = [
1185
1280
  { name: "ace-tool", value: "ace-tool" },
1186
1281
  { name: "ContextWeaver", value: "contextweaver" },
1282
+ { name: "grok-search", value: "grok-search" },
1187
1283
  ...AUXILIARY_MCPS.map((m) => ({ name: m.name, value: m.id }))
1188
1284
  ];
1189
1285
  const { targets } = await inquirer.prompt([{
@@ -1442,6 +1538,25 @@ const zhCN = {
1442
1538
  token: "API Token:",
1443
1539
  installing: "\u6B63\u5728\u914D\u7F6E ace-tool-rs MCP...",
1444
1540
  failed: "ace-tool-rs \u914D\u7F6E\u5931\u8D25\uFF08\u53EF\u7A0D\u540E\u624B\u52A8\u914D\u7F6E\uFF09"
1541
+ },
1542
+ grok: {
1543
+ title: "\u8054\u7F51\u641C\u7D22 MCP (grok-search)",
1544
+ installPrompt: "\u5B89\u88C5 grok \u8054\u7F51\u641C\u7D22 MCP\uFF1F\uFF08\u6BD4 Claude Code \u5185\u7F6E\u8054\u7F51\u66F4\u597D\u7528\uFF09",
1545
+ selectProvider: "\u9009\u62E9\u641C\u7D22\u4FE1\u6E90\uFF08\u4E09\u9009\u4E00\uFF09",
1546
+ custom: "\u81EA\u5B9A\u4E49",
1547
+ customHint: "\u586B\u5199\u81EA\u5B9A\u4E49 API URL + Key",
1548
+ getKeys: "\u83B7\u53D6 API Keys",
1549
+ tavilyHint: "\u514D\u8D39\u989D\u5EA6 1000\u6B21/\u6708",
1550
+ firecrawlHint: "\u6CE8\u518C\u5373\u9001\u989D\u5EA6",
1551
+ grokHint: "\u9700\u81EA\u884C\u90E8\u7F72 grok2api\uFF08\u53EF\u9009\uFF09",
1552
+ enterTavilyKey: "\u8BF7\u8F93\u5165 Tavily API Key",
1553
+ enterFirecrawlKey: "\u8BF7\u8F93\u5165 Firecrawl API Key",
1554
+ installing: "\u6B63\u5728\u5B89\u88C5 grok-search MCP...",
1555
+ installed: "grok-search MCP \u5DF2\u5B89\u88C5",
1556
+ promptAppended: "\u5168\u5C40\u641C\u7D22\u63D0\u793A\u8BCD\u5DF2\u8FFD\u52A0",
1557
+ installFailed: "\u5B89\u88C5\u5931\u8D25",
1558
+ optional: "\u53EF\u9009",
1559
+ required: "\u5FC5\u586B"
1445
1560
  }
1446
1561
  },
1447
1562
  update: {
@@ -1846,6 +1961,25 @@ const en = {
1846
1961
  token: "API Token:",
1847
1962
  installing: "Configuring ace-tool-rs MCP...",
1848
1963
  failed: "ace-tool-rs configuration failed (can be configured manually later)"
1964
+ },
1965
+ grok: {
1966
+ title: "Web Search MCP (grok-search)",
1967
+ installPrompt: "Install grok web search MCP? (Better than CC built-in web search)",
1968
+ selectProvider: "Choose search provider (pick one)",
1969
+ custom: "Custom",
1970
+ customHint: "Enter custom API URL + Key",
1971
+ getKeys: "Get API Keys",
1972
+ tavilyHint: "Free quota: 1000 requests/month",
1973
+ firecrawlHint: "Free credits on signup",
1974
+ grokHint: "Requires self-hosted grok2api (optional)",
1975
+ enterTavilyKey: "Please enter Tavily API Key",
1976
+ enterFirecrawlKey: "Please enter Firecrawl API Key",
1977
+ installing: "Installing grok-search MCP...",
1978
+ installed: "grok-search MCP installed",
1979
+ promptAppended: "Global search prompt appended",
1980
+ installFailed: "Installation failed",
1981
+ optional: "optional",
1982
+ required: "required"
1849
1983
  }
1850
1984
  },
1851
1985
  update: {
@@ -2236,6 +2370,72 @@ async function installHook(settingsPath) {
2236
2370
  await fs.writeJSON(settingsPath, settings, { spaces: 2 });
2237
2371
  }
2238
2372
  }
2373
+ async function appendGrokSearchPrompt() {
2374
+ const rulesDir = join(homedir(), ".claude", "rules");
2375
+ const rulePath = join(rulesDir, "ccg-grok-search.md");
2376
+ const claudeMdPath = join(homedir(), ".claude", "CLAUDE.md");
2377
+ if (await fs.pathExists(claudeMdPath)) {
2378
+ const content = await fs.readFile(claudeMdPath, "utf-8");
2379
+ if (content.includes("CCG-GROK-SEARCH-PROMPT")) {
2380
+ const cleaned = content.replace(/\n*<!-- CCG-GROK-SEARCH-PROMPT-START -->[\s\S]*?<!-- CCG-GROK-SEARCH-PROMPT-END -->\n*/g, "");
2381
+ await fs.writeFile(claudeMdPath, cleaned, "utf-8");
2382
+ }
2383
+ }
2384
+ const prompt = `## 0. Language and Format Standards
2385
+
2386
+ - **Interaction Language**: Tools and models must interact exclusively in **English**; user outputs must be in **Chinese**.
2387
+ - MUST ULRTA Thinking in ENGLISH!
2388
+ - **Formatting Requirements**: Use standard Markdown formatting. Code blocks and specific text results should be marked with backticks. Skilled in applying four or more \`\`\`\`markdown wrappers.
2389
+
2390
+ ## 1. Search and Evidence Standards
2391
+ Typically, the results of web searches only constitute third-party suggestions and are not directly credible; they must be cross-verified with sources to provide users with absolutely authoritative and correct answers.
2392
+
2393
+ ### Search Trigger Conditions
2394
+ Strictly distinguish between internal and external knowledge. Avoid speculation based on general internal knowledge. When uncertain, explicitly inform the user.
2395
+
2396
+ For example, when using the \`fastapi\` library to encapsulate an API endpoint, despite possessing common-sense knowledge internally, you must still rely on the latest search results or official documentation for reliable implementation.
2397
+
2398
+ ### Search Execution Guidelines
2399
+
2400
+ - Use the \`mcp__grok-search\` tool for web searches
2401
+ - Execute independent search requests in parallel; sequential execution applies only when dependencies exist
2402
+ - Evaluate search results for quality: analyze relevance, source credibility, cross-source consistency, and completeness. Conduct supplementary searches if gaps exist
2403
+
2404
+ ### Source Quality Standards
2405
+
2406
+ - Key factual claims must be supported by >=2 independent sources. If relying on a single source, explicitly state this limitation
2407
+ - Conflicting sources: Present evidence from both sides, assess credibility and timeliness, identify the stronger evidence, or declare unresolved discrepancies
2408
+ - Empirical conclusions must include confidence levels (High/Medium/Low)
2409
+ - Citation format: [Author/Organization, Year/Date, Section/URL]. Fabricated references are strictly prohibited
2410
+
2411
+ ## 2. Reasoning and Expression Principles
2412
+
2413
+ - Be concise, direct, and information-dense: Use lists for discrete items; paragraphs for arguments
2414
+ - Challenge flawed premises: When user logic contains errors, pinpoint specific issues with evidence
2415
+ - All conclusions must specify: Applicable conditions, scope boundaries, and known limitations
2416
+ - Avoid greetings, pleasantries, filler adjectives, and emotional expressions
2417
+ - When uncertain: State unknowns and reasons before presenting confirmed facts
2418
+ `;
2419
+ await fs.ensureDir(rulesDir);
2420
+ await fs.writeFile(rulePath, prompt, "utf-8");
2421
+ }
2422
+ async function installGrokSearchMcp(keys) {
2423
+ const env = {};
2424
+ if (keys.tavilyKey)
2425
+ env.TAVILY_API_KEY = keys.tavilyKey;
2426
+ if (keys.firecrawlKey)
2427
+ env.FIRECRAWL_API_KEY = keys.firecrawlKey;
2428
+ if (keys.grokApiUrl)
2429
+ env.GROK_API_URL = keys.grokApiUrl;
2430
+ if (keys.grokApiKey)
2431
+ env.GROK_API_KEY = keys.grokApiKey;
2432
+ return installMcpServer(
2433
+ "grok-search",
2434
+ "uvx",
2435
+ ["--from", "git+https://github.com/GuDaStudio/GrokSearch@grok-with-tavily", "grok-search"],
2436
+ env
2437
+ );
2438
+ }
2239
2439
  async function init(options = {}) {
2240
2440
  console.log();
2241
2441
  console.log(ansis.cyan.bold(` CCG - Claude + Codex + Gemini`));
@@ -2287,23 +2487,23 @@ async function init(options = {}) {
2287
2487
  message: i18n.t("init:mcp.selectProvider"),
2288
2488
  choices: [
2289
2489
  {
2290
- name: `contextweaver ${ansis.green(`(${i18n.t("common:info")})`)} ${ansis.gray(`- ${i18n.t("init:mcp.contextweaver")}`)}`,
2291
- value: "contextweaver"
2292
- },
2293
- {
2294
- name: `ace-tool ${ansis.red(`(${i18n.t("init:mcp.aceToolPaid")})`)} ${ansis.gray("(Node.js) - Augment")}`,
2490
+ name: `ace-tool ${ansis.green(`(${i18n.t("common:info")})`)} ${ansis.gray("- search_context (enhance_prompt N/A)")}`,
2295
2491
  value: "ace-tool"
2296
2492
  },
2297
2493
  {
2298
- name: `ace-tool-rs ${ansis.red(`(${i18n.t("init:mcp.aceToolRsPaid")})`)} ${ansis.gray("(Rust) - " + i18n.t("init:mcp.aceToolRsPaid"))}`,
2494
+ name: `ace-tool-rs ${ansis.green(`(${i18n.t("common:info")})`)} ${ansis.gray("(Rust) - search_context")}`,
2299
2495
  value: "ace-tool-rs"
2300
2496
  },
2497
+ {
2498
+ name: `contextweaver ${ansis.gray(`- ${i18n.t("init:mcp.contextweaver")}`)}`,
2499
+ value: "contextweaver"
2500
+ },
2301
2501
  {
2302
2502
  name: `${i18n.t("init:mcp.skipLater")} ${ansis.gray(`- ${i18n.t("init:mcp.configManually")}`)}`,
2303
2503
  value: "skip"
2304
2504
  }
2305
2505
  ],
2306
- default: "contextweaver"
2506
+ default: "ace-tool"
2307
2507
  }]);
2308
2508
  mcpProvider = selectedMcp;
2309
2509
  if (selectedMcp === "ace-tool" || selectedMcp === "ace-tool-rs") {
@@ -2326,7 +2526,7 @@ async function init(options = {}) {
2326
2526
  console.log(` ${ansis.gray("\u2022")} ${ansis.cyan(i18n.t("init:mcp.officialService"))}: ${ansis.underline("https://augmentcode.com/")}`);
2327
2527
  console.log(` ${ansis.gray(i18n.t("init:mcp.registerForToken"))}`);
2328
2528
  console.log();
2329
- console.log(` ${ansis.gray("\u2022")} ${ansis.cyan(i18n.t("init:mcp.proxyService"))} ${ansis.yellow(`(${i18n.t("init:mcp.noSignup")})`)}: ${ansis.underline("https://linux.do/t/topic/1291730")}`);
2529
+ 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/")}`);
2330
2530
  console.log(` ${ansis.gray(i18n.t("init:mcp.communityProxy"))}`);
2331
2531
  console.log();
2332
2532
  const aceAnswers = await inquirer.prompt([
@@ -2394,6 +2594,42 @@ async function init(options = {}) {
2394
2594
  console.log();
2395
2595
  }
2396
2596
  }
2597
+ let wantGrokSearch = false;
2598
+ let tavilyKey = "";
2599
+ let firecrawlKey = "";
2600
+ let grokApiUrl = "";
2601
+ let grokApiKey = "";
2602
+ if (!options.skipPrompt && !options.skipMcp) {
2603
+ console.log();
2604
+ console.log(ansis.cyan.bold(` \u{1F50D} ${i18n.t("init:grok.title")}`));
2605
+ console.log();
2606
+ const { wantGrok } = await inquirer.prompt([{
2607
+ type: "confirm",
2608
+ name: "wantGrok",
2609
+ message: i18n.t("init:grok.installPrompt"),
2610
+ default: false
2611
+ }]);
2612
+ if (wantGrok) {
2613
+ wantGrokSearch = true;
2614
+ console.log();
2615
+ console.log();
2616
+ console.log(ansis.cyan(` \u{1F4D6} ${i18n.t("init:grok.getKeys")}`));
2617
+ console.log(` Tavily: ${ansis.underline("https://www.tavily.com/")} ${ansis.gray(`(${i18n.t("init:grok.tavilyHint")})`)}`);
2618
+ console.log(` Firecrawl: ${ansis.underline("https://www.firecrawl.dev/")} ${ansis.gray(`(${i18n.t("init:grok.firecrawlHint")})`)}`);
2619
+ console.log(` Grok API: ${ansis.gray(i18n.t("init:grok.grokHint"))}`);
2620
+ console.log();
2621
+ const grokAnswers = await inquirer.prompt([
2622
+ { type: "input", name: "grokApiUrl", message: `GROK_API_URL ${ansis.gray(`(${i18n.t("init:grok.optional")})`)}`, default: "" },
2623
+ { type: "password", name: "grokApiKey", message: `GROK_API_KEY ${ansis.gray(`(${i18n.t("init:grok.optional")})`)}`, mask: "*" },
2624
+ { type: "password", name: "tavilyKey", message: `TAVILY_API_KEY ${ansis.gray(`(${i18n.t("init:grok.optional")})`)}`, mask: "*" },
2625
+ { type: "password", name: "firecrawlKey", message: `FIRECRAWL_API_KEY ${ansis.gray(`(${i18n.t("init:grok.optional")})`)}`, mask: "*" }
2626
+ ]);
2627
+ tavilyKey = grokAnswers.tavilyKey?.trim() || "";
2628
+ firecrawlKey = grokAnswers.firecrawlKey?.trim() || "";
2629
+ grokApiUrl = grokAnswers.grokApiUrl?.trim() || "";
2630
+ grokApiKey = grokAnswers.grokApiKey?.trim() || "";
2631
+ }
2632
+ }
2397
2633
  let apiUrl = "";
2398
2634
  let apiKey = "";
2399
2635
  if (!options.skipPrompt) {
@@ -2468,6 +2704,9 @@ async function init(options = {}) {
2468
2704
  console.log(` ${ansis.cyan(i18n.t("init:summary.commandCount"))} ${ansis.yellow(selectedWorkflows.length.toString())}`);
2469
2705
  console.log(` ${ansis.cyan(i18n.t("init:summary.mcpTool"))} ${mcpProvider === "ace-tool" || mcpProvider === "ace-tool-rs" ? aceToolToken ? ansis.green(mcpProvider) : ansis.yellow(`${mcpProvider} (${i18n.t("init:summary.pendingConfig")})`) : mcpProvider === "contextweaver" ? contextWeaverApiKey ? ansis.green("contextweaver") : ansis.yellow(`contextweaver (${i18n.t("init:summary.pendingConfig")})`) : ansis.gray(i18n.t("init:summary.skipped"))}`);
2470
2706
  console.log(` ${ansis.cyan(i18n.t("init:summary.webUI"))} ${liteMode ? ansis.gray(i18n.t("init:summary.disabled")) : ansis.green(i18n.t("init:summary.enabled"))}`);
2707
+ if (wantGrokSearch) {
2708
+ console.log(` ${ansis.cyan("grok-search")} ${tavilyKey ? ansis.green("\u2713") : ansis.yellow(`(${i18n.t("init:summary.pendingConfig")})`)}`);
2709
+ }
2471
2710
  console.log(ansis.yellow("\u2501".repeat(50)));
2472
2711
  console.log();
2473
2712
  if (!options.skipPrompt && !options.force) {
@@ -2609,6 +2848,25 @@ async function init(options = {}) {
2609
2848
  await installHook(settingsPath);
2610
2849
  console.log();
2611
2850
  console.log(` ${ansis.green("\u2713")} ${i18n.t("init:hooks.installed")}`);
2851
+ if (wantGrokSearch && (tavilyKey || firecrawlKey || grokApiUrl || grokApiKey)) {
2852
+ spinner.text = i18n.t("init:grok.installing");
2853
+ const grokResult = await installGrokSearchMcp({
2854
+ tavilyKey,
2855
+ firecrawlKey,
2856
+ grokApiUrl: grokApiUrl || void 0,
2857
+ grokApiKey: grokApiKey || void 0
2858
+ });
2859
+ if (grokResult.success) {
2860
+ await appendGrokSearchPrompt();
2861
+ console.log();
2862
+ console.log(` ${ansis.green("\u2713")} grok-search MCP ${ansis.gray("\u2192 ~/.claude.json")}`);
2863
+ console.log(` ${ansis.green("\u2713")} ${i18n.t("init:grok.promptAppended")} ${ansis.gray("\u2192 ~/.claude/rules/ccg-grok-search.md")}`);
2864
+ } else {
2865
+ console.log();
2866
+ console.log(` ${ansis.yellow("\u26A0")} grok-search MCP ${i18n.t("init:grok.installFailed")}`);
2867
+ console.log(ansis.gray(` ${grokResult.message}`));
2868
+ }
2869
+ }
2612
2870
  const hasJq = await checkJqAvailable();
2613
2871
  if (!hasJq) {
2614
2872
  console.log();
@@ -2707,7 +2965,7 @@ ${exportCommand}
2707
2965
  console.log(` ${ansis.green("1.")} ${ansis.cyan("ace-tool / ace-tool-rs")}: ${ansis.underline("https://augmentcode.com/")}`);
2708
2966
  console.log(` ${ansis.gray(i18n.t("init:mcp.promptEnhancement"))}`);
2709
2967
  console.log();
2710
- console.log(` ${ansis.green("2.")} ${ansis.cyan("ace-tool " + i18n.t("init:mcp.proxyService"))} ${ansis.yellow(`(${i18n.t("init:mcp.noSignup")})`)}: ${ansis.underline("https://linux.do/t/topic/1291730")}`);
2968
+ console.log(` ${ansis.green("2.")} ${ansis.cyan("ace-tool " + i18n.t("init:mcp.proxyService"))} ${ansis.yellow(`(${i18n.t("init:mcp.noSignup")})`)}: ${ansis.underline("https://acemcp.heroman.wtf/")}`);
2711
2969
  console.log(` ${ansis.gray(i18n.t("init:mcp.communityProxy"))}`);
2712
2970
  console.log();
2713
2971
  console.log(` ${ansis.green("3.")} ${ansis.cyan("ContextWeaver")} ${ansis.yellow(`(${i18n.t("init:mcp.freeQuota")})`)}: ${ansis.underline("https://siliconflow.cn/")}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccg-workflow",
3
- "version": "1.7.70",
3
+ "version": "1.7.72",
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",