ccg-workflow 3.1.0 → 3.1.2

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
@@ -26,7 +26,9 @@
26
26
 
27
27
  ---
28
28
 
29
- [**n1n.ai**](https://api.n1n.ai/register?channel=c_ivgzug0w) — Global LLM API Gateway. One API Key to access 500+ top AI models (GPT-5, Claude 4.5, Gemini 3 Pro, and more).
29
+ [![NotebookLM Remover](assets/sponsors/notebooklm-remover.png)](https://notebooklmremover.org)
30
+
31
+ [NotebookLM Remover](https://notebooklmremover.org) — Free browser-local AI watermark remover. Remove NotebookLM watermarks across every format — video, PDF, PPTX, infographic, podcast, and more. 100% private, works offline.
30
32
 
31
33
  ---
32
34
 
@@ -251,4 +253,4 @@ MIT
251
253
 
252
254
  ---
253
255
 
254
- v3.0.4 | [Issues](https://github.com/fengshao1227/ccg-workflow/issues) | [Contributing](./CONTRIBUTING.md)
256
+ v3.1.2 | [Issues](https://github.com/fengshao1227/ccg-workflow/issues) | [Contributing](./CONTRIBUTING.md)
package/README.zh-CN.md CHANGED
@@ -27,7 +27,9 @@
27
27
 
28
28
  ---
29
29
 
30
- [**n1n.ai**](https://api.n1n.ai/register?channel=c_ivgzug0w) — Global LLM API Gateway. One API Key to access 500+ top AI models (GPT-5, Claude 4.5, Gemini 3 Pro, and more).
30
+ [![NotebookLM Remover](assets/sponsors/notebooklm-remover.png)](https://notebooklmremover.org)
31
+
32
+ [NotebookLM Remover](https://notebooklmremover.org) — 免费浏览器本地 AI 水印去除工具。支持视频、PDF、PPTX、信息图、播客等全格式,100% 隐私,离线可用。
31
33
 
32
34
  ---
33
35
 
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 { B as diagnoseMcpConfig, C as isWindows, D as readClaudeCodeConfig, E as fixWindowsMcpConfig, F as writeClaudeCodeConfig, r as readCcgConfig, b as initI18n, a as i18n, s as showMainMenu, i as init, G as configMcp, H as version } from './shared/ccg-workflow.B4hxlK6F.mjs';
4
+ import { B as diagnoseMcpConfig, C as isWindows, D as readClaudeCodeConfig, E as fixWindowsMcpConfig, F as writeClaudeCodeConfig, r as readCcgConfig, b as initI18n, a as i18n, s as showMainMenu, i as init, G as configMcp, H as version } from './shared/ccg-workflow.CTnUpMWE.mjs';
5
5
  import 'inquirer';
6
6
  import 'ora';
7
7
  import 'node:child_process';
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { c as changeLanguage, z as checkForUpdates, A as compareVersions, d as createDefaultConfig, e as createDefaultRouting, g as getCcgDir, f as getConfigPath, x as getCurrentVersion, y as getLatestVersion, j as getWorkflowById, h as getWorkflowConfigs, a as i18n, i as init, b as initI18n, l as installAceTool, m as installAceToolRs, n as installCodexMode, k as installWorkflows, t as migrateToV1_4_0, v as needsMigration, r as readCcgConfig, s as showMainMenu, q as uninstallAceTool, o as uninstallCodexMode, p as uninstallWorkflows, u as update, w as writeCcgConfig } from './shared/ccg-workflow.B4hxlK6F.mjs';
1
+ export { c as changeLanguage, z as checkForUpdates, A as compareVersions, d as createDefaultConfig, e as createDefaultRouting, g as getCcgDir, f as getConfigPath, x as getCurrentVersion, y as getLatestVersion, j as getWorkflowById, h as getWorkflowConfigs, a as i18n, i as init, b as initI18n, l as installAceTool, m as installAceToolRs, n as installCodexMode, k as installWorkflows, t as migrateToV1_4_0, v as needsMigration, r as readCcgConfig, s as showMainMenu, q as uninstallAceTool, o as uninstallCodexMode, p as uninstallWorkflows, u as update, w as writeCcgConfig } from './shared/ccg-workflow.CTnUpMWE.mjs';
2
2
  import 'ansis';
3
3
  import 'inquirer';
4
4
  import 'ora';
@@ -10,7 +10,7 @@ import fs from 'fs-extra';
10
10
  import { parse, stringify } from 'smol-toml';
11
11
  import i18next from 'i18next';
12
12
 
13
- const version = "3.1.0";
13
+ const version = "3.1.2";
14
14
 
15
15
  function cmd(id, order, category, name, nameEn, description, descriptionEn, cmdOverride) {
16
16
  return {
@@ -197,6 +197,79 @@ function replaceHomePathsInTemplate(content, installDir) {
197
197
  return processed;
198
198
  }
199
199
 
200
+ const CCG_DIR = join(homedir(), ".claude", ".ccg");
201
+ const CONFIG_FILE = join(CCG_DIR, "config.toml");
202
+ function getCcgDir() {
203
+ return CCG_DIR;
204
+ }
205
+ function getConfigPath() {
206
+ return CONFIG_FILE;
207
+ }
208
+ async function ensureCcgDir() {
209
+ await fs.ensureDir(CCG_DIR);
210
+ }
211
+ async function readCcgConfig() {
212
+ try {
213
+ if (await fs.pathExists(CONFIG_FILE)) {
214
+ const content = await fs.readFile(CONFIG_FILE, "utf-8");
215
+ return parse(content);
216
+ }
217
+ } catch {
218
+ }
219
+ return null;
220
+ }
221
+ async function writeCcgConfig(config) {
222
+ await ensureCcgDir();
223
+ const content = stringify(config);
224
+ await fs.writeFile(CONFIG_FILE, content, "utf-8");
225
+ }
226
+ function createDefaultConfig(options) {
227
+ return {
228
+ general: {
229
+ version: version,
230
+ language: options.language,
231
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
232
+ },
233
+ routing: options.routing,
234
+ workflows: {
235
+ installed: options.installedWorkflows
236
+ },
237
+ paths: {
238
+ commands: join(homedir(), ".claude", "commands", "ccg"),
239
+ prompts: join(CCG_DIR, "prompts"),
240
+ // v1.4.0: 移到配置目录
241
+ backup: join(CCG_DIR, "backup")
242
+ },
243
+ mcp: {
244
+ provider: options.mcpProvider || "fast-context",
245
+ setup_url: "https://augmentcode.com/"
246
+ },
247
+ performance: {
248
+ liteMode: options.liteMode || false,
249
+ skipImpeccable: options.skipImpeccable || false
250
+ }
251
+ };
252
+ }
253
+ function createDefaultRouting() {
254
+ return {
255
+ frontend: {
256
+ models: ["antigravity"],
257
+ primary: "antigravity",
258
+ strategy: "parallel"
259
+ },
260
+ backend: {
261
+ models: ["codex"],
262
+ primary: "codex",
263
+ strategy: "parallel"
264
+ },
265
+ review: {
266
+ models: ["codex", "antigravity"],
267
+ strategy: "parallel"
268
+ },
269
+ mode: "smart"
270
+ };
271
+ }
272
+
200
273
  const DEFAULT_ALLOWED_TOOLS = ["Read"];
201
274
  const NAME_SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
202
275
  const TOOL_NAME_RE = /^[A-Z][A-Za-z0-9]*$/;
@@ -1100,6 +1173,12 @@ async function installCodexMode() {
1100
1173
  try {
1101
1174
  const codexHome = join(homedir(), ".codex");
1102
1175
  await fs.ensureDir(join(codexHome, "agents"));
1176
+ const config = await readCcgConfig();
1177
+ const injectOpts = {
1178
+ routing: config?.routing,
1179
+ liteMode: config?.performance?.liteMode || false,
1180
+ mcpProvider: config?.mcp?.provider || "skip"
1181
+ };
1103
1182
  const configSrc = join(codexTemplateDir, "config.toml");
1104
1183
  const configDest = join(codexHome, "config.toml");
1105
1184
  if (await fs.pathExists(configSrc) && !await fs.pathExists(configDest)) {
@@ -1111,16 +1190,32 @@ async function installCodexMode() {
1111
1190
  }
1112
1191
  const agentsMdSrc = join(codexTemplateDir, "AGENTS.md");
1113
1192
  if (await fs.pathExists(agentsMdSrc)) {
1114
- await fs.copy(agentsMdSrc, join(codexHome, "AGENTS.md"), { overwrite: true });
1193
+ let content = await fs.readFile(agentsMdSrc, "utf-8");
1194
+ content = injectConfigVariables(content, injectOpts);
1195
+ await fs.writeFile(join(codexHome, "AGENTS.md"), content, "utf-8");
1115
1196
  }
1116
1197
  const hooksSrc = join(codexTemplateDir, "hooks");
1117
1198
  if (await fs.pathExists(hooksSrc)) {
1118
- await fs.ensureDir(join(codexHome, "hooks"));
1119
- await fs.copy(hooksSrc, join(codexHome, "hooks"), { overwrite: true });
1199
+ const hooksDest = join(codexHome, "hooks");
1200
+ await fs.ensureDir(hooksDest);
1201
+ for (const file of await fs.readdir(hooksSrc)) {
1202
+ const srcFile = join(hooksSrc, file);
1203
+ const destFile = join(hooksDest, file);
1204
+ if (file.endsWith(".py")) {
1205
+ let content = await fs.readFile(srcFile, "utf-8");
1206
+ content = injectConfigVariables(content, injectOpts);
1207
+ await fs.writeFile(destFile, content, "utf-8");
1208
+ } else {
1209
+ await fs.copy(srcFile, destFile, { overwrite: true });
1210
+ }
1211
+ }
1120
1212
  }
1121
1213
  const hooksJsonSrc = join(codexTemplateDir, "hooks.json");
1122
1214
  if (await fs.pathExists(hooksJsonSrc)) {
1123
- await fs.copy(hooksJsonSrc, join(codexHome, "hooks.json"), { overwrite: true });
1215
+ let content = await fs.readFile(hooksJsonSrc, "utf-8");
1216
+ const absHome = homedir().replace(/\\/g, "/");
1217
+ content = content.replace(/~\//g, `${absHome}/`);
1218
+ await fs.writeFile(join(codexHome, "hooks.json"), content, "utf-8");
1124
1219
  }
1125
1220
  return {
1126
1221
  success: true,
@@ -2888,79 +2983,6 @@ async function changeLanguage(lang) {
2888
2983
  await i18n.changeLanguage(lang);
2889
2984
  }
2890
2985
 
2891
- const CCG_DIR = join(homedir(), ".claude", ".ccg");
2892
- const CONFIG_FILE = join(CCG_DIR, "config.toml");
2893
- function getCcgDir() {
2894
- return CCG_DIR;
2895
- }
2896
- function getConfigPath() {
2897
- return CONFIG_FILE;
2898
- }
2899
- async function ensureCcgDir() {
2900
- await fs.ensureDir(CCG_DIR);
2901
- }
2902
- async function readCcgConfig() {
2903
- try {
2904
- if (await fs.pathExists(CONFIG_FILE)) {
2905
- const content = await fs.readFile(CONFIG_FILE, "utf-8");
2906
- return parse(content);
2907
- }
2908
- } catch {
2909
- }
2910
- return null;
2911
- }
2912
- async function writeCcgConfig(config) {
2913
- await ensureCcgDir();
2914
- const content = stringify(config);
2915
- await fs.writeFile(CONFIG_FILE, content, "utf-8");
2916
- }
2917
- function createDefaultConfig(options) {
2918
- return {
2919
- general: {
2920
- version: version,
2921
- language: options.language,
2922
- createdAt: (/* @__PURE__ */ new Date()).toISOString()
2923
- },
2924
- routing: options.routing,
2925
- workflows: {
2926
- installed: options.installedWorkflows
2927
- },
2928
- paths: {
2929
- commands: join(homedir(), ".claude", "commands", "ccg"),
2930
- prompts: join(CCG_DIR, "prompts"),
2931
- // v1.4.0: 移到配置目录
2932
- backup: join(CCG_DIR, "backup")
2933
- },
2934
- mcp: {
2935
- provider: options.mcpProvider || "fast-context",
2936
- setup_url: "https://augmentcode.com/"
2937
- },
2938
- performance: {
2939
- liteMode: options.liteMode || false,
2940
- skipImpeccable: options.skipImpeccable || false
2941
- }
2942
- };
2943
- }
2944
- function createDefaultRouting() {
2945
- return {
2946
- frontend: {
2947
- models: ["antigravity"],
2948
- primary: "antigravity",
2949
- strategy: "parallel"
2950
- },
2951
- backend: {
2952
- models: ["codex"],
2953
- primary: "codex",
2954
- strategy: "parallel"
2955
- },
2956
- review: {
2957
- models: ["codex", "antigravity"],
2958
- strategy: "parallel"
2959
- },
2960
- mode: "smart"
2961
- };
2962
- }
2963
-
2964
2986
  async function migrateToV1_4_0() {
2965
2987
  const result = {
2966
2988
  success: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccg-workflow",
3
- "version": "3.1.0",
3
+ "version": "3.1.2",
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",
@@ -23,12 +23,12 @@ You are the **lead orchestrator** of a multi-model development team. You think,
23
23
 
24
24
  ```
25
25
  S + 低风险 → 直接写,跑测试,完事
26
- S + 高风险 → 直接写,但必须调双模型审查(Gemini + Claude)
27
- M + 任意 → 双模型并行分析(Gemini + Claude 都调),再写,完成后双模型审查
26
+ S + 高风险 → 直接写,但必须调双模型审查({{FRONTEND_PRIMARY}} + Claude)
27
+ M + 任意 → 双模型并行分析({{FRONTEND_PRIMARY}} + Claude 都调),再写,完成后双模型审查
28
28
  L+ + 任意 → 双模型并行分析,制定 plan.md,spawn 子 Agent 并行写,双模型审查
29
29
  ```
30
30
 
31
- **⛔ M 以上复杂度,分析和审查都必须是双模型(Gemini + Claude 都调)。**
31
+ **⛔ M 以上复杂度,分析和审查都必须是双模型({{FRONTEND_PRIMARY}} + Claude 都调)。**
32
32
  这是 CCG 的核心价值——两个模型从不同角度分析同一个问题,交叉验证,弥补单模型盲区。只调一个模型 = 浪费了多模型协作的意义。
33
33
 
34
34
  **不确定时,选高一级。** 宁可多做一步分析,不可写完才发现方向错了。
@@ -127,13 +127,13 @@ ls .ccg/spec/ 2>/dev/null
127
127
  ### ⛔ 默认调用方式:双模型并行(M+ 复杂度必须用这个)
128
128
 
129
129
  ```bash
130
- ~/.claude/bin/codeagent-wrapper --progress --backend gemini - "$(pwd)" <<'GEMINI_EOF'
131
- ROLE_FILE: ~/.claude/.ccg/prompts/gemini/$ROLE.md
130
+ ~/.claude/bin/codeagent-wrapper --progress --backend {{FRONTEND_PRIMARY}} - "$(pwd)" <<'FRONTEND_EOF'
131
+ ROLE_FILE: ~/.claude/.ccg/prompts/{{FRONTEND_PRIMARY}}/$ROLE.md
132
132
  <TASK>
133
133
  {任务描述 + 上下文}
134
134
  </TASK>
135
135
  OUTPUT: {期望输出格式}
136
- GEMINI_EOF
136
+ FRONTEND_EOF
137
137
  &
138
138
  ~/.claude/bin/codeagent-wrapper --progress --backend claude - "$(pwd)" <<'CLAUDE_EOF'
139
139
  ROLE_FILE: ~/.claude/.ccg/prompts/claude/$ROLE.md
@@ -150,10 +150,10 @@ wait
150
150
 
151
151
  ### 单模型调用(仅 S 复杂度可用)
152
152
 
153
- #### Gemini(前端/UI 分析)
153
+ #### {{FRONTEND_PRIMARY}}(前端/UI 分析)
154
154
  ```bash
155
- ~/.claude/bin/codeagent-wrapper --progress --backend gemini - "$(pwd)" <<'EOF'
156
- ROLE_FILE: ~/.claude/.ccg/prompts/gemini/$ROLE.md
155
+ ~/.claude/bin/codeagent-wrapper --progress --backend {{FRONTEND_PRIMARY}} - "$(pwd)" <<'EOF'
156
+ ROLE_FILE: ~/.claude/.ccg/prompts/{{FRONTEND_PRIMARY}}/$ROLE.md
157
157
  <TASK>
158
158
  {任务描述 + 上下文}
159
159
  </TASK>
@@ -279,7 +279,7 @@ Critical 问题 → spawn 修复代理。Warning → 视情况修复。
279
279
  - [ ] git diff 只有预期变更
280
280
 
281
281
  ### 何时调外部模型审查
282
- - 变更 >30 行 → **必须**调双模型审查(Gemini + Claude 都调)
282
+ - 变更 >30 行 → **必须**调双模型审查({{FRONTEND_PRIMARY}} + Claude 都调)
283
283
  - 变更 ≤30 行但涉及 auth/数据库/加密 → **必须**调双模型审查
284
284
  - 变更 ≤30 行且低风险 → 可以只调一个
285
285
 
@@ -287,8 +287,8 @@ Critical 问题 → spawn 修复代理。Warning → 视情况修复。
287
287
 
288
288
  ```bash
289
289
  # 必须并行调用两个模型审查 git diff
290
- ~/.claude/bin/codeagent-wrapper --progress --backend gemini - "$(pwd)" <<'EOF'
291
- ROLE_FILE: ~/.claude/.ccg/prompts/gemini/reviewer.md
290
+ ~/.claude/bin/codeagent-wrapper --progress --backend {{FRONTEND_PRIMARY}} - "$(pwd)" <<'EOF'
291
+ ROLE_FILE: ~/.claude/.ccg/prompts/{{FRONTEND_PRIMARY}}/reviewer.md
292
292
  <TASK>审查以下代码变更:$(git diff)</TASK>
293
293
  OUTPUT: Critical/Warning/Info 分级审查报告
294
294
  EOF
@@ -127,8 +127,8 @@ def build_guidance(task, progress, root):
127
127
  if phase == "analysis":
128
128
  if complexity in ("M", "L", "XL"):
129
129
  parts.append("")
130
- parts.append(f"⛔ {complexity} complexity: you MUST call BOTH Gemini AND Claude for parallel analysis before coding.")
131
- parts.append("Use the dual-model parallel template in AGENTS.md: --backend gemini & --backend claude with & + wait.")
130
+ parts.append(f"⛔ {complexity} complexity: you MUST call BOTH the frontend model AND Claude for parallel analysis before coding.")
131
+ parts.append("Use the dual-model parallel template in AGENTS.md: --backend {{FRONTEND_PRIMARY}} & --backend claude with & + wait.")
132
132
 
133
133
  # Phase: implementation — coding in progress
134
134
  elif phase == "implementation":
@@ -146,12 +146,12 @@ def build_guidance(task, progress, root):
146
146
  # Big changes without review
147
147
  if progress["changed_lines"] > 30 and phase != "review":
148
148
  parts.append("")
149
- parts.append(f"⚠️ {progress['changed_lines']} lines changed. When done coding, you MUST call BOTH Gemini AND Claude for dual-model review. Not just one — both.")
149
+ parts.append(f"⚠️ {progress['changed_lines']} lines changed. When done coding, you MUST call BOTH the frontend model AND Claude for dual-model review. Not just one — both.")
150
150
 
151
151
  # Review phase: enforce dual model
152
152
  if phase == "review":
153
153
  parts.append("")
154
- parts.append("⛔ Review phase: call BOTH Gemini (--backend gemini) AND Claude (--backend claude) with reviewer role. Two models, not one.")
154
+ parts.append("⛔ Review phase: call BOTH the frontend model (--backend {{FRONTEND_PRIMARY}}) AND Claude (--backend claude) with reviewer role. Two models, not one.")
155
155
 
156
156
  # High-risk files detected
157
157
  if progress["high_risk_files"] and phase not in ("review", "completed"):
@@ -5,7 +5,7 @@
5
5
  "hooks": [
6
6
  {
7
7
  "type": "command",
8
- "command": "python3 .codex/hooks/ccg-workflow.py",
8
+ "command": "python3 ~/.codex/hooks/ccg-workflow.py",
9
9
  "timeout": 10
10
10
  }
11
11
  ]