ccg-workflow 1.7.69 → 1.7.70

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
@@ -178,8 +178,8 @@ scoop install jq
178
178
  ### MCP Configuration
179
179
 
180
180
  Code retrieval MCP (choose one):
181
- - **ContextWeaver** (recommended) - Local hybrid search, requires SiliconFlow API Key (free)
182
- - **ace-tool** (paid) - Augment official, Token: https://augmentcode.com/
181
+ - **ace-tool** (recommended) - Code search via `search_context` (note: `enhance_prompt` is no longer available). [Official](https://augmentcode.com/) | [Third-party proxy (recommended)](https://acemcp.heroman.wtf/)
182
+ - **ContextWeaver** (alternative) - Local hybrid search, requires SiliconFlow API Key (free)
183
183
 
184
184
  Optional MCP tools:
185
185
  - **Context7** - Latest library documentation
@@ -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.69+). If you installed an older version, add this to `~/.claude/settings.json`:
228
+ CCG automatically installs the Hook during setup (v1.7.70+). 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.69 | [Issues](https://github.com/fengshao1227/ccg-workflow/issues)
291
+ v1.7.70 | [Issues](https://github.com/fengshao1227/ccg-workflow/issues)
package/README.zh-CN.md CHANGED
@@ -180,8 +180,8 @@ scoop install jq
180
180
  ### MCP 配置
181
181
 
182
182
  代码检索 MCP(二选一):
183
- - **ContextWeaver**(推荐)- 本地混合搜索,需要硅基流动 API Key(免费)
184
- - **ace-tool**(收费)- Augment 官方,Token 获取:https://augmentcode.com/
183
+ - **ace-tool**(推荐)- 代码检索 `search_context` 可用(注:`enhance_prompt` 已不可用)。[官方](https://augmentcode.com/) | [第三方中转(推荐)](https://acemcp.heroman.wtf/)
184
+ - **ContextWeaver**(备选)- 本地混合搜索,需要硅基流动 API Key(免费)
185
185
 
186
186
  辅助工具 MCP(可选):
187
187
  - **Context7** - 获取最新库文档
@@ -227,7 +227,7 @@ npm uninstall -g ccg-workflow # npm 全局用户需额外执行
227
227
 
228
228
  ### 1. 如何让 codeagent-wrapper 无需手动同意即可运行?
229
229
 
230
- v1.7.69+ 安装时会自动写入 Hook。如果你是旧版本用户,可手动在 `~/.claude/settings.json` 中添加:
230
+ v1.7.70+ 安装时会自动写入 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.69 | [Issues](https://github.com/fengshao1227/ccg-workflow/issues)
293
+ v1.7.70 | [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.3chn8_4c.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.BPzva2Np.mjs';
5
5
  import 'inquirer';
6
6
  import 'node:child_process';
7
7
  import 'node:util';
@@ -9,9 +9,9 @@ import 'node:os';
9
9
  import 'node:url';
10
10
  import 'pathe';
11
11
  import 'fs-extra';
12
+ import 'smol-toml';
12
13
  import 'i18next';
13
14
  import 'ora';
14
- import 'smol-toml';
15
15
 
16
16
  async function diagnoseMcp() {
17
17
  console.log();
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.3chn8_4c.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.BPzva2Np.mjs';
2
2
  import 'ansis';
3
3
  import 'inquirer';
4
4
  import 'node:child_process';
@@ -7,6 +7,6 @@ import 'node:os';
7
7
  import 'node:url';
8
8
  import 'pathe';
9
9
  import 'fs-extra';
10
+ import 'smol-toml';
10
11
  import 'i18next';
11
12
  import 'ora';
12
- import 'smol-toml';
@@ -6,11 +6,11 @@ import { homedir } from 'node:os';
6
6
  import { fileURLToPath } from 'node:url';
7
7
  import { join, dirname } from 'pathe';
8
8
  import fs from 'fs-extra';
9
+ import { parse, stringify } from 'smol-toml';
9
10
  import i18next from 'i18next';
10
11
  import ora from 'ora';
11
- import { parse, stringify } from 'smol-toml';
12
12
 
13
- const version = "1.7.69";
13
+ const version = "1.7.70";
14
14
 
15
15
  function isWindows() {
16
16
  return process.platform === "win32";
@@ -1064,9 +1064,9 @@ async function handleCodeRetrieval() {
1064
1064
  name: "tool",
1065
1065
  message: "\u9009\u62E9\u4EE3\u7801\u68C0\u7D22\u5DE5\u5177",
1066
1066
  choices: [
1067
- { name: `ContextWeaver ${ansis.green("(\u63A8\u8350)")} ${ansis.gray("- \u672C\u5730\u6DF7\u5408\u641C\u7D22")}`, value: "contextweaver" },
1068
- { name: `ace-tool ${ansis.red("(\u6536\u8D39)")} ${ansis.gray("- Node.js")}`, value: "ace-tool" },
1069
- { name: `ace-tool-rs ${ansis.red("(\u6536\u8D39)")} ${ansis.gray("- Rust")}`, value: "ace-tool-rs" },
1067
+ { name: `ace-tool ${ansis.green("(\u63A8\u8350)")} ${ansis.gray("- \u4EE3\u7801\u68C0\u7D22\uFF08enhance_prompt \u5DF2\u4E0D\u53EF\u7528\uFF09")}`, value: "ace-tool" },
1068
+ { name: `ace-tool-rs ${ansis.green("(\u63A8\u8350)")} ${ansis.gray("- Rust \u7248\u672C")}`, value: "ace-tool-rs" },
1069
+ { name: `ContextWeaver ${ansis.gray("- \u672C\u5730\u6DF7\u5408\u641C\u7D22\uFF08\u9700\u7845\u57FA\u6D41\u52A8 API Key\uFF09")}`, value: "contextweaver" },
1070
1070
  new inquirer.Separator(),
1071
1071
  { name: `${ansis.gray("\u8FD4\u56DE")}`, value: "cancel" }
1072
1072
  ]
@@ -1084,7 +1084,8 @@ async function handleInstallAceTool(isRs) {
1084
1084
  console.log();
1085
1085
  console.log(ansis.cyan(`\u{1F4D6} \u83B7\u53D6 ${toolName} \u8BBF\u95EE\u65B9\u5F0F\uFF1A`));
1086
1086
  console.log(` ${ansis.gray("\u2022")} ${ansis.cyan("\u5B98\u65B9\u670D\u52A1")}: ${ansis.underline("https://augmentcode.com/")}`);
1087
- console.log(` ${ansis.gray("\u2022")} ${ansis.cyan("\u4E2D\u8F6C\u670D\u52A1")} ${ansis.yellow("(\u65E0\u9700\u6CE8\u518C)")}: ${ansis.underline("https://linux.do/t/topic/1291730")}`);
1087
+ console.log(` ${ansis.gray("\u2022")} ${ansis.cyan("\u7B2C\u4E09\u65B9\u4E2D\u8F6C")} ${ansis.green("(\u63A8\u8350)")}: ${ansis.underline("https://acemcp.heroman.wtf/")}`);
1088
+ console.log(` ${ansis.gray("\u26A0")} ${ansis.yellow("\u6CE8\u610F")}: enhance_prompt \u5DF2\u4E0D\u53EF\u7528\uFF0Csearch_context \u4EE3\u7801\u68C0\u7D22\u6B63\u5E38`);
1088
1089
  console.log();
1089
1090
  const answers = await inquirer.prompt([
1090
1091
  { type: "input", name: "baseUrl", message: `Base URL ${ansis.gray("(\u4E2D\u8F6C\u670D\u52A1\u5FC5\u586B\uFF0C\u5B98\u65B9\u7559\u7A7A)")}` },
@@ -2985,60 +2986,147 @@ async function performUpdate(fromVersion, toVersion, isNewVersion) {
2985
2986
  }
2986
2987
 
2987
2988
  const execAsync = promisify(exec);
2989
+ function visWidth(s) {
2990
+ const stripped = s.replace(/\x1B\[[0-9;]*m/g, "");
2991
+ let w = 0;
2992
+ for (const ch of stripped) {
2993
+ const code = ch.codePointAt(0) || 0;
2994
+ if (code >= 11904 && code <= 40959 || code >= 63744 && code <= 64255 || code >= 65072 && code <= 65103 || code >= 65280 && code <= 65376 || code >= 65504 && code <= 65510 || code >= 127744 && code <= 129535 || code >= 131072 && code <= 195103) {
2995
+ w += 2;
2996
+ } else {
2997
+ w += 1;
2998
+ }
2999
+ }
3000
+ return w;
3001
+ }
3002
+ function pad(s, w) {
3003
+ const diff = w - visWidth(s);
3004
+ return diff > 0 ? s + " ".repeat(diff) : s;
3005
+ }
3006
+ const INNER_W = 60;
3007
+ function centerLine(s, w) {
3008
+ const vis = visWidth(s);
3009
+ const left = Math.max(0, Math.floor((w - vis) / 2));
3010
+ const right = Math.max(0, w - vis - left);
3011
+ return " ".repeat(left) + s + " ".repeat(right);
3012
+ }
3013
+ function boxRow(content) {
3014
+ const vis = visWidth(content);
3015
+ const gap = Math.max(0, INNER_W - vis);
3016
+ return ansis.cyan("\u2551") + content + " ".repeat(gap) + ansis.cyan("\u2551");
3017
+ }
3018
+ function drawHeader(statusParts) {
3019
+ const top = ansis.cyan("\u2554" + "\u2550".repeat(INNER_W) + "\u2557");
3020
+ const bot = ansis.cyan("\u255A" + "\u2550".repeat(INNER_W) + "\u255D");
3021
+ const empty = boxRow(" ".repeat(INNER_W));
3022
+ const logo = [
3023
+ " \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 ",
3024
+ " \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D \u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D ",
3025
+ " \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2588\u2557",
3026
+ " \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551",
3027
+ " \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D",
3028
+ " \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D "
3029
+ ];
3030
+ console.log();
3031
+ console.log(top);
3032
+ console.log(empty);
3033
+ for (const line of logo) {
3034
+ console.log(boxRow(centerLine(ansis.bold.white(line), INNER_W)));
3035
+ }
3036
+ console.log(empty);
3037
+ console.log(boxRow(centerLine(ansis.gray("Claude + Codex + Gemini"), INNER_W)));
3038
+ console.log(boxRow(centerLine(ansis.gray("Multi-Model Collaboration"), INNER_W)));
3039
+ console.log(empty);
3040
+ if (statusParts.length > 0) {
3041
+ const statusLine = statusParts.join(ansis.gray(" | "));
3042
+ console.log(boxRow(centerLine(statusLine, INNER_W)));
3043
+ console.log(empty);
3044
+ }
3045
+ console.log(bot);
3046
+ console.log();
3047
+ }
3048
+ function groupSep(label) {
3049
+ const w = 42;
3050
+ const labelW = visWidth(label);
3051
+ const remaining = Math.max(0, w - labelW - 2);
3052
+ const left = Math.floor(remaining / 2);
3053
+ const right = remaining - left;
3054
+ return new inquirer.Separator(ansis.gray(`${"\u2500".repeat(left)} ${label} ${"\u2500".repeat(right)}`));
3055
+ }
2988
3056
  async function showMainMenu() {
2989
3057
  while (true) {
2990
- console.log();
2991
- console.log(ansis.cyan.bold(` CCG - Claude + Codex + Gemini`));
2992
- console.log(ansis.gray(" Multi-Model Collaboration System"));
2993
- console.log();
3058
+ const config = await readCcgConfig();
3059
+ const cmdCount = config?.workflows?.installed?.length || 0;
3060
+ const lang = config?.general?.language || "zh-CN";
3061
+ const mcpProvider = config?.mcp?.provider || "\u2014";
3062
+ const statusParts = [
3063
+ ansis.green(`v${version}`),
3064
+ ansis.white(`${cmdCount} commands`),
3065
+ ansis.yellow(lang)
3066
+ ];
3067
+ if (mcpProvider !== "\u2014" && mcpProvider !== "skip") {
3068
+ statusParts.push(ansis.magenta(mcpProvider));
3069
+ }
3070
+ drawHeader(statusParts);
3071
+ const isZh = lang === "zh-CN";
3072
+ const item = (key, label, desc) => ({
3073
+ name: ` ${ansis.green(key + ".")} ${pad(label, 20)} ${ansis.gray("- " + desc)}`,
3074
+ value: key
3075
+ });
2994
3076
  const { action } = await inquirer.prompt([{
2995
3077
  type: "list",
2996
3078
  name: "action",
2997
3079
  message: i18n.t("menu:title"),
3080
+ pageSize: 20,
2998
3081
  choices: [
2999
- { name: `${ansis.green("\u279C")} ${i18n.t("menu:options.init")}`, value: "init" },
3000
- { name: `${ansis.blue("\u279C")} ${i18n.t("menu:options.update")}`, value: "update" },
3001
- { name: `${ansis.cyan("\u2699")} ${i18n.t("menu:options.configMcp")}`, value: "config-mcp" },
3002
- { name: `${ansis.cyan("\u{1F511}")} ${i18n.t("menu:options.configApi")}`, value: "config-api" },
3003
- { name: `${ansis.magenta("\u{1F3AD}")} ${i18n.t("menu:options.configStyle")}`, value: "config-style" },
3004
- { name: `${ansis.yellow("\u{1F527}")} ${i18n.t("menu:options.tools")}`, value: "tools" },
3005
- { name: `${ansis.blue("\u{1F4E6}")} ${i18n.t("menu:options.installClaude")}`, value: "install-claude" },
3006
- { name: `${ansis.magenta("\u279C")} ${i18n.t("menu:options.uninstall")}`, value: "uninstall" },
3007
- { name: `${ansis.yellow("?")} ${i18n.t("menu:options.help")}`, value: "help" },
3008
- new inquirer.Separator(),
3009
- { name: `${ansis.red("\u2715")} ${i18n.t("menu:options.exit")}`, value: "exit" }
3082
+ groupSep(isZh ? "Claude Code" : "Claude Code"),
3083
+ item("1", i18n.t("menu:options.init"), isZh ? "\u5B89\u88C5 CCG \u5DE5\u4F5C\u6D41" : "Install CCG workflows"),
3084
+ item("2", i18n.t("menu:options.update"), isZh ? "\u66F4\u65B0\u5230\u6700\u65B0\u7248\u672C" : "Update to latest version"),
3085
+ item("3", i18n.t("menu:options.configMcp"), isZh ? "\u4EE3\u7801\u68C0\u7D22 MCP \u5DE5\u5177" : "Code retrieval MCP tool"),
3086
+ item("4", i18n.t("menu:options.configApi"), isZh ? "\u81EA\u5B9A\u4E49 API \u7AEF\u70B9" : "Custom API endpoint"),
3087
+ item("5", i18n.t("menu:options.configStyle"), isZh ? "\u9009\u62E9\u8F93\u51FA\u4EBA\u683C" : "Choose output personality"),
3088
+ groupSep(isZh ? "\u5176\u4ED6\u5DE5\u5177" : "Tools"),
3089
+ item("T", i18n.t("menu:options.tools"), "ccusage, CCometixLine"),
3090
+ item("C", i18n.t("menu:options.installClaude"), isZh ? "\u5B89\u88C5/\u91CD\u88C5 CLI" : "Install/reinstall CLI"),
3091
+ groupSep("CCG"),
3092
+ item("H", i18n.t("menu:options.help"), isZh ? "\u67E5\u770B\u5168\u90E8\u659C\u6760\u547D\u4EE4" : "View all slash commands"),
3093
+ item("-", i18n.t("menu:options.uninstall"), isZh ? "\u79FB\u9664 CCG \u914D\u7F6E" : "Remove CCG config"),
3094
+ new inquirer.Separator(ansis.gray("\u2500".repeat(42))),
3095
+ { name: ` ${ansis.red("Q.")} ${i18n.t("menu:options.exit")}`, value: "Q" }
3010
3096
  ]
3011
3097
  }]);
3012
3098
  switch (action) {
3013
- case "init":
3099
+ case "1":
3014
3100
  await init();
3015
3101
  break;
3016
- case "update":
3102
+ case "2":
3017
3103
  await update();
3018
3104
  break;
3019
- case "config-mcp":
3105
+ case "3":
3020
3106
  await configMcp();
3021
3107
  break;
3022
- case "config-api":
3108
+ case "4":
3023
3109
  await configApi();
3024
3110
  break;
3025
- case "config-style":
3111
+ case "5":
3026
3112
  await configOutputStyle();
3027
3113
  break;
3028
- case "tools":
3114
+ case "T":
3029
3115
  await handleTools();
3030
3116
  break;
3031
- case "install-claude":
3117
+ case "C":
3032
3118
  await handleInstallClaude();
3033
3119
  break;
3034
- case "uninstall":
3120
+ case "-":
3035
3121
  await uninstall();
3036
3122
  break;
3037
- case "help":
3123
+ case "H":
3038
3124
  showHelp();
3039
3125
  break;
3040
- case "exit":
3041
- console.log(ansis.gray(i18n.t("common:goodbye")));
3126
+ case "Q":
3127
+ console.log();
3128
+ console.log(ansis.gray(` ${i18n.t("common:goodbye")}`));
3129
+ console.log();
3042
3130
  return;
3043
3131
  }
3044
3132
  console.log();
@@ -3050,41 +3138,63 @@ async function showMainMenu() {
3050
3138
  }
3051
3139
  }
3052
3140
  function showHelp() {
3141
+ const config = readCcgConfigSync();
3142
+ const isZh = (config?.general?.language || "zh-CN") === "zh-CN";
3053
3143
  console.log();
3054
- console.log(ansis.cyan.bold(i18n.t("menu:help.title")));
3144
+ console.log(ansis.cyan.bold(` ${i18n.t("menu:help.title")}`));
3055
3145
  console.log();
3056
- console.log(ansis.yellow.bold(` ${i18n.t("menu:help.sections.devWorkflow")}`));
3057
- console.log(` ${ansis.green("/ccg:workflow")} ${i18n.t("menu:help.descriptions.workflow")}`);
3058
- console.log(` ${ansis.green("/ccg:plan")} ${i18n.t("menu:help.descriptions.plan")}`);
3059
- console.log(` ${ansis.green("/ccg:execute")} ${i18n.t("menu:help.descriptions.execute")}`);
3060
- console.log(` ${ansis.green("/ccg:frontend")} ${i18n.t("menu:help.descriptions.frontend")}`);
3061
- console.log(` ${ansis.green("/ccg:backend")} ${i18n.t("menu:help.descriptions.backend")}`);
3062
- console.log(` ${ansis.green("/ccg:feat")} ${i18n.t("menu:help.descriptions.feat")}`);
3063
- console.log(` ${ansis.green("/ccg:analyze")} ${i18n.t("menu:help.descriptions.analyze")}`);
3064
- console.log(` ${ansis.green("/ccg:debug")} ${i18n.t("menu:help.descriptions.debug")}`);
3065
- console.log(` ${ansis.green("/ccg:optimize")} ${i18n.t("menu:help.descriptions.optimize")}`);
3066
- console.log(` ${ansis.green("/ccg:test")} ${i18n.t("menu:help.descriptions.test")}`);
3067
- console.log(` ${ansis.green("/ccg:review")} ${i18n.t("menu:help.descriptions.review")}`);
3146
+ const col1 = 22;
3147
+ const section = (title) => console.log(ansis.yellow.bold(` ${title}`));
3148
+ const cmd = (name, desc) => console.log(` ${ansis.green(name.padEnd(col1))} ${ansis.gray(desc)}`);
3149
+ section(i18n.t("menu:help.sections.devWorkflow"));
3150
+ cmd("/ccg:workflow", i18n.t("menu:help.descriptions.workflow"));
3151
+ cmd("/ccg:plan", i18n.t("menu:help.descriptions.plan"));
3152
+ cmd("/ccg:execute", i18n.t("menu:help.descriptions.execute"));
3153
+ cmd("/ccg:frontend", i18n.t("menu:help.descriptions.frontend"));
3154
+ cmd("/ccg:backend", i18n.t("menu:help.descriptions.backend"));
3155
+ cmd("/ccg:feat", i18n.t("menu:help.descriptions.feat"));
3156
+ cmd("/ccg:analyze", i18n.t("menu:help.descriptions.analyze"));
3157
+ cmd("/ccg:debug", i18n.t("menu:help.descriptions.debug"));
3158
+ cmd("/ccg:optimize", i18n.t("menu:help.descriptions.optimize"));
3159
+ cmd("/ccg:test", i18n.t("menu:help.descriptions.test"));
3160
+ cmd("/ccg:review", i18n.t("menu:help.descriptions.review"));
3068
3161
  console.log();
3069
- console.log(ansis.yellow.bold(` ${i18n.t("menu:help.sections.opsx")}`));
3070
- console.log(` ${ansis.green("/ccg:spec-init")} ${i18n.t("menu:help.descriptions.specInit")}`);
3071
- console.log(` ${ansis.green("/ccg:spec-research")} ${i18n.t("menu:help.descriptions.specResearch")}`);
3072
- console.log(` ${ansis.green("/ccg:spec-plan")} ${i18n.t("menu:help.descriptions.specPlan")}`);
3073
- console.log(` ${ansis.green("/ccg:spec-impl")} ${i18n.t("menu:help.descriptions.specImpl")}`);
3074
- console.log(` ${ansis.green("/ccg:spec-review")} ${i18n.t("menu:help.descriptions.specReview")}`);
3162
+ section(isZh ? "Agent Teams \u5E76\u884C\u5B9E\u65BD:" : "Agent Teams Parallel:");
3163
+ cmd("/ccg:team-research", isZh ? "\u9700\u6C42 \u2192 \u7EA6\u675F\u96C6" : "Requirements \u2192 Constraints");
3164
+ cmd("/ccg:team-plan", isZh ? "\u7EA6\u675F \u2192 \u5E76\u884C\u8BA1\u5212" : "Constraints \u2192 Parallel plan");
3165
+ cmd("/ccg:team-exec", isZh ? "\u5E76\u884C\u5B9E\u65BD" : "Parallel execution");
3166
+ cmd("/ccg:team-review", isZh ? "\u53CC\u6A21\u578B\u5BA1\u67E5" : "Dual-model review");
3075
3167
  console.log();
3076
- console.log(ansis.yellow.bold(` ${i18n.t("menu:help.sections.gitTools")}`));
3077
- console.log(` ${ansis.green("/ccg:commit")} ${i18n.t("menu:help.descriptions.commit")}`);
3078
- console.log(` ${ansis.green("/ccg:rollback")} ${i18n.t("menu:help.descriptions.rollback")}`);
3079
- console.log(` ${ansis.green("/ccg:clean-branches")} ${i18n.t("menu:help.descriptions.cleanBranches")}`);
3080
- console.log(` ${ansis.green("/ccg:worktree")} ${i18n.t("menu:help.descriptions.worktree")}`);
3168
+ section(i18n.t("menu:help.sections.opsx"));
3169
+ cmd("/ccg:spec-init", i18n.t("menu:help.descriptions.specInit"));
3170
+ cmd("/ccg:spec-research", i18n.t("menu:help.descriptions.specResearch"));
3171
+ cmd("/ccg:spec-plan", i18n.t("menu:help.descriptions.specPlan"));
3172
+ cmd("/ccg:spec-impl", i18n.t("menu:help.descriptions.specImpl"));
3173
+ cmd("/ccg:spec-review", i18n.t("menu:help.descriptions.specReview"));
3081
3174
  console.log();
3082
- console.log(ansis.yellow.bold(` ${i18n.t("menu:help.sections.projectMgmt")}`));
3083
- console.log(` ${ansis.green("/ccg:init")} ${i18n.t("menu:help.descriptions.init")}`);
3175
+ section(i18n.t("menu:help.sections.gitTools"));
3176
+ cmd("/ccg:commit", i18n.t("menu:help.descriptions.commit"));
3177
+ cmd("/ccg:rollback", i18n.t("menu:help.descriptions.rollback"));
3178
+ cmd("/ccg:clean-branches", i18n.t("menu:help.descriptions.cleanBranches"));
3179
+ cmd("/ccg:worktree", i18n.t("menu:help.descriptions.worktree"));
3084
3180
  console.log();
3085
- console.log(ansis.gray(i18n.t("menu:help.hint")));
3181
+ section(i18n.t("menu:help.sections.projectMgmt"));
3182
+ cmd("/ccg:init", i18n.t("menu:help.descriptions.init"));
3183
+ cmd("/ccg:enhance", isZh ? "Prompt \u589E\u5F3A" : "Prompt enhancement");
3184
+ console.log();
3185
+ console.log(ansis.gray(` ${i18n.t("menu:help.hint")}`));
3086
3186
  console.log();
3087
3187
  }
3188
+ function readCcgConfigSync() {
3189
+ try {
3190
+ const configPath = join(homedir(), ".claude", ".ccg", "config.toml");
3191
+ if (fs.pathExistsSync(configPath)) {
3192
+ return parse(fs.readFileSync(configPath, "utf-8"));
3193
+ }
3194
+ } catch {
3195
+ }
3196
+ return null;
3197
+ }
3088
3198
  async function configApi() {
3089
3199
  console.log();
3090
3200
  console.log(ansis.cyan.bold(` ${i18n.t("menu:api.title")}`));
@@ -3151,8 +3261,8 @@ async function configApi() {
3151
3261
  await fs.ensureDir(join(homedir(), ".claude"));
3152
3262
  await fs.writeJson(settingsPath, settings, { spaces: 2 });
3153
3263
  console.log();
3154
- console.log(ansis.green(`\u2713 ${i18n.t("menu:api.saved")}`));
3155
- console.log(ansis.gray(` ${i18n.t("common:configFile")}: ${settingsPath}`));
3264
+ console.log(ansis.green(` \u2713 ${i18n.t("menu:api.saved")}`));
3265
+ console.log(ansis.gray(` ${i18n.t("common:configFile")}: ${settingsPath}`));
3156
3266
  }
3157
3267
  const OUTPUT_STYLES = [
3158
3268
  { id: "default", nameKey: "menu:style.default", descKey: "menu:style.defaultDesc" },
@@ -3201,7 +3311,7 @@ async function configOutputStyle() {
3201
3311
  const destPath = join(outputStylesDir, `${style}.md`);
3202
3312
  if (await fs.pathExists(templatePath)) {
3203
3313
  await fs.copy(templatePath, destPath);
3204
- console.log(ansis.green(`\u2713 ${i18n.t("menu:style.installed", { style })}`));
3314
+ console.log(ansis.green(` \u2713 ${i18n.t("menu:style.installed", { style })}`));
3205
3315
  }
3206
3316
  }
3207
3317
  if (style === "default") {
@@ -3211,8 +3321,8 @@ async function configOutputStyle() {
3211
3321
  }
3212
3322
  await fs.writeJson(settingsPath, settings, { spaces: 2 });
3213
3323
  console.log();
3214
- console.log(ansis.green(`\u2713 ${i18n.t("menu:style.set", { style })}`));
3215
- console.log(ansis.gray(` ${i18n.t("common:restartToApply")}`));
3324
+ console.log(ansis.green(` \u2713 ${i18n.t("menu:style.set", { style })}`));
3325
+ console.log(ansis.gray(` ${i18n.t("common:restartToApply")}`));
3216
3326
  }
3217
3327
  async function handleInstallClaude() {
3218
3328
  console.log();
@@ -3226,7 +3336,7 @@ async function handleInstallClaude() {
3226
3336
  isInstalled = false;
3227
3337
  }
3228
3338
  if (isInstalled) {
3229
- console.log(ansis.yellow(`\u26A0 ${i18n.t("menu:claude.alreadyInstalled")}`));
3339
+ console.log(ansis.yellow(` \u26A0 ${i18n.t("menu:claude.alreadyInstalled")}`));
3230
3340
  const { confirm } = await inquirer.prompt([{
3231
3341
  type: "confirm",
3232
3342
  name: "confirm",
@@ -3234,17 +3344,17 @@ async function handleInstallClaude() {
3234
3344
  default: false
3235
3345
  }]);
3236
3346
  if (!confirm) {
3237
- console.log(ansis.gray(i18n.t("common:cancelled")));
3347
+ console.log(ansis.gray(` ${i18n.t("common:cancelled")}`));
3238
3348
  return;
3239
3349
  }
3240
3350
  console.log();
3241
- console.log(ansis.yellow(`\u23F3 ${i18n.t("menu:claude.uninstalling")}`));
3351
+ console.log(ansis.yellow(` \u23F3 ${i18n.t("menu:claude.uninstalling")}`));
3242
3352
  try {
3243
3353
  const uninstallCmd = isWindows() ? "npm uninstall -g @anthropic-ai/claude-code" : "sudo npm uninstall -g @anthropic-ai/claude-code";
3244
3354
  await execAsync(uninstallCmd, { timeout: 6e4 });
3245
- console.log(ansis.green(`\u2713 ${i18n.t("menu:claude.uninstallSuccess")}`));
3355
+ console.log(ansis.green(` \u2713 ${i18n.t("menu:claude.uninstallSuccess")}`));
3246
3356
  } catch (e) {
3247
- console.log(ansis.red(`\u2717 ${i18n.t("menu:claude.uninstallFailed", { error: String(e) })}`));
3357
+ console.log(ansis.red(` \u2717 ${i18n.t("menu:claude.uninstallFailed", { error: String(e) })}`));
3248
3358
  return;
3249
3359
  }
3250
3360
  }
@@ -3255,7 +3365,7 @@ async function handleInstallClaude() {
3255
3365
  name: "method",
3256
3366
  message: i18n.t("menu:claude.selectMethod"),
3257
3367
  choices: [
3258
- { name: `npm ${ansis.green(`(${i18n.t("menu:claude.npmRecommended")})`)} ${ansis.gray("- npm install -g")}`, value: "npm" },
3368
+ { name: `npm ${ansis.green("(\u2B50)")} ${ansis.gray("- npm install -g")}`, value: "npm" },
3259
3369
  ...isMac || isLinux ? [{ name: `homebrew ${ansis.gray("- brew install")}`, value: "homebrew" }] : [],
3260
3370
  ...isMac || isLinux ? [{ name: `curl ${ansis.gray("- official script")}`, value: "curl" }] : [],
3261
3371
  ...isWindows() ? [
@@ -3269,7 +3379,7 @@ async function handleInstallClaude() {
3269
3379
  if (method === "cancel")
3270
3380
  return;
3271
3381
  console.log();
3272
- console.log(ansis.yellow(`\u23F3 ${i18n.t("menu:claude.installing")}`));
3382
+ console.log(ansis.yellow(` \u23F3 ${i18n.t("menu:claude.installing")}`));
3273
3383
  try {
3274
3384
  if (method === "npm") {
3275
3385
  const installCmd = isWindows() ? "npm install -g @anthropic-ai/claude-code" : "sudo npm install -g @anthropic-ai/claude-code";
@@ -3283,11 +3393,11 @@ async function handleInstallClaude() {
3283
3393
  } else if (method === "cmd") {
3284
3394
  await execAsync('cmd /c "curl -fsSL https://claude.ai/install.cmd -o install.cmd && install.cmd && del install.cmd"', { timeout: 3e5 });
3285
3395
  }
3286
- console.log(ansis.green(`\u2713 ${i18n.t("menu:claude.installSuccess")}`));
3396
+ console.log(ansis.green(` \u2713 ${i18n.t("menu:claude.installSuccess")}`));
3287
3397
  console.log();
3288
- console.log(ansis.cyan(`\u{1F4A1} ${i18n.t("menu:claude.runHint")}`));
3398
+ console.log(ansis.cyan(` \u{1F4A1} ${i18n.t("menu:claude.runHint")}`));
3289
3399
  } catch (e) {
3290
- console.log(ansis.red(`\u2717 ${i18n.t("menu:claude.installFailed", { error: String(e) })}`));
3400
+ console.log(ansis.red(` \u2717 ${i18n.t("menu:claude.installFailed", { error: String(e) })}`));
3291
3401
  }
3292
3402
  }
3293
3403
  async function checkIfGlobalInstall() {
@@ -3302,11 +3412,11 @@ async function uninstall() {
3302
3412
  console.log();
3303
3413
  const isGlobalInstall = await checkIfGlobalInstall();
3304
3414
  if (isGlobalInstall) {
3305
- console.log(ansis.yellow(`\u26A0\uFE0F ${i18n.t("menu:uninstall.globalDetected")}`));
3415
+ console.log(ansis.yellow(` \u26A0\uFE0F ${i18n.t("menu:uninstall.globalDetected")}`));
3306
3416
  console.log();
3307
- console.log(i18n.t("menu:uninstall.twoSteps"));
3308
- console.log(` ${ansis.cyan(`1. ${i18n.t("menu:uninstall.step1")}`)} (${i18n.t("menu:uninstall.step1Hint")})`);
3309
- console.log(` ${ansis.cyan(`2. ${i18n.t("menu:uninstall.step2")}`)} (${i18n.t("menu:uninstall.step2Hint")})`);
3417
+ console.log(` ${i18n.t("menu:uninstall.twoSteps")}`);
3418
+ console.log(` ${ansis.cyan(`1. ${i18n.t("menu:uninstall.step1")}`)} ${ansis.gray(`(${i18n.t("menu:uninstall.step1Hint")})`)}`);
3419
+ console.log(` ${ansis.cyan(`2. ${i18n.t("menu:uninstall.step2")}`)} ${ansis.gray(`(${i18n.t("menu:uninstall.step2Hint")})`)}`);
3310
3420
  console.log();
3311
3421
  }
3312
3422
  const { confirm } = await inquirer.prompt([{
@@ -3316,53 +3426,53 @@ async function uninstall() {
3316
3426
  default: false
3317
3427
  }]);
3318
3428
  if (!confirm) {
3319
- console.log(ansis.gray(i18n.t("menu:uninstall.cancelled")));
3429
+ console.log(ansis.gray(` ${i18n.t("menu:uninstall.cancelled")}`));
3320
3430
  return;
3321
3431
  }
3322
3432
  console.log();
3323
- console.log(ansis.yellow(i18n.t("menu:uninstall.uninstalling")));
3433
+ console.log(ansis.yellow(` ${i18n.t("menu:uninstall.uninstalling")}`));
3324
3434
  const installDir = join(homedir(), ".claude");
3325
3435
  const result = await uninstallWorkflows(installDir);
3326
3436
  if (result.success) {
3327
- console.log(ansis.green(`\u2705 ${i18n.t("menu:uninstall.success")}`));
3437
+ console.log(ansis.green(` \u2705 ${i18n.t("menu:uninstall.success")}`));
3328
3438
  if (result.removedCommands.length > 0) {
3329
3439
  console.log();
3330
- console.log(ansis.cyan(i18n.t("menu:uninstall.removedCommands")));
3440
+ console.log(ansis.cyan(` ${i18n.t("menu:uninstall.removedCommands")}`));
3331
3441
  for (const cmd of result.removedCommands) {
3332
- console.log(` ${ansis.gray("\u2022")} /ccg:${cmd}`);
3442
+ console.log(` ${ansis.gray("\u2022")} /ccg:${cmd}`);
3333
3443
  }
3334
3444
  }
3335
3445
  if (result.removedAgents.length > 0) {
3336
3446
  console.log();
3337
- console.log(ansis.cyan(i18n.t("menu:uninstall.removedAgents")));
3447
+ console.log(ansis.cyan(` ${i18n.t("menu:uninstall.removedAgents")}`));
3338
3448
  for (const agent of result.removedAgents) {
3339
- console.log(` ${ansis.gray("\u2022")} ${agent}`);
3449
+ console.log(` ${ansis.gray("\u2022")} ${agent}`);
3340
3450
  }
3341
3451
  }
3342
3452
  if (result.removedSkills.length > 0) {
3343
3453
  console.log();
3344
- console.log(ansis.cyan(i18n.t("menu:uninstall.removedSkills")));
3345
- console.log(` ${ansis.gray("\u2022")} multi-model-collaboration`);
3454
+ console.log(ansis.cyan(` ${i18n.t("menu:uninstall.removedSkills")}`));
3455
+ console.log(` ${ansis.gray("\u2022")} multi-model-collaboration`);
3346
3456
  }
3347
3457
  if (result.removedBin) {
3348
3458
  console.log();
3349
- console.log(ansis.cyan(i18n.t("menu:uninstall.removedBin")));
3350
- console.log(` ${ansis.gray("\u2022")} codeagent-wrapper`);
3459
+ console.log(ansis.cyan(` ${i18n.t("menu:uninstall.removedBin")}`));
3460
+ console.log(` ${ansis.gray("\u2022")} codeagent-wrapper`);
3351
3461
  }
3352
3462
  if (isGlobalInstall) {
3353
3463
  console.log();
3354
- console.log(ansis.yellow.bold(`\u{1F538} ${i18n.t("menu:uninstall.lastStep")}`));
3464
+ console.log(ansis.yellow.bold(` \u{1F538} ${i18n.t("menu:uninstall.lastStep")}`));
3355
3465
  console.log();
3356
- console.log(i18n.t("menu:uninstall.runInNewTerminal"));
3466
+ console.log(` ${i18n.t("menu:uninstall.runInNewTerminal")}`);
3357
3467
  console.log();
3358
- console.log(ansis.cyan.bold(" npm uninstall -g ccg-workflow"));
3468
+ console.log(ansis.cyan.bold(" npm uninstall -g ccg-workflow"));
3359
3469
  console.log();
3360
- console.log(ansis.gray(`(${i18n.t("menu:uninstall.afterDone")})`));
3470
+ console.log(ansis.gray(` (${i18n.t("menu:uninstall.afterDone")})`));
3361
3471
  }
3362
3472
  } else {
3363
- console.log(ansis.red(i18n.t("menu:uninstall.failed")));
3473
+ console.log(ansis.red(` ${i18n.t("menu:uninstall.failed")}`));
3364
3474
  for (const error of result.errors) {
3365
- console.log(ansis.red(` ${error}`));
3475
+ console.log(ansis.red(` ${error}`));
3366
3476
  }
3367
3477
  }
3368
3478
  console.log();
@@ -3374,10 +3484,10 @@ async function handleTools() {
3374
3484
  name: "tool",
3375
3485
  message: i18n.t("menu:tools.title"),
3376
3486
  choices: [
3377
- { name: `${ansis.green("\u{1F4CA}")} ccusage ${ansis.gray(`- ${i18n.t("menu:tools.ccusage")}`)}`, value: "ccusage" },
3378
- { name: `${ansis.blue("\u{1F4DF}")} CCometixLine ${ansis.gray(`- ${i18n.t("menu:tools.ccline")}`)}`, value: "ccline" },
3487
+ { name: `${ansis.green("\u{1F4CA}")} ccusage ${ansis.gray(`${i18n.t("menu:tools.ccusage")}`)}`, value: "ccusage" },
3488
+ { name: `${ansis.blue("\u{1F4DF}")} CCometixLine ${ansis.gray(`${i18n.t("menu:tools.ccline")}`)}`, value: "ccline" },
3379
3489
  new inquirer.Separator(),
3380
- { name: `${ansis.gray(i18n.t("common:back"))}`, value: "cancel" }
3490
+ { name: `${ansis.gray(`\u2190 ${i18n.t("common:back")}`)}`, value: "cancel" }
3381
3491
  ]
3382
3492
  }]);
3383
3493
  if (tool === "cancel")
@@ -3390,8 +3500,8 @@ async function handleTools() {
3390
3500
  }
3391
3501
  async function runCcusage() {
3392
3502
  console.log();
3393
- console.log(ansis.cyan(`\u{1F4CA} ${i18n.t("menu:tools.runningCcusage")}`));
3394
- console.log(ansis.gray("$ npx ccusage@latest"));
3503
+ console.log(ansis.cyan(` \u{1F4CA} ${i18n.t("menu:tools.runningCcusage")}`));
3504
+ console.log(ansis.gray(" $ npx ccusage@latest"));
3395
3505
  console.log();
3396
3506
  return new Promise((resolve) => {
3397
3507
  const child = spawn("npx", ["ccusage@latest"], {
@@ -3412,7 +3522,7 @@ async function handleCCometixLine() {
3412
3522
  { name: `${ansis.green("\u279C")} ${i18n.t("menu:tools.cclineInstall")}`, value: "install" },
3413
3523
  { name: `${ansis.red("\u2715")} ${i18n.t("menu:tools.cclineUninstall")}`, value: "uninstall" },
3414
3524
  new inquirer.Separator(),
3415
- { name: `${ansis.gray(i18n.t("common:back"))}`, value: "cancel" }
3525
+ { name: `${ansis.gray(`\u2190 ${i18n.t("common:back")}`)}`, value: "cancel" }
3416
3526
  ]
3417
3527
  }]);
3418
3528
  if (action === "cancel")
@@ -3425,11 +3535,11 @@ async function handleCCometixLine() {
3425
3535
  }
3426
3536
  async function installCCometixLine() {
3427
3537
  console.log();
3428
- console.log(ansis.yellow(`\u23F3 ${i18n.t("menu:tools.cclineInstalling")}`));
3538
+ console.log(ansis.yellow(` \u23F3 ${i18n.t("menu:tools.cclineInstalling")}`));
3429
3539
  try {
3430
3540
  const installCmd = isWindows() ? "npm install -g @cometix/ccline" : "sudo npm install -g @cometix/ccline";
3431
3541
  await execAsync(installCmd, { timeout: 12e4 });
3432
- console.log(ansis.green(`\u2713 ${i18n.t("menu:tools.cclineInstallSuccess")}`));
3542
+ console.log(ansis.green(` \u2713 ${i18n.t("menu:tools.cclineInstallSuccess")}`));
3433
3543
  const settingsPath = join(homedir(), ".claude", "settings.json");
3434
3544
  let settings = {};
3435
3545
  if (await fs.pathExists(settingsPath)) {
@@ -3442,29 +3552,29 @@ async function installCCometixLine() {
3442
3552
  };
3443
3553
  await fs.ensureDir(join(homedir(), ".claude"));
3444
3554
  await fs.writeJson(settingsPath, settings, { spaces: 2 });
3445
- console.log(ansis.green(`\u2713 ${i18n.t("menu:tools.cclineConfigured")}`));
3555
+ console.log(ansis.green(` \u2713 ${i18n.t("menu:tools.cclineConfigured")}`));
3446
3556
  console.log();
3447
- console.log(ansis.cyan(`\u{1F4A1} ${i18n.t("common:restartToApply")}`));
3557
+ console.log(ansis.cyan(` \u{1F4A1} ${i18n.t("common:restartToApply")}`));
3448
3558
  } catch (error) {
3449
- console.log(ansis.red(`\u2717 ${i18n.t("menu:tools.cclineInstallFailed", { error: String(error) })}`));
3559
+ console.log(ansis.red(` \u2717 ${i18n.t("menu:tools.cclineInstallFailed", { error: String(error) })}`));
3450
3560
  }
3451
3561
  }
3452
3562
  async function uninstallCCometixLine() {
3453
3563
  console.log();
3454
- console.log(ansis.yellow(`\u23F3 ${i18n.t("menu:tools.cclineUninstalling")}`));
3564
+ console.log(ansis.yellow(` \u23F3 ${i18n.t("menu:tools.cclineUninstalling")}`));
3455
3565
  try {
3456
3566
  const settingsPath = join(homedir(), ".claude", "settings.json");
3457
3567
  if (await fs.pathExists(settingsPath)) {
3458
3568
  const settings = await fs.readJson(settingsPath);
3459
3569
  delete settings.statusLine;
3460
3570
  await fs.writeJson(settingsPath, settings, { spaces: 2 });
3461
- console.log(ansis.green(`\u2713 ${i18n.t("menu:tools.cclineConfigRemoved")}`));
3571
+ console.log(ansis.green(` \u2713 ${i18n.t("menu:tools.cclineConfigRemoved")}`));
3462
3572
  }
3463
3573
  const uninstallCmd = isWindows() ? "npm uninstall -g @cometix/ccline" : "sudo npm uninstall -g @cometix/ccline";
3464
3574
  await execAsync(uninstallCmd, { timeout: 6e4 });
3465
- console.log(ansis.green(`\u2713 ${i18n.t("menu:tools.cclineUninstalled")}`));
3575
+ console.log(ansis.green(` \u2713 ${i18n.t("menu:tools.cclineUninstalled")}`));
3466
3576
  } catch (error) {
3467
- console.log(ansis.red(`\u2717 ${i18n.t("menu:tools.cclineUninstallFailed", { error: String(error) })}`));
3577
+ console.log(ansis.red(` \u2717 ${i18n.t("menu:tools.cclineUninstallFailed", { error: String(error) })}`));
3468
3578
  }
3469
3579
  }
3470
3580
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccg-workflow",
3
- "version": "1.7.69",
3
+ "version": "1.7.70",
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",