ccg-workflow 2.0.0 → 2.1.1
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 +2 -2
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +2 -2
- package/dist/shared/{ccg-workflow.iK6lgCG3.mjs → ccg-workflow.pMx0aHNz.mjs} +222 -12
- package/package.json +1 -1
- package/templates/commands/analyze.md +6 -9
- package/templates/commands/backend.md +11 -11
- package/templates/commands/codex-exec.md +13 -16
- package/templates/commands/debug.md +9 -9
- package/templates/commands/execute.md +6 -9
- package/templates/commands/feat.md +2 -5
- package/templates/commands/frontend.md +11 -11
- package/templates/commands/optimize.md +6 -9
- package/templates/commands/plan.md +5 -8
- package/templates/commands/review.md +3 -6
- package/templates/commands/spec-impl.md +7 -9
- package/templates/commands/spec-init.md +3 -3
- package/templates/commands/spec-plan.md +6 -6
- package/templates/commands/spec-research.md +6 -6
- package/templates/commands/spec-review.md +6 -6
- package/templates/commands/team-plan.md +6 -6
- package/templates/commands/team-research.md +6 -6
- package/templates/commands/team-review.md +6 -6
- package/templates/commands/test.md +11 -14
- package/templates/commands/workflow.md +6 -9
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.
|
|
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.pMx0aHNz.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
package/dist/index.d.ts
CHANGED
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.
|
|
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.pMx0aHNz.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.
|
|
13
|
+
const version = "2.1.1";
|
|
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";
|
|
@@ -275,8 +279,15 @@ function collectInvocableSkills(skillsDir) {
|
|
|
275
279
|
function generateCommandContent(skill, skillsInstallDir) {
|
|
276
280
|
const skillMdPath = join(skillsInstallDir, skill.relPath, "SKILL.md");
|
|
277
281
|
const runSkillPath = join(skillsInstallDir, "run_skill.js");
|
|
282
|
+
const frontmatter = [
|
|
283
|
+
"---",
|
|
284
|
+
`description: '${skill.description.replace(/'/g, "''")}'`,
|
|
285
|
+
"---"
|
|
286
|
+
].join("\n");
|
|
278
287
|
if (skill.runtimeType === "scripted") {
|
|
279
288
|
return [
|
|
289
|
+
frontmatter,
|
|
290
|
+
"",
|
|
280
291
|
`# ${skill.name}`,
|
|
281
292
|
"",
|
|
282
293
|
skill.description,
|
|
@@ -293,6 +304,8 @@ function generateCommandContent(skill, skillsInstallDir) {
|
|
|
293
304
|
].join("\n");
|
|
294
305
|
}
|
|
295
306
|
return [
|
|
307
|
+
frontmatter,
|
|
308
|
+
"",
|
|
296
309
|
`# ${skill.name}`,
|
|
297
310
|
"",
|
|
298
311
|
skill.description,
|
|
@@ -1842,6 +1855,20 @@ const zhCN = {
|
|
|
1842
1855
|
prompt: "\u542F\u7528 Web UI \u5B9E\u65F6\u8F93\u51FA\uFF1F",
|
|
1843
1856
|
disableHint: "\u7981\u7528\u53EF\u52A0\u901F\u54CD\u5E94"
|
|
1844
1857
|
},
|
|
1858
|
+
model: {
|
|
1859
|
+
title: "\u6A21\u578B\u8DEF\u7531\u914D\u7F6E",
|
|
1860
|
+
selectFrontend: "\u9009\u62E9\u524D\u7AEF\u6A21\u578B",
|
|
1861
|
+
selectBackend: "\u9009\u62E9\u540E\u7AEF\u6A21\u578B",
|
|
1862
|
+
selectGeminiModel: "Gemini \u6A21\u578B\u578B\u53F7",
|
|
1863
|
+
recommended: "\u63A8\u8350",
|
|
1864
|
+
custom: "\u81EA\u5B9A\u4E49...",
|
|
1865
|
+
enterCustomModel: "\u8F93\u5165\u81EA\u5B9A\u4E49 Gemini \u6A21\u578B\u540D\u79F0",
|
|
1866
|
+
currentRouting: "\u5F53\u524D\u6A21\u578B\u8DEF\u7531",
|
|
1867
|
+
routingUpdated: "\u6A21\u578B\u8DEF\u7531\u5DF2\u66F4\u65B0",
|
|
1868
|
+
reinstalling: "\u6B63\u5728\u91CD\u88C5\u6A21\u677F\u4EE5\u5E94\u7528\u65B0\u914D\u7F6E...",
|
|
1869
|
+
reinstallDone: "\u6A21\u677F\u5DF2\u66F4\u65B0",
|
|
1870
|
+
reinstallFailed: "\u6A21\u677F\u66F4\u65B0\u5931\u8D25"
|
|
1871
|
+
},
|
|
1845
1872
|
perf: {
|
|
1846
1873
|
title: "\u6027\u80FD\u6A21\u5F0F",
|
|
1847
1874
|
selectMode: "\u9009\u62E9\u6027\u80FD\u6A21\u5F0F",
|
|
@@ -1974,6 +2001,7 @@ const zhCN = {
|
|
|
1974
2001
|
configMcp: "\u914D\u7F6E MCP",
|
|
1975
2002
|
configApi: "\u914D\u7F6E API",
|
|
1976
2003
|
configStyle: "\u914D\u7F6E\u8F93\u51FA\u98CE\u683C",
|
|
2004
|
+
configModel: "\u914D\u7F6E\u6A21\u578B\u8DEF\u7531",
|
|
1977
2005
|
tools: "\u5B9E\u7528\u5DE5\u5177",
|
|
1978
2006
|
installClaude: "\u5B89\u88C5 Claude Code",
|
|
1979
2007
|
uninstall: "\u5378\u8F7D CCG",
|
|
@@ -2300,6 +2328,20 @@ const en = {
|
|
|
2300
2328
|
prompt: "Enable Web UI real-time output?",
|
|
2301
2329
|
disableHint: "Disabling can speed up response"
|
|
2302
2330
|
},
|
|
2331
|
+
model: {
|
|
2332
|
+
title: "Model Routing",
|
|
2333
|
+
selectFrontend: "Select frontend model",
|
|
2334
|
+
selectBackend: "Select backend model",
|
|
2335
|
+
selectGeminiModel: "Gemini model name",
|
|
2336
|
+
recommended: "Recommended",
|
|
2337
|
+
custom: "Custom...",
|
|
2338
|
+
enterCustomModel: "Enter custom Gemini model name",
|
|
2339
|
+
currentRouting: "Current model routing",
|
|
2340
|
+
routingUpdated: "Model routing updated",
|
|
2341
|
+
reinstalling: "Reinstalling templates with new config...",
|
|
2342
|
+
reinstallDone: "Templates updated",
|
|
2343
|
+
reinstallFailed: "Template update failed"
|
|
2344
|
+
},
|
|
2303
2345
|
perf: {
|
|
2304
2346
|
title: "Performance Mode",
|
|
2305
2347
|
selectMode: "Select performance mode",
|
|
@@ -2432,6 +2474,7 @@ const en = {
|
|
|
2432
2474
|
configMcp: "Configure MCP",
|
|
2433
2475
|
configApi: "Configure API",
|
|
2434
2476
|
configStyle: "Configure output style",
|
|
2477
|
+
configModel: "Configure model routing",
|
|
2435
2478
|
tools: "Tools",
|
|
2436
2479
|
installClaude: "Install Claude Code",
|
|
2437
2480
|
uninstall: "Uninstall CCG",
|
|
@@ -2880,10 +2923,19 @@ async function init(options = {}) {
|
|
|
2880
2923
|
language = options.lang;
|
|
2881
2924
|
await initI18n(language);
|
|
2882
2925
|
}
|
|
2883
|
-
|
|
2884
|
-
|
|
2926
|
+
let frontendModels = ["gemini"];
|
|
2927
|
+
let backendModels = ["codex"];
|
|
2928
|
+
let geminiModel = "gemini-3.1-pro-preview";
|
|
2885
2929
|
const mode = "smart";
|
|
2886
2930
|
const selectedWorkflows = getAllCommandIds();
|
|
2931
|
+
if (options.skipPrompt) {
|
|
2932
|
+
const existingConfig = await readCcgConfig();
|
|
2933
|
+
if (existingConfig?.routing) {
|
|
2934
|
+
frontendModels = existingConfig.routing.frontend?.models || ["gemini"];
|
|
2935
|
+
backendModels = existingConfig.routing.backend?.models || ["codex"];
|
|
2936
|
+
geminiModel = existingConfig.routing.geminiModel || "gemini-3.1-pro-preview";
|
|
2937
|
+
}
|
|
2938
|
+
}
|
|
2887
2939
|
let liteMode = false;
|
|
2888
2940
|
let mcpProvider = "ace-tool";
|
|
2889
2941
|
let aceToolBaseUrl = "";
|
|
@@ -2901,7 +2953,7 @@ async function init(options = {}) {
|
|
|
2901
2953
|
let apiKey = "";
|
|
2902
2954
|
if (!options.skipPrompt) {
|
|
2903
2955
|
console.log();
|
|
2904
|
-
console.log(ansis.cyan.bold(` \u{1F511} Step 1/
|
|
2956
|
+
console.log(ansis.cyan.bold(` \u{1F511} Step 1/4 \u2014 ${i18n.t("init:api.title")}`));
|
|
2905
2957
|
console.log();
|
|
2906
2958
|
const { apiProvider } = await inquirer.prompt([{
|
|
2907
2959
|
type: "list",
|
|
@@ -2933,11 +2985,63 @@ async function init(options = {}) {
|
|
|
2933
2985
|
apiKey = apiAnswers.key?.trim() || "";
|
|
2934
2986
|
}
|
|
2935
2987
|
}
|
|
2988
|
+
if (!options.skipPrompt) {
|
|
2989
|
+
const existingConfig = await readCcgConfig();
|
|
2990
|
+
console.log();
|
|
2991
|
+
console.log(ansis.cyan.bold(` \u{1F9E0} Step 2/4 \u2014 ${i18n.t("init:model.title")}`));
|
|
2992
|
+
console.log();
|
|
2993
|
+
const { selectedFrontend } = await inquirer.prompt([{
|
|
2994
|
+
type: "list",
|
|
2995
|
+
name: "selectedFrontend",
|
|
2996
|
+
message: i18n.t("init:model.selectFrontend"),
|
|
2997
|
+
choices: [
|
|
2998
|
+
{ name: `Gemini ${ansis.green(`(${i18n.t("init:model.recommended")})`)}`, value: "gemini" },
|
|
2999
|
+
{ name: "Codex", value: "codex" }
|
|
3000
|
+
],
|
|
3001
|
+
default: existingConfig?.routing?.frontend?.primary || "gemini"
|
|
3002
|
+
}]);
|
|
3003
|
+
const { selectedBackend } = await inquirer.prompt([{
|
|
3004
|
+
type: "list",
|
|
3005
|
+
name: "selectedBackend",
|
|
3006
|
+
message: i18n.t("init:model.selectBackend"),
|
|
3007
|
+
choices: [
|
|
3008
|
+
{ name: "Gemini", value: "gemini" },
|
|
3009
|
+
{ name: `Codex ${ansis.green(`(${i18n.t("init:model.recommended")})`)}`, value: "codex" }
|
|
3010
|
+
],
|
|
3011
|
+
default: existingConfig?.routing?.backend?.primary || "codex"
|
|
3012
|
+
}]);
|
|
3013
|
+
frontendModels = [selectedFrontend];
|
|
3014
|
+
backendModels = [selectedBackend];
|
|
3015
|
+
if (selectedFrontend === "gemini" || selectedBackend === "gemini") {
|
|
3016
|
+
const { selectedGeminiModel } = await inquirer.prompt([{
|
|
3017
|
+
type: "list",
|
|
3018
|
+
name: "selectedGeminiModel",
|
|
3019
|
+
message: i18n.t("init:model.selectGeminiModel"),
|
|
3020
|
+
choices: [
|
|
3021
|
+
{ name: `gemini-3.1-pro-preview ${ansis.green(`(${i18n.t("init:model.recommended")})`)}`, value: "gemini-3.1-pro-preview" },
|
|
3022
|
+
{ name: "gemini-2.5-flash", value: "gemini-2.5-flash" },
|
|
3023
|
+
{ name: `${i18n.t("init:model.custom")}`, value: "custom" }
|
|
3024
|
+
],
|
|
3025
|
+
default: existingConfig?.routing?.geminiModel || "gemini-3.1-pro-preview"
|
|
3026
|
+
}]);
|
|
3027
|
+
if (selectedGeminiModel === "custom") {
|
|
3028
|
+
const { customModel } = await inquirer.prompt([{
|
|
3029
|
+
type: "input",
|
|
3030
|
+
name: "customModel",
|
|
3031
|
+
message: i18n.t("init:model.enterCustomModel"),
|
|
3032
|
+
validate: (v) => v.trim() !== "" || i18n.t("init:model.enterCustomModel")
|
|
3033
|
+
}]);
|
|
3034
|
+
geminiModel = customModel.trim();
|
|
3035
|
+
} else {
|
|
3036
|
+
geminiModel = selectedGeminiModel;
|
|
3037
|
+
}
|
|
3038
|
+
}
|
|
3039
|
+
}
|
|
2936
3040
|
if (options.skipMcp) {
|
|
2937
3041
|
mcpProvider = "skip";
|
|
2938
3042
|
} else if (!options.skipPrompt) {
|
|
2939
3043
|
console.log();
|
|
2940
|
-
console.log(ansis.cyan.bold(` \u{1F527} Step
|
|
3044
|
+
console.log(ansis.cyan.bold(` \u{1F527} Step 3/4 \u2014 ${i18n.t("init:mcp.title")}`));
|
|
2941
3045
|
console.log();
|
|
2942
3046
|
const { selectedTools } = await inquirer.prompt([{
|
|
2943
3047
|
type: "checkbox",
|
|
@@ -3073,7 +3177,7 @@ async function init(options = {}) {
|
|
|
3073
3177
|
const existingConfig = await readCcgConfig();
|
|
3074
3178
|
const currentLiteMode = existingConfig?.performance?.liteMode || false;
|
|
3075
3179
|
console.log();
|
|
3076
|
-
console.log(ansis.cyan.bold(` \u26A1 Step
|
|
3180
|
+
console.log(ansis.cyan.bold(` \u26A1 Step 4/4 \u2014 ${i18n.t("init:perf.title")}`));
|
|
3077
3181
|
console.log();
|
|
3078
3182
|
const { perfMode } = await inquirer.prompt([{
|
|
3079
3183
|
type: "list",
|
|
@@ -3095,25 +3199,28 @@ async function init(options = {}) {
|
|
|
3095
3199
|
const routing = {
|
|
3096
3200
|
frontend: {
|
|
3097
3201
|
models: frontendModels,
|
|
3098
|
-
primary:
|
|
3202
|
+
primary: frontendModels[0],
|
|
3099
3203
|
strategy: "fallback"
|
|
3100
3204
|
},
|
|
3101
3205
|
backend: {
|
|
3102
3206
|
models: backendModels,
|
|
3103
|
-
primary:
|
|
3207
|
+
primary: backendModels[0],
|
|
3104
3208
|
strategy: "fallback"
|
|
3105
3209
|
},
|
|
3106
3210
|
review: {
|
|
3107
|
-
models: [
|
|
3211
|
+
models: [.../* @__PURE__ */ new Set([...frontendModels, ...backendModels])],
|
|
3108
3212
|
strategy: "parallel"
|
|
3109
3213
|
},
|
|
3110
|
-
mode
|
|
3214
|
+
mode,
|
|
3215
|
+
geminiModel
|
|
3111
3216
|
};
|
|
3112
3217
|
console.log();
|
|
3113
3218
|
console.log(ansis.yellow("\u2501".repeat(50)));
|
|
3114
3219
|
console.log(ansis.bold(` ${i18n.t("init:summary.title")}`));
|
|
3115
3220
|
console.log();
|
|
3116
|
-
|
|
3221
|
+
const fmName = frontendModels[0].charAt(0).toUpperCase() + frontendModels[0].slice(1);
|
|
3222
|
+
const bmName = backendModels[0].charAt(0).toUpperCase() + backendModels[0].slice(1);
|
|
3223
|
+
console.log(` ${ansis.cyan(i18n.t("init:summary.modelRouting"))} ${ansis.green(fmName)} (Frontend) + ${ansis.blue(bmName)} (Backend)`);
|
|
3117
3224
|
console.log(` ${ansis.cyan(i18n.t("init:summary.commandCount"))} ${ansis.yellow(selectedWorkflows.length.toString())}`);
|
|
3118
3225
|
const mcpSummary = (() => {
|
|
3119
3226
|
if (mcpProvider === "fast-context") return ansis.green("fast-context");
|
|
@@ -3886,6 +3993,7 @@ async function showMainMenu() {
|
|
|
3886
3993
|
item("3", i18n.t("menu:options.configMcp"), isZh ? "\u4EE3\u7801\u68C0\u7D22 MCP \u5DE5\u5177" : "Code retrieval MCP tool"),
|
|
3887
3994
|
item("4", i18n.t("menu:options.configApi"), isZh ? "\u81EA\u5B9A\u4E49 API \u7AEF\u70B9" : "Custom API endpoint"),
|
|
3888
3995
|
item("5", i18n.t("menu:options.configStyle"), isZh ? "\u9009\u62E9\u8F93\u51FA\u4EBA\u683C" : "Choose output personality"),
|
|
3996
|
+
item("6", i18n.t("menu:options.configModel"), isZh ? "\u524D\u7AEF/\u540E\u7AEF\u6A21\u578B\u5207\u6362" : "Switch frontend/backend models"),
|
|
3889
3997
|
groupSep(isZh ? "\u5176\u4ED6\u5DE5\u5177" : "Tools"),
|
|
3890
3998
|
item("T", i18n.t("menu:options.tools"), "ccusage, CCometixLine"),
|
|
3891
3999
|
item("C", i18n.t("menu:options.installClaude"), isZh ? "\u5B89\u88C5/\u91CD\u88C5 CLI" : "Install/reinstall CLI"),
|
|
@@ -3912,6 +4020,9 @@ async function showMainMenu() {
|
|
|
3912
4020
|
case "5":
|
|
3913
4021
|
await configOutputStyle();
|
|
3914
4022
|
break;
|
|
4023
|
+
case "6":
|
|
4024
|
+
await configModelRouting();
|
|
4025
|
+
break;
|
|
3915
4026
|
case "T":
|
|
3916
4027
|
await handleTools();
|
|
3917
4028
|
break;
|
|
@@ -4088,6 +4199,105 @@ const OUTPUT_STYLES = [
|
|
|
4088
4199
|
{ id: "abyss-command", nameKey: "menu:style.abyssCommand", descKey: "menu:style.abyssCommandDesc" },
|
|
4089
4200
|
{ id: "abyss-ritual", nameKey: "menu:style.abyssRitual", descKey: "menu:style.abyssRitualDesc" }
|
|
4090
4201
|
];
|
|
4202
|
+
async function configModelRouting() {
|
|
4203
|
+
const config = await readCcgConfig();
|
|
4204
|
+
(config?.general?.language || "zh-CN") === "zh-CN";
|
|
4205
|
+
console.log();
|
|
4206
|
+
console.log(ansis.cyan.bold(` ${i18n.t("init:model.title")}`));
|
|
4207
|
+
console.log();
|
|
4208
|
+
const currentFrontend = config?.routing?.frontend?.primary || "gemini";
|
|
4209
|
+
const currentBackend = config?.routing?.backend?.primary || "codex";
|
|
4210
|
+
const currentGeminiModel = config?.routing?.geminiModel || "gemini-3.1-pro-preview";
|
|
4211
|
+
console.log(ansis.gray(` ${i18n.t("init:model.currentRouting")}:`));
|
|
4212
|
+
console.log(` ${ansis.cyan("Frontend:")} ${ansis.green(currentFrontend)}`);
|
|
4213
|
+
console.log(` ${ansis.cyan("Backend:")} ${ansis.blue(currentBackend)}`);
|
|
4214
|
+
if (currentFrontend === "gemini" || currentBackend === "gemini") {
|
|
4215
|
+
console.log(` ${ansis.cyan("Gemini:")} ${ansis.gray(currentGeminiModel)}`);
|
|
4216
|
+
}
|
|
4217
|
+
console.log();
|
|
4218
|
+
const { selectedFrontend } = await inquirer.prompt([{
|
|
4219
|
+
type: "list",
|
|
4220
|
+
name: "selectedFrontend",
|
|
4221
|
+
message: i18n.t("init:model.selectFrontend"),
|
|
4222
|
+
choices: [
|
|
4223
|
+
{ name: `Gemini ${ansis.green(`(${i18n.t("init:model.recommended")})`)}`, value: "gemini" },
|
|
4224
|
+
{ name: "Codex", value: "codex" }
|
|
4225
|
+
],
|
|
4226
|
+
default: currentFrontend
|
|
4227
|
+
}]);
|
|
4228
|
+
const { selectedBackend } = await inquirer.prompt([{
|
|
4229
|
+
type: "list",
|
|
4230
|
+
name: "selectedBackend",
|
|
4231
|
+
message: i18n.t("init:model.selectBackend"),
|
|
4232
|
+
choices: [
|
|
4233
|
+
{ name: "Gemini", value: "gemini" },
|
|
4234
|
+
{ name: `Codex ${ansis.green(`(${i18n.t("init:model.recommended")})`)}`, value: "codex" }
|
|
4235
|
+
],
|
|
4236
|
+
default: currentBackend
|
|
4237
|
+
}]);
|
|
4238
|
+
let geminiModel = currentGeminiModel;
|
|
4239
|
+
if (selectedFrontend === "gemini" || selectedBackend === "gemini") {
|
|
4240
|
+
const { selectedGeminiModel } = await inquirer.prompt([{
|
|
4241
|
+
type: "list",
|
|
4242
|
+
name: "selectedGeminiModel",
|
|
4243
|
+
message: i18n.t("init:model.selectGeminiModel"),
|
|
4244
|
+
choices: [
|
|
4245
|
+
{ name: `gemini-3.1-pro-preview ${ansis.green(`(${i18n.t("init:model.recommended")})`)}`, value: "gemini-3.1-pro-preview" },
|
|
4246
|
+
{ name: "gemini-2.5-flash", value: "gemini-2.5-flash" },
|
|
4247
|
+
{ name: `${i18n.t("init:model.custom")}`, value: "custom" }
|
|
4248
|
+
],
|
|
4249
|
+
default: currentGeminiModel
|
|
4250
|
+
}]);
|
|
4251
|
+
if (selectedGeminiModel === "custom") {
|
|
4252
|
+
const { customModel } = await inquirer.prompt([{
|
|
4253
|
+
type: "input",
|
|
4254
|
+
name: "customModel",
|
|
4255
|
+
message: i18n.t("init:model.enterCustomModel"),
|
|
4256
|
+
validate: (v) => v.trim() !== "" || i18n.t("init:model.enterCustomModel")
|
|
4257
|
+
}]);
|
|
4258
|
+
geminiModel = customModel.trim();
|
|
4259
|
+
} else {
|
|
4260
|
+
geminiModel = selectedGeminiModel;
|
|
4261
|
+
}
|
|
4262
|
+
}
|
|
4263
|
+
if (selectedFrontend === currentFrontend && selectedBackend === currentBackend && geminiModel === currentGeminiModel) {
|
|
4264
|
+
console.log(ansis.gray(` ${i18n.t("common:configNotModified")}`));
|
|
4265
|
+
return;
|
|
4266
|
+
}
|
|
4267
|
+
if (config) {
|
|
4268
|
+
config.routing.frontend = {
|
|
4269
|
+
models: [selectedFrontend],
|
|
4270
|
+
primary: selectedFrontend,
|
|
4271
|
+
strategy: "fallback"
|
|
4272
|
+
};
|
|
4273
|
+
config.routing.backend = {
|
|
4274
|
+
models: [selectedBackend],
|
|
4275
|
+
primary: selectedBackend,
|
|
4276
|
+
strategy: "fallback"
|
|
4277
|
+
};
|
|
4278
|
+
config.routing.review = {
|
|
4279
|
+
models: [.../* @__PURE__ */ new Set([selectedFrontend, selectedBackend])],
|
|
4280
|
+
strategy: "parallel"
|
|
4281
|
+
};
|
|
4282
|
+
config.routing.geminiModel = geminiModel;
|
|
4283
|
+
await writeCcgConfig(config);
|
|
4284
|
+
}
|
|
4285
|
+
console.log();
|
|
4286
|
+
console.log(ansis.green(` \u2713 ${i18n.t("init:model.routingUpdated")}`));
|
|
4287
|
+
const spinner = ora(i18n.t("init:model.reinstalling")).start();
|
|
4288
|
+
try {
|
|
4289
|
+
const { execSync } = await import('node:child_process');
|
|
4290
|
+
execSync("npx --yes ccg-workflow init --force --skip-prompt --skip-mcp", {
|
|
4291
|
+
timeout: 3e5,
|
|
4292
|
+
stdio: "pipe",
|
|
4293
|
+
env: { ...process.env, CCG_UPDATE_MODE: "true" }
|
|
4294
|
+
});
|
|
4295
|
+
spinner.succeed(i18n.t("init:model.reinstallDone"));
|
|
4296
|
+
} catch {
|
|
4297
|
+
spinner.fail(i18n.t("init:model.reinstallFailed"));
|
|
4298
|
+
}
|
|
4299
|
+
console.log(ansis.gray(` ${i18n.t("common:restartToApply")}`));
|
|
4300
|
+
}
|
|
4091
4301
|
async function configOutputStyle() {
|
|
4092
4302
|
console.log();
|
|
4093
4303
|
console.log(ansis.cyan.bold(` ${i18n.t("menu:style.title")}`));
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: '多模型技术分析(并行执行):
|
|
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
|
-
- **
|
|
20
|
-
- **
|
|
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 <
|
|
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. **
|
|
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. **
|
|
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: '后端专项工作流(研究→构思→计划→执行→优化→评审),
|
|
2
|
+
description: '后端专项工作流(研究→构思→计划→执行→优化→评审),{{BACKEND_PRIMARY}} 主导'
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
# Backend - 后端专项开发
|
|
@@ -13,7 +13,7 @@ description: '后端专项工作流(研究→构思→计划→执行→优化
|
|
|
13
13
|
## 上下文
|
|
14
14
|
|
|
15
15
|
- 后端任务:$ARGUMENTS
|
|
16
|
-
-
|
|
16
|
+
- {{BACKEND_PRIMARY}} 主导,{{FRONTEND_PRIMARY}} 辅助参考
|
|
17
17
|
- 适用:API 设计、算法实现、数据库优化、业务逻辑
|
|
18
18
|
|
|
19
19
|
## 你的角色
|
|
@@ -21,8 +21,8 @@ description: '后端专项工作流(研究→构思→计划→执行→优化
|
|
|
21
21
|
你是**后端编排者**,协调多模型完成服务端任务(研究 → 构思 → 计划 → 执行 → 优化 → 评审),用中文协助用户。
|
|
22
22
|
|
|
23
23
|
**协作模型**:
|
|
24
|
-
- **
|
|
25
|
-
- **
|
|
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
|
|
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
|
|
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
|
-
`[模式:构思]` -
|
|
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
|
-
`[模式:计划]` -
|
|
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
|
-
`[模式:优化]` -
|
|
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. **
|
|
165
|
-
2. **
|
|
164
|
+
1. **{{BACKEND_PRIMARY}} 后端意见可信赖**
|
|
165
|
+
2. **{{FRONTEND_PRIMARY}} 后端意见仅供参考**
|
|
166
166
|
3. 外部模型对文件系统**零写入权限**
|
|
167
167
|
4. Claude 负责所有代码写入和文件操作
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: '
|
|
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 重构
|
|
28
|
-
| MCP 搜索 | Claude 调用 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
|
-
**
|
|
49
|
+
**{{BACKEND_PRIMARY}} 执行调用语法**:
|
|
50
50
|
|
|
51
51
|
```
|
|
52
52
|
Bash({
|
|
53
|
-
command: "~/.claude/bin/codeagent-wrapper {{LITE_MODE_FLAG}}--progress --backend
|
|
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
|
-
**
|
|
64
|
+
**{{BACKEND_PRIMARY}} 复用会话调用**:
|
|
65
65
|
|
|
66
66
|
```
|
|
67
67
|
Bash({
|
|
68
|
-
command: "~/.claude/bin/codeagent-wrapper {{LITE_MODE_FLAG}}--progress --backend
|
|
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 <
|
|
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
|
|
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
|
|
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
|
-
- **
|
|
309
|
+
- **{{BACKEND_PRIMARY}} 审查**:
|
|
313
310
|
- ROLE_FILE: `~/.claude/.ccg/prompts/codex/reviewer.md`
|
|
314
311
|
- 输入:变更 Diff + 计划文件内容
|
|
315
312
|
- 关注:安全性、性能、错误处理、逻辑正确性
|
|
316
313
|
|
|
317
|
-
- **
|
|
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. **
|
|
373
|
+
2. **{{BACKEND_PRIMARY}} 全权执行** — MCP 搜索、文档查询、代码检索、实现、测试全由 {{BACKEND_PRIMARY}} 完成。
|
|
377
374
|
3. **多模型审核不变** — 审核阶段仍然 Codex ∥ Gemini 交叉审查,保证质量。
|
|
378
375
|
4. **信任规则** — 后端以 Codex 为准,前端以 Gemini 为准。
|
|
379
376
|
5. **一次性下发** — 尽量一次给 Codex 完整指令 + 完整计划,减少来回通信。
|