ccg-workflow 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.mjs CHANGED
@@ -1,8 +1,9 @@
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.iK6lgCG3.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.CP2pPVul.mjs';
5
5
  import 'inquirer';
6
+ import 'ora';
6
7
  import 'node:child_process';
7
8
  import 'node:util';
8
9
  import 'node:os';
@@ -11,7 +12,6 @@ import 'pathe';
11
12
  import 'fs-extra';
12
13
  import 'smol-toml';
13
14
  import 'i18next';
14
- import 'ora';
15
15
 
16
16
  async function diagnoseMcp() {
17
17
  console.log();
package/dist/index.d.mts CHANGED
@@ -32,6 +32,7 @@ interface ModelRouting {
32
32
  strategy: 'parallel';
33
33
  };
34
34
  mode: CollaborationMode;
35
+ geminiModel?: string;
35
36
  }
36
37
  interface CcgConfig {
37
38
  general: {
package/dist/index.d.ts CHANGED
@@ -32,6 +32,7 @@ interface ModelRouting {
32
32
  strategy: 'parallel';
33
33
  };
34
34
  mode: CollaborationMode;
35
+ geminiModel?: string;
35
36
  }
36
37
  interface CcgConfig {
37
38
  general: {
package/dist/index.mjs CHANGED
@@ -1,6 +1,7 @@
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.iK6lgCG3.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.CP2pPVul.mjs';
2
2
  import 'ansis';
3
3
  import 'inquirer';
4
+ import 'ora';
4
5
  import 'node:child_process';
5
6
  import 'node:util';
6
7
  import 'node:os';
@@ -9,4 +10,3 @@ import 'pathe';
9
10
  import 'fs-extra';
10
11
  import 'smol-toml';
11
12
  import 'i18next';
12
- import 'ora';
@@ -1,5 +1,6 @@
1
1
  import ansis from 'ansis';
2
2
  import inquirer from 'inquirer';
3
+ import ora from 'ora';
3
4
  import { exec, spawn } from 'node:child_process';
4
5
  import { promisify } from 'node:util';
5
6
  import { homedir } from 'node:os';
@@ -8,9 +9,8 @@ import { dirname, join, relative, sep, basename } from 'pathe';
8
9
  import fs from 'fs-extra';
9
10
  import { parse, stringify } from 'smol-toml';
10
11
  import i18next from 'i18next';
11
- import ora from 'ora';
12
12
 
13
- const version = "2.0.0";
13
+ const version = "2.1.0";
14
14
 
15
15
  function cmd(id, order, category, name, nameEn, description, descriptionEn, cmdOverride) {
16
16
  return {
@@ -133,6 +133,10 @@ function injectConfigVariables(content, config) {
133
133
  processed = processed.replace(/\{\{REVIEW_MODELS\}\}/g, JSON.stringify(reviewModels));
134
134
  const routingMode = routing.mode || "smart";
135
135
  processed = processed.replace(/\{\{ROUTING_MODE\}\}/g, routingMode);
136
+ const geminiModel = routing.geminiModel || "gemini-3.1-pro-preview";
137
+ const usesGemini = frontendPrimary === "gemini" || backendPrimary === "gemini";
138
+ const geminiModelFlag = usesGemini ? `--gemini-model ${geminiModel} ` : "";
139
+ processed = processed.replace(/\{\{GEMINI_MODEL_FLAG\}\}/g, geminiModelFlag);
136
140
  const liteModeFlag = config.liteMode ? "--lite " : "";
137
141
  processed = processed.replace(/\{\{LITE_MODE_FLAG\}\}/g, liteModeFlag);
138
142
  const mcpProvider = config.mcpProvider || "ace-tool";
@@ -1842,6 +1846,20 @@ const zhCN = {
1842
1846
  prompt: "\u542F\u7528 Web UI \u5B9E\u65F6\u8F93\u51FA\uFF1F",
1843
1847
  disableHint: "\u7981\u7528\u53EF\u52A0\u901F\u54CD\u5E94"
1844
1848
  },
1849
+ model: {
1850
+ title: "\u6A21\u578B\u8DEF\u7531\u914D\u7F6E",
1851
+ selectFrontend: "\u9009\u62E9\u524D\u7AEF\u6A21\u578B",
1852
+ selectBackend: "\u9009\u62E9\u540E\u7AEF\u6A21\u578B",
1853
+ selectGeminiModel: "Gemini \u6A21\u578B\u578B\u53F7",
1854
+ recommended: "\u63A8\u8350",
1855
+ custom: "\u81EA\u5B9A\u4E49...",
1856
+ enterCustomModel: "\u8F93\u5165\u81EA\u5B9A\u4E49 Gemini \u6A21\u578B\u540D\u79F0",
1857
+ currentRouting: "\u5F53\u524D\u6A21\u578B\u8DEF\u7531",
1858
+ routingUpdated: "\u6A21\u578B\u8DEF\u7531\u5DF2\u66F4\u65B0",
1859
+ reinstalling: "\u6B63\u5728\u91CD\u88C5\u6A21\u677F\u4EE5\u5E94\u7528\u65B0\u914D\u7F6E...",
1860
+ reinstallDone: "\u6A21\u677F\u5DF2\u66F4\u65B0",
1861
+ reinstallFailed: "\u6A21\u677F\u66F4\u65B0\u5931\u8D25"
1862
+ },
1845
1863
  perf: {
1846
1864
  title: "\u6027\u80FD\u6A21\u5F0F",
1847
1865
  selectMode: "\u9009\u62E9\u6027\u80FD\u6A21\u5F0F",
@@ -1974,6 +1992,7 @@ const zhCN = {
1974
1992
  configMcp: "\u914D\u7F6E MCP",
1975
1993
  configApi: "\u914D\u7F6E API",
1976
1994
  configStyle: "\u914D\u7F6E\u8F93\u51FA\u98CE\u683C",
1995
+ configModel: "\u914D\u7F6E\u6A21\u578B\u8DEF\u7531",
1977
1996
  tools: "\u5B9E\u7528\u5DE5\u5177",
1978
1997
  installClaude: "\u5B89\u88C5 Claude Code",
1979
1998
  uninstall: "\u5378\u8F7D CCG",
@@ -2300,6 +2319,20 @@ const en = {
2300
2319
  prompt: "Enable Web UI real-time output?",
2301
2320
  disableHint: "Disabling can speed up response"
2302
2321
  },
2322
+ model: {
2323
+ title: "Model Routing",
2324
+ selectFrontend: "Select frontend model",
2325
+ selectBackend: "Select backend model",
2326
+ selectGeminiModel: "Gemini model name",
2327
+ recommended: "Recommended",
2328
+ custom: "Custom...",
2329
+ enterCustomModel: "Enter custom Gemini model name",
2330
+ currentRouting: "Current model routing",
2331
+ routingUpdated: "Model routing updated",
2332
+ reinstalling: "Reinstalling templates with new config...",
2333
+ reinstallDone: "Templates updated",
2334
+ reinstallFailed: "Template update failed"
2335
+ },
2303
2336
  perf: {
2304
2337
  title: "Performance Mode",
2305
2338
  selectMode: "Select performance mode",
@@ -2432,6 +2465,7 @@ const en = {
2432
2465
  configMcp: "Configure MCP",
2433
2466
  configApi: "Configure API",
2434
2467
  configStyle: "Configure output style",
2468
+ configModel: "Configure model routing",
2435
2469
  tools: "Tools",
2436
2470
  installClaude: "Install Claude Code",
2437
2471
  uninstall: "Uninstall CCG",
@@ -2880,10 +2914,19 @@ async function init(options = {}) {
2880
2914
  language = options.lang;
2881
2915
  await initI18n(language);
2882
2916
  }
2883
- const frontendModels = ["gemini"];
2884
- const backendModels = ["codex"];
2917
+ let frontendModels = ["gemini"];
2918
+ let backendModels = ["codex"];
2919
+ let geminiModel = "gemini-3.1-pro-preview";
2885
2920
  const mode = "smart";
2886
2921
  const selectedWorkflows = getAllCommandIds();
2922
+ if (options.skipPrompt) {
2923
+ const existingConfig = await readCcgConfig();
2924
+ if (existingConfig?.routing) {
2925
+ frontendModels = existingConfig.routing.frontend?.models || ["gemini"];
2926
+ backendModels = existingConfig.routing.backend?.models || ["codex"];
2927
+ geminiModel = existingConfig.routing.geminiModel || "gemini-3.1-pro-preview";
2928
+ }
2929
+ }
2887
2930
  let liteMode = false;
2888
2931
  let mcpProvider = "ace-tool";
2889
2932
  let aceToolBaseUrl = "";
@@ -2901,7 +2944,7 @@ async function init(options = {}) {
2901
2944
  let apiKey = "";
2902
2945
  if (!options.skipPrompt) {
2903
2946
  console.log();
2904
- console.log(ansis.cyan.bold(` \u{1F511} Step 1/3 \u2014 ${i18n.t("init:api.title")}`));
2947
+ console.log(ansis.cyan.bold(` \u{1F511} Step 1/4 \u2014 ${i18n.t("init:api.title")}`));
2905
2948
  console.log();
2906
2949
  const { apiProvider } = await inquirer.prompt([{
2907
2950
  type: "list",
@@ -2933,11 +2976,63 @@ async function init(options = {}) {
2933
2976
  apiKey = apiAnswers.key?.trim() || "";
2934
2977
  }
2935
2978
  }
2979
+ if (!options.skipPrompt) {
2980
+ const existingConfig = await readCcgConfig();
2981
+ console.log();
2982
+ console.log(ansis.cyan.bold(` \u{1F9E0} Step 2/4 \u2014 ${i18n.t("init:model.title")}`));
2983
+ console.log();
2984
+ const { selectedFrontend } = await inquirer.prompt([{
2985
+ type: "list",
2986
+ name: "selectedFrontend",
2987
+ message: i18n.t("init:model.selectFrontend"),
2988
+ choices: [
2989
+ { name: `Gemini ${ansis.green(`(${i18n.t("init:model.recommended")})`)}`, value: "gemini" },
2990
+ { name: "Codex", value: "codex" }
2991
+ ],
2992
+ default: existingConfig?.routing?.frontend?.primary || "gemini"
2993
+ }]);
2994
+ const { selectedBackend } = await inquirer.prompt([{
2995
+ type: "list",
2996
+ name: "selectedBackend",
2997
+ message: i18n.t("init:model.selectBackend"),
2998
+ choices: [
2999
+ { name: "Gemini", value: "gemini" },
3000
+ { name: `Codex ${ansis.green(`(${i18n.t("init:model.recommended")})`)}`, value: "codex" }
3001
+ ],
3002
+ default: existingConfig?.routing?.backend?.primary || "codex"
3003
+ }]);
3004
+ frontendModels = [selectedFrontend];
3005
+ backendModels = [selectedBackend];
3006
+ if (selectedFrontend === "gemini" || selectedBackend === "gemini") {
3007
+ const { selectedGeminiModel } = await inquirer.prompt([{
3008
+ type: "list",
3009
+ name: "selectedGeminiModel",
3010
+ message: i18n.t("init:model.selectGeminiModel"),
3011
+ choices: [
3012
+ { name: `gemini-3.1-pro-preview ${ansis.green(`(${i18n.t("init:model.recommended")})`)}`, value: "gemini-3.1-pro-preview" },
3013
+ { name: "gemini-2.5-flash", value: "gemini-2.5-flash" },
3014
+ { name: `${i18n.t("init:model.custom")}`, value: "custom" }
3015
+ ],
3016
+ default: existingConfig?.routing?.geminiModel || "gemini-3.1-pro-preview"
3017
+ }]);
3018
+ if (selectedGeminiModel === "custom") {
3019
+ const { customModel } = await inquirer.prompt([{
3020
+ type: "input",
3021
+ name: "customModel",
3022
+ message: i18n.t("init:model.enterCustomModel"),
3023
+ validate: (v) => v.trim() !== "" || i18n.t("init:model.enterCustomModel")
3024
+ }]);
3025
+ geminiModel = customModel.trim();
3026
+ } else {
3027
+ geminiModel = selectedGeminiModel;
3028
+ }
3029
+ }
3030
+ }
2936
3031
  if (options.skipMcp) {
2937
3032
  mcpProvider = "skip";
2938
3033
  } else if (!options.skipPrompt) {
2939
3034
  console.log();
2940
- console.log(ansis.cyan.bold(` \u{1F527} Step 2/3 \u2014 ${i18n.t("init:mcp.title")}`));
3035
+ console.log(ansis.cyan.bold(` \u{1F527} Step 3/4 \u2014 ${i18n.t("init:mcp.title")}`));
2941
3036
  console.log();
2942
3037
  const { selectedTools } = await inquirer.prompt([{
2943
3038
  type: "checkbox",
@@ -3073,7 +3168,7 @@ async function init(options = {}) {
3073
3168
  const existingConfig = await readCcgConfig();
3074
3169
  const currentLiteMode = existingConfig?.performance?.liteMode || false;
3075
3170
  console.log();
3076
- console.log(ansis.cyan.bold(` \u26A1 Step 3/3 \u2014 ${i18n.t("init:perf.title")}`));
3171
+ console.log(ansis.cyan.bold(` \u26A1 Step 4/4 \u2014 ${i18n.t("init:perf.title")}`));
3077
3172
  console.log();
3078
3173
  const { perfMode } = await inquirer.prompt([{
3079
3174
  type: "list",
@@ -3095,25 +3190,28 @@ async function init(options = {}) {
3095
3190
  const routing = {
3096
3191
  frontend: {
3097
3192
  models: frontendModels,
3098
- primary: "gemini",
3193
+ primary: frontendModels[0],
3099
3194
  strategy: "fallback"
3100
3195
  },
3101
3196
  backend: {
3102
3197
  models: backendModels,
3103
- primary: "codex",
3198
+ primary: backendModels[0],
3104
3199
  strategy: "fallback"
3105
3200
  },
3106
3201
  review: {
3107
- models: ["codex", "gemini"],
3202
+ models: [.../* @__PURE__ */ new Set([...frontendModels, ...backendModels])],
3108
3203
  strategy: "parallel"
3109
3204
  },
3110
- mode
3205
+ mode,
3206
+ geminiModel
3111
3207
  };
3112
3208
  console.log();
3113
3209
  console.log(ansis.yellow("\u2501".repeat(50)));
3114
3210
  console.log(ansis.bold(` ${i18n.t("init:summary.title")}`));
3115
3211
  console.log();
3116
- console.log(` ${ansis.cyan(i18n.t("init:summary.modelRouting"))} ${ansis.green("Gemini")} (Frontend) + ${ansis.blue("Codex")} (Backend)`);
3212
+ const fmName = frontendModels[0].charAt(0).toUpperCase() + frontendModels[0].slice(1);
3213
+ const bmName = backendModels[0].charAt(0).toUpperCase() + backendModels[0].slice(1);
3214
+ console.log(` ${ansis.cyan(i18n.t("init:summary.modelRouting"))} ${ansis.green(fmName)} (Frontend) + ${ansis.blue(bmName)} (Backend)`);
3117
3215
  console.log(` ${ansis.cyan(i18n.t("init:summary.commandCount"))} ${ansis.yellow(selectedWorkflows.length.toString())}`);
3118
3216
  const mcpSummary = (() => {
3119
3217
  if (mcpProvider === "fast-context") return ansis.green("fast-context");
@@ -3886,6 +3984,7 @@ async function showMainMenu() {
3886
3984
  item("3", i18n.t("menu:options.configMcp"), isZh ? "\u4EE3\u7801\u68C0\u7D22 MCP \u5DE5\u5177" : "Code retrieval MCP tool"),
3887
3985
  item("4", i18n.t("menu:options.configApi"), isZh ? "\u81EA\u5B9A\u4E49 API \u7AEF\u70B9" : "Custom API endpoint"),
3888
3986
  item("5", i18n.t("menu:options.configStyle"), isZh ? "\u9009\u62E9\u8F93\u51FA\u4EBA\u683C" : "Choose output personality"),
3987
+ item("6", i18n.t("menu:options.configModel"), isZh ? "\u524D\u7AEF/\u540E\u7AEF\u6A21\u578B\u5207\u6362" : "Switch frontend/backend models"),
3889
3988
  groupSep(isZh ? "\u5176\u4ED6\u5DE5\u5177" : "Tools"),
3890
3989
  item("T", i18n.t("menu:options.tools"), "ccusage, CCometixLine"),
3891
3990
  item("C", i18n.t("menu:options.installClaude"), isZh ? "\u5B89\u88C5/\u91CD\u88C5 CLI" : "Install/reinstall CLI"),
@@ -3912,6 +4011,9 @@ async function showMainMenu() {
3912
4011
  case "5":
3913
4012
  await configOutputStyle();
3914
4013
  break;
4014
+ case "6":
4015
+ await configModelRouting();
4016
+ break;
3915
4017
  case "T":
3916
4018
  await handleTools();
3917
4019
  break;
@@ -4088,6 +4190,105 @@ const OUTPUT_STYLES = [
4088
4190
  { id: "abyss-command", nameKey: "menu:style.abyssCommand", descKey: "menu:style.abyssCommandDesc" },
4089
4191
  { id: "abyss-ritual", nameKey: "menu:style.abyssRitual", descKey: "menu:style.abyssRitualDesc" }
4090
4192
  ];
4193
+ async function configModelRouting() {
4194
+ const config = await readCcgConfig();
4195
+ (config?.general?.language || "zh-CN") === "zh-CN";
4196
+ console.log();
4197
+ console.log(ansis.cyan.bold(` ${i18n.t("init:model.title")}`));
4198
+ console.log();
4199
+ const currentFrontend = config?.routing?.frontend?.primary || "gemini";
4200
+ const currentBackend = config?.routing?.backend?.primary || "codex";
4201
+ const currentGeminiModel = config?.routing?.geminiModel || "gemini-3.1-pro-preview";
4202
+ console.log(ansis.gray(` ${i18n.t("init:model.currentRouting")}:`));
4203
+ console.log(` ${ansis.cyan("Frontend:")} ${ansis.green(currentFrontend)}`);
4204
+ console.log(` ${ansis.cyan("Backend:")} ${ansis.blue(currentBackend)}`);
4205
+ if (currentFrontend === "gemini" || currentBackend === "gemini") {
4206
+ console.log(` ${ansis.cyan("Gemini:")} ${ansis.gray(currentGeminiModel)}`);
4207
+ }
4208
+ console.log();
4209
+ const { selectedFrontend } = await inquirer.prompt([{
4210
+ type: "list",
4211
+ name: "selectedFrontend",
4212
+ message: i18n.t("init:model.selectFrontend"),
4213
+ choices: [
4214
+ { name: `Gemini ${ansis.green(`(${i18n.t("init:model.recommended")})`)}`, value: "gemini" },
4215
+ { name: "Codex", value: "codex" }
4216
+ ],
4217
+ default: currentFrontend
4218
+ }]);
4219
+ const { selectedBackend } = await inquirer.prompt([{
4220
+ type: "list",
4221
+ name: "selectedBackend",
4222
+ message: i18n.t("init:model.selectBackend"),
4223
+ choices: [
4224
+ { name: "Gemini", value: "gemini" },
4225
+ { name: `Codex ${ansis.green(`(${i18n.t("init:model.recommended")})`)}`, value: "codex" }
4226
+ ],
4227
+ default: currentBackend
4228
+ }]);
4229
+ let geminiModel = currentGeminiModel;
4230
+ if (selectedFrontend === "gemini" || selectedBackend === "gemini") {
4231
+ const { selectedGeminiModel } = await inquirer.prompt([{
4232
+ type: "list",
4233
+ name: "selectedGeminiModel",
4234
+ message: i18n.t("init:model.selectGeminiModel"),
4235
+ choices: [
4236
+ { name: `gemini-3.1-pro-preview ${ansis.green(`(${i18n.t("init:model.recommended")})`)}`, value: "gemini-3.1-pro-preview" },
4237
+ { name: "gemini-2.5-flash", value: "gemini-2.5-flash" },
4238
+ { name: `${i18n.t("init:model.custom")}`, value: "custom" }
4239
+ ],
4240
+ default: currentGeminiModel
4241
+ }]);
4242
+ if (selectedGeminiModel === "custom") {
4243
+ const { customModel } = await inquirer.prompt([{
4244
+ type: "input",
4245
+ name: "customModel",
4246
+ message: i18n.t("init:model.enterCustomModel"),
4247
+ validate: (v) => v.trim() !== "" || i18n.t("init:model.enterCustomModel")
4248
+ }]);
4249
+ geminiModel = customModel.trim();
4250
+ } else {
4251
+ geminiModel = selectedGeminiModel;
4252
+ }
4253
+ }
4254
+ if (selectedFrontend === currentFrontend && selectedBackend === currentBackend && geminiModel === currentGeminiModel) {
4255
+ console.log(ansis.gray(` ${i18n.t("common:configNotModified")}`));
4256
+ return;
4257
+ }
4258
+ if (config) {
4259
+ config.routing.frontend = {
4260
+ models: [selectedFrontend],
4261
+ primary: selectedFrontend,
4262
+ strategy: "fallback"
4263
+ };
4264
+ config.routing.backend = {
4265
+ models: [selectedBackend],
4266
+ primary: selectedBackend,
4267
+ strategy: "fallback"
4268
+ };
4269
+ config.routing.review = {
4270
+ models: [.../* @__PURE__ */ new Set([selectedFrontend, selectedBackend])],
4271
+ strategy: "parallel"
4272
+ };
4273
+ config.routing.geminiModel = geminiModel;
4274
+ await writeCcgConfig(config);
4275
+ }
4276
+ console.log();
4277
+ console.log(ansis.green(` \u2713 ${i18n.t("init:model.routingUpdated")}`));
4278
+ const spinner = ora(i18n.t("init:model.reinstalling")).start();
4279
+ try {
4280
+ const { execSync } = await import('node:child_process');
4281
+ execSync("npx --yes ccg-workflow init --force --skip-prompt --skip-mcp", {
4282
+ timeout: 3e5,
4283
+ stdio: "pipe",
4284
+ env: { ...process.env, CCG_UPDATE_MODE: "true" }
4285
+ });
4286
+ spinner.succeed(i18n.t("init:model.reinstallDone"));
4287
+ } catch {
4288
+ spinner.fail(i18n.t("init:model.reinstallFailed"));
4289
+ }
4290
+ console.log(ansis.gray(` ${i18n.t("common:restartToApply")}`));
4291
+ }
4091
4292
  async function configOutputStyle() {
4092
4293
  console.log();
4093
4294
  console.log(ansis.cyan.bold(` ${i18n.t("menu:style.title")}`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccg-workflow",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
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",
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: '多模型技术分析(并行执行):Codex 后端视角 + Gemini 前端视角,交叉验证后综合见解'
2
+ description: '多模型技术分析(并行执行):{{BACKEND_PRIMARY}} 后端视角 + {{FRONTEND_PRIMARY}} 前端视角,交叉验证后综合见解'
3
3
  ---
4
4
 
5
5
  # Analyze - 多模型技术分析
@@ -16,8 +16,8 @@ description: '多模型技术分析(并行执行):Codex 后端视角 + Gem
16
16
 
17
17
  你是**分析协调者**,编排多模型分析流程:
18
18
  - **ace-tool** – 代码上下文检索
19
- - **Codex** – 后端/系统视角(**后端权威**)
20
- - **Gemini** – 前端/用户视角(**前端权威**)
19
+ - **{{BACKEND_PRIMARY}}** – 后端/系统视角(**后端权威**)
20
+ - **{{FRONTEND_PRIMARY}}** – 前端/用户视角(**前端权威**)
21
21
  - **Claude (自己)** – 综合见解
22
22
 
23
23
  ---
@@ -33,7 +33,7 @@ description: '多模型技术分析(并行执行):Codex 后端视角 + Gem
33
33
 
34
34
  ```
35
35
  Bash({
36
- command: "~/.claude/bin/codeagent-wrapper {{LITE_MODE_FLAG}}--progress --backend <codex|gemini> {{GEMINI_MODEL_FLAG}}- \"{{WORKDIR}}\" <<'EOF'
36
+ command: "~/.claude/bin/codeagent-wrapper {{LITE_MODE_FLAG}}--progress --backend <{{BACKEND_PRIMARY}}|{{FRONTEND_PRIMARY}}> {{GEMINI_MODEL_FLAG}}- \"{{WORKDIR}}\" <<'EOF'
37
37
  ROLE_FILE: <角色提示词路径>
38
38
  <TASK>
39
39
  需求:<增强后的需求(如未增强则用 $ARGUMENTS)>
@@ -47,9 +47,6 @@ EOF",
47
47
  })
48
48
  ```
49
49
 
50
- **模型参数说明**:
51
- - `{{GEMINI_MODEL_FLAG}}`:当使用 `--backend gemini` 时,替换为 `--gemini-model gemini-3.1-pro-preview `(注意末尾空格);使用 codex 时替换为空字符串
52
-
53
50
  **角色提示词**:
54
51
 
55
52
  | 模型 | 提示词 |
@@ -96,11 +93,11 @@ TaskOutput({ task_id: "<task_id>", block: true, timeout: 600000 })
96
93
 
97
94
  **⚠️ 必须发起两个并行 Bash 调用**(参照上方调用规范):
98
95
 
99
- 1. **Codex 后端分析**:`Bash({ command: "...--backend codex...", run_in_background: true })`
96
+ 1. **{{BACKEND_PRIMARY}} 后端分析**:`Bash({ command: "...--backend {{BACKEND_PRIMARY}}...", run_in_background: true })`
100
97
  - ROLE_FILE: `~/.claude/.ccg/prompts/codex/analyzer.md`
101
98
  - OUTPUT:技术可行性、架构影响、性能考量
102
99
 
103
- 2. **Gemini 前端分析**:`Bash({ command: "...--backend gemini...", run_in_background: true })`
100
+ 2. **{{FRONTEND_PRIMARY}} 前端分析**:`Bash({ command: "...--backend {{FRONTEND_PRIMARY}}...", run_in_background: true })`
104
101
  - ROLE_FILE: `~/.claude/.ccg/prompts/gemini/analyzer.md`
105
102
  - OUTPUT:UI/UX 影响、用户体验、视觉设计考量
106
103
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: '后端专项工作流(研究→构思→计划→执行→优化→评审),Codex 主导'
2
+ description: '后端专项工作流(研究→构思→计划→执行→优化→评审),{{BACKEND_PRIMARY}} 主导'
3
3
  ---
4
4
 
5
5
  # Backend - 后端专项开发
@@ -13,7 +13,7 @@ description: '后端专项工作流(研究→构思→计划→执行→优化
13
13
  ## 上下文
14
14
 
15
15
  - 后端任务:$ARGUMENTS
16
- - Codex 主导,Gemini 辅助参考
16
+ - {{BACKEND_PRIMARY}} 主导,{{FRONTEND_PRIMARY}} 辅助参考
17
17
  - 适用:API 设计、算法实现、数据库优化、业务逻辑
18
18
 
19
19
  ## 你的角色
@@ -21,8 +21,8 @@ description: '后端专项工作流(研究→构思→计划→执行→优化
21
21
  你是**后端编排者**,协调多模型完成服务端任务(研究 → 构思 → 计划 → 执行 → 优化 → 评审),用中文协助用户。
22
22
 
23
23
  **协作模型**:
24
- - **Codex** – 后端逻辑、算法(**后端权威,可信赖**)
25
- - **Gemini** – 前端视角(**后端意见仅供参考**)
24
+ - **{{BACKEND_PRIMARY}}** – 后端逻辑、算法(**后端权威,可信赖**)
25
+ - **{{FRONTEND_PRIMARY}}** – 前端视角(**后端意见仅供参考**)
26
26
  - **Claude (自己)** – 编排、计划、执行、交付
27
27
 
28
28
  ---
@@ -39,7 +39,7 @@ description: '后端专项工作流(研究→构思→计划→执行→优化
39
39
  ```
40
40
  # 新会话调用
41
41
  Bash({
42
- command: "~/.claude/bin/codeagent-wrapper {{LITE_MODE_FLAG}}--progress --backend codex - \"{{WORKDIR}}\" <<'EOF'
42
+ command: "~/.claude/bin/codeagent-wrapper {{LITE_MODE_FLAG}}--progress --backend {{BACKEND_PRIMARY}} {{GEMINI_MODEL_FLAG}}- \"{{WORKDIR}}\" <<'EOF'
43
43
  ROLE_FILE: <角色提示词路径>
44
44
  <TASK>
45
45
  需求:<增强后的需求(如未增强则用 $ARGUMENTS)>
@@ -54,7 +54,7 @@ EOF",
54
54
 
55
55
  # 复用会话调用
56
56
  Bash({
57
- command: "~/.claude/bin/codeagent-wrapper {{LITE_MODE_FLAG}}--progress --backend codex resume <SESSION_ID> - \"{{WORKDIR}}\" <<'EOF'
57
+ command: "~/.claude/bin/codeagent-wrapper {{LITE_MODE_FLAG}}--progress --backend {{BACKEND_PRIMARY}} {{GEMINI_MODEL_FLAG}}resume <SESSION_ID> - \"{{WORKDIR}}\" <<'EOF'
58
58
  ROLE_FILE: <角色提示词路径>
59
59
  <TASK>
60
60
  需求:<增强后的需求(如未增强则用 $ARGUMENTS)>
@@ -105,7 +105,7 @@ EOF",
105
105
 
106
106
  ### 💡 阶段 2:构思
107
107
 
108
- `[模式:构思]` - Codex 主导分析
108
+ `[模式:构思]` - {{BACKEND_PRIMARY}} 主导分析
109
109
 
110
110
  **⚠️ 必须调用 Codex**(参照上方调用规范):
111
111
  - ROLE_FILE: `~/.claude/.ccg/prompts/codex/analyzer.md`
@@ -119,7 +119,7 @@ EOF",
119
119
 
120
120
  ### 📋 阶段 3:计划
121
121
 
122
- `[模式:计划]` - Codex 主导规划
122
+ `[模式:计划]` - {{BACKEND_PRIMARY}} 主导规划
123
123
 
124
124
  **⚠️ 必须调用 Codex**(使用 `resume <CODEX_SESSION>` 复用会话):
125
125
  - ROLE_FILE: `~/.claude/.ccg/prompts/codex/architect.md`
@@ -139,7 +139,7 @@ Claude 综合规划,请求用户批准后存入 `.claude/plan/任务名.md`
139
139
 
140
140
  ### 🚀 阶段 5:优化
141
141
 
142
- `[模式:优化]` - Codex 主导审查
142
+ `[模式:优化]` - {{BACKEND_PRIMARY}} 主导审查
143
143
 
144
144
  **⚠️ 必须调用 Codex**(参照上方调用规范):
145
145
  - ROLE_FILE: `~/.claude/.ccg/prompts/codex/reviewer.md`
@@ -161,7 +161,7 @@ Claude 综合规划,请求用户批准后存入 `.claude/plan/任务名.md`
161
161
 
162
162
  ## 关键规则
163
163
 
164
- 1. **Codex 后端意见可信赖**
165
- 2. **Gemini 后端意见仅供参考**
164
+ 1. **{{BACKEND_PRIMARY}} 后端意见可信赖**
165
+ 2. **{{FRONTEND_PRIMARY}} 后端意见仅供参考**
166
166
  3. 外部模型对文件系统**零写入权限**
167
167
  4. Claude 负责所有代码写入和文件操作
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: 'Codex 全权执行计划 - 读取 /ccg:plan 产出的计划文件,Codex 承担 MCP 搜索 + 代码实现 + 测试,多模型审核'
2
+ description: '{{BACKEND_PRIMARY}} 全权执行计划 - 读取 /ccg:plan 产出的计划文件,{{BACKEND_PRIMARY}} 承担 MCP 搜索 + 代码实现 + 测试,多模型审核'
3
3
  ---
4
4
 
5
5
  # Codex-Exec - Codex 全权执行计划
@@ -24,8 +24,8 @@ $ARGUMENTS
24
24
 
25
25
  | 维度 | `/ccg:execute` | `/ccg:codex-exec` |
26
26
  |------|---------------|-------------------|
27
- | 代码实现 | Claude 重构 Codex/Gemini 的 Diff | **Codex 直接实现** |
28
- | MCP 搜索 | Claude 调用 MCP | **Codex 调用 MCP** |
27
+ | 代码实现 | Claude 重构 {{BACKEND_PRIMARY}}/{{FRONTEND_PRIMARY}} 的 Diff | **{{BACKEND_PRIMARY}} 直接实现** |
28
+ | MCP 搜索 | Claude 调用 MCP | **{{BACKEND_PRIMARY}} 调用 MCP** |
29
29
  | Claude 上下文 | 高(搜索结果 + 代码全进来) | **极低(只看摘要 + diff)** |
30
30
  | Claude token | 大量消耗 | **极少消耗** |
31
31
  | 审核 | 多模型审查 | **多模型审查(不变)** |
@@ -46,11 +46,11 @@ $ARGUMENTS
46
46
  - 如果用户通过 `/add-dir` 添加了多个工作区,先用 Glob/Grep 确定任务相关的工作区
47
47
  - 如果无法确定,用 `AskUserQuestion` 询问用户选择目标工作区
48
48
 
49
- **Codex 执行调用语法**:
49
+ **{{BACKEND_PRIMARY}} 执行调用语法**:
50
50
 
51
51
  ```
52
52
  Bash({
53
- command: "~/.claude/bin/codeagent-wrapper {{LITE_MODE_FLAG}}--progress --backend codex - \"{{WORKDIR}}\" <<'EXEC_EOF'
53
+ command: "~/.claude/bin/codeagent-wrapper {{LITE_MODE_FLAG}}--progress --backend {{BACKEND_PRIMARY}} {{GEMINI_MODEL_FLAG}}- \"{{WORKDIR}}\" <<'EXEC_EOF'
54
54
  <TASK>
55
55
  <指令内容>
56
56
  </TASK>
@@ -61,11 +61,11 @@ EXEC_EOF",
61
61
  })
62
62
  ```
63
63
 
64
- **Codex 复用会话调用**:
64
+ **{{BACKEND_PRIMARY}} 复用会话调用**:
65
65
 
66
66
  ```
67
67
  Bash({
68
- command: "~/.claude/bin/codeagent-wrapper {{LITE_MODE_FLAG}}--progress --backend codex resume <SESSION_ID> - \"{{WORKDIR}}\" <<'EXEC_EOF'
68
+ command: "~/.claude/bin/codeagent-wrapper {{LITE_MODE_FLAG}}--progress --backend {{BACKEND_PRIMARY}} {{GEMINI_MODEL_FLAG}}resume <SESSION_ID> - \"{{WORKDIR}}\" <<'EXEC_EOF'
69
69
  <TASK>
70
70
  <指令内容>
71
71
  </TASK>
@@ -76,14 +76,11 @@ EXEC_EOF",
76
76
  })
77
77
  ```
78
78
 
79
- **模型参数说明**:
80
- - `{{GEMINI_MODEL_FLAG}}`:当使用 `--backend gemini` 时,替换为 `--gemini-model gemini-3.1-pro-preview `(注意末尾空格);使用 codex 时替换为空字符串
81
-
82
79
  **审核调用语法**(Codex ∥ Gemini 并行审查):
83
80
 
84
81
  ```
85
82
  Bash({
86
- command: "~/.claude/bin/codeagent-wrapper {{LITE_MODE_FLAG}}--progress --backend <codex|gemini> {{GEMINI_MODEL_FLAG}}- \"{{WORKDIR}}\" <<'REVIEW_EOF'
83
+ command: "~/.claude/bin/codeagent-wrapper {{LITE_MODE_FLAG}}--progress --backend <{{BACKEND_PRIMARY}}|{{FRONTEND_PRIMARY}}> {{GEMINI_MODEL_FLAG}}- \"{{WORKDIR}}\" <<'REVIEW_EOF'
87
84
  ROLE_FILE: <角色提示词路径>
88
85
  <TASK>
89
86
  Scope: Audit the code changes made by Codex.
@@ -170,7 +167,7 @@ TaskOutput({ task_id: "<task_id>", block: true, timeout: 600000 })
170
167
 
171
168
  ```
172
169
  Bash({
173
- command: "~/.claude/bin/codeagent-wrapper {{LITE_MODE_FLAG}}--progress --backend codex resume <CODEX_SESSION> - \"{{WORKDIR}}\" <<'EXEC_EOF'
170
+ command: "~/.claude/bin/codeagent-wrapper {{LITE_MODE_FLAG}}--progress --backend {{BACKEND_PRIMARY}} {{GEMINI_MODEL_FLAG}}resume <CODEX_SESSION> - \"{{WORKDIR}}\" <<'EXEC_EOF'
174
171
  <TASK>
175
172
  You are a full-stack execution agent. Implement the following plan end-to-end.
176
173
 
@@ -270,7 +267,7 @@ EXEC_EOF",
270
267
 
271
268
  ```
272
269
  Bash({
273
- command: "~/.claude/bin/codeagent-wrapper {{LITE_MODE_FLAG}}--progress --backend codex resume <CODEX_EXEC_SESSION> - \"{{WORKDIR}}\" <<'FIXEOF'
270
+ command: "~/.claude/bin/codeagent-wrapper {{LITE_MODE_FLAG}}--progress --backend {{BACKEND_PRIMARY}} {{GEMINI_MODEL_FLAG}}resume <CODEX_EXEC_SESSION> - \"{{WORKDIR}}\" <<'FIXEOF'
274
271
  <TASK>
275
272
  The implementation needs corrections:
276
273
 
@@ -309,12 +306,12 @@ FIXEOF",
309
306
 
310
307
  2. **并行调用**(`run_in_background: true`):
311
308
 
312
- - **Codex 审查**:
309
+ - **{{BACKEND_PRIMARY}} 审查**:
313
310
  - ROLE_FILE: `~/.claude/.ccg/prompts/codex/reviewer.md`
314
311
  - 输入:变更 Diff + 计划文件内容
315
312
  - 关注:安全性、性能、错误处理、逻辑正确性
316
313
 
317
- - **Gemini 审查**:
314
+ - **{{FRONTEND_PRIMARY}} 审查**:
318
315
  - ROLE_FILE: `~/.claude/.ccg/prompts/gemini/reviewer.md`
319
316
  - 输入:变更 Diff + 计划文件内容
320
317
  - 关注:代码可读性、设计一致性、可维护性
@@ -373,7 +370,7 @@ FIXEOF",
373
370
  ## 关键规则
374
371
 
375
372
  1. **Claude 极简原则** — Claude 不调用 MCP、不做代码检索。只读计划、指挥 Codex、审核结果。
376
- 2. **Codex 全权执行** — MCP 搜索、文档查询、代码检索、实现、测试全由 Codex 完成。
373
+ 2. **{{BACKEND_PRIMARY}} 全权执行** — MCP 搜索、文档查询、代码检索、实现、测试全由 {{BACKEND_PRIMARY}} 完成。
377
374
  3. **多模型审核不变** — 审核阶段仍然 Codex ∥ Gemini 交叉审查,保证质量。
378
375
  4. **信任规则** — 后端以 Codex 为准,前端以 Gemini 为准。
379
376
  5. **一次性下发** — 尽量一次给 Codex 完整指令 + 完整计划,减少来回通信。