ccg-workflow 3.0.3 → 3.0.5

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
@@ -42,6 +42,7 @@ v3.0 is a ground-up rewrite. One command replaces 29.
42
42
  - **Agent Teams** — Large tasks spawn parallel Builder teammates via TeamCreate. Each Builder gets isolated file ownership.
43
43
  - **Quality gates** — `verify-security`, `verify-quality`, `verify-change` run as Skill invocations inside strategy verification phases.
44
44
  - **Domain knowledge hooks** — When your message mentions security, caching, RAG, etc., the relevant knowledge file is auto-injected into context.
45
+ - **Codex-Led Mode** — Use Codex CLI as the lead orchestrator. Codex writes code directly and dispatches analysis/review to Gemini + Claude via codeagent-wrapper. Install via menu option `X`.
45
46
 
46
47
  ## Quick Start
47
48
 
@@ -250,4 +251,4 @@ MIT
250
251
 
251
252
  ---
252
253
 
253
- v3.0.3 | [Issues](https://github.com/fengshao1227/ccg-workflow/issues) | [Contributing](./CONTRIBUTING.md)
254
+ v3.0.4 | [Issues](https://github.com/fengshao1227/ccg-workflow/issues) | [Contributing](./CONTRIBUTING.md)
package/README.zh-CN.md CHANGED
@@ -43,6 +43,7 @@ v3.0 从底层重写。一个命令替代 29 个。
43
43
  - **Agent Teams** — 大型任务通过 TeamCreate 并行 spawn 多个 Builder。每个 Builder 有独立文件所有权。
44
44
  - **质量关卡** — `verify-security`、`verify-quality`、`verify-change` 作为 Skill 在策略验证阶段强制调用。
45
45
  - **域知识 Hook** — 消息涉及安全、缓存、RAG 等关键词时,相关知识文件自动注入上下文。
46
+ - **Codex 主导模式** — 用 Codex CLI 作为主编排器,Codex 自己写代码,同时调度 Gemini + Claude 做分析和审查。菜单 `X` 选项安装。
46
47
 
47
48
  ## 快速开始
48
49
 
@@ -245,4 +246,4 @@ MIT
245
246
 
246
247
  ---
247
248
 
248
- v3.0.3 | [Issues](https://github.com/fengshao1227/ccg-workflow/issues) | [Contributing](./CONTRIBUTING.md)
249
+ v3.0.4 | [Issues](https://github.com/fengshao1227/ccg-workflow/issues) | [Contributing](./CONTRIBUTING.md)
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.DxKAcBrr.mjs';
4
+ import { A as diagnoseMcpConfig, B as isWindows, C as readClaudeCodeConfig, D as fixWindowsMcpConfig, E as writeClaudeCodeConfig, r as readCcgConfig, b as initI18n, a as i18n, s as showMainMenu, i as init, F as configMcp, G as version } from './shared/ccg-workflow.B4dDUxv8.mjs';
5
5
  import 'inquirer';
6
6
  import 'ora';
7
7
  import 'node:child_process';
package/dist/index.d.mts CHANGED
@@ -153,6 +153,15 @@ declare function installAceTool(config: AceToolConfig): Promise<McpInstallResult
153
153
  */
154
154
  declare function installAceToolRs(config: AceToolConfig): Promise<McpInstallResult>;
155
155
 
156
+ /**
157
+ * Install Codex-mode files: AGENTS.md + .codex/config.toml + .codex/agents/*.toml
158
+ * These enable Codex CLI as an alternative lead orchestrator (Codex-led multi-model mode).
159
+ * Files are installed to ~/.codex/ (global) and user copies AGENTS.md to project root.
160
+ */
161
+ declare function installCodexMode(): Promise<{
162
+ success: boolean;
163
+ message: string;
164
+ }>;
156
165
  declare function installWorkflows(workflowIds: string[], installDir: string, force?: boolean, config?: {
157
166
  routing?: {
158
167
  mode?: string;
@@ -235,5 +244,5 @@ declare function checkForUpdates(): Promise<{
235
244
  latestVersion: string | null;
236
245
  }>;
237
246
 
238
- export { changeLanguage, checkForUpdates, compareVersions, createDefaultConfig, createDefaultRouting, getCcgDir, getConfigPath, getCurrentVersion, getLatestVersion, getWorkflowById, getWorkflowConfigs, i18n, init, initI18n, installAceTool, installAceToolRs, installWorkflows, migrateToV1_4_0, needsMigration, readCcgConfig, showMainMenu, uninstallAceTool, uninstallWorkflows, update, writeCcgConfig };
247
+ export { changeLanguage, checkForUpdates, compareVersions, createDefaultConfig, createDefaultRouting, getCcgDir, getConfigPath, getCurrentVersion, getLatestVersion, getWorkflowById, getWorkflowConfigs, i18n, init, initI18n, installAceTool, installAceToolRs, installCodexMode, installWorkflows, migrateToV1_4_0, needsMigration, readCcgConfig, showMainMenu, uninstallAceTool, uninstallWorkflows, update, writeCcgConfig };
239
248
  export type { AceToolConfig, CcgConfig, CliOptions, CollaborationMode, FastContextConfig, InitOptions, InstallResult, ModelRouting, ModelType, RoutingStrategy, SupportedLang, WorkflowConfig };
package/dist/index.d.ts CHANGED
@@ -153,6 +153,15 @@ declare function installAceTool(config: AceToolConfig): Promise<McpInstallResult
153
153
  */
154
154
  declare function installAceToolRs(config: AceToolConfig): Promise<McpInstallResult>;
155
155
 
156
+ /**
157
+ * Install Codex-mode files: AGENTS.md + .codex/config.toml + .codex/agents/*.toml
158
+ * These enable Codex CLI as an alternative lead orchestrator (Codex-led multi-model mode).
159
+ * Files are installed to ~/.codex/ (global) and user copies AGENTS.md to project root.
160
+ */
161
+ declare function installCodexMode(): Promise<{
162
+ success: boolean;
163
+ message: string;
164
+ }>;
156
165
  declare function installWorkflows(workflowIds: string[], installDir: string, force?: boolean, config?: {
157
166
  routing?: {
158
167
  mode?: string;
@@ -235,5 +244,5 @@ declare function checkForUpdates(): Promise<{
235
244
  latestVersion: string | null;
236
245
  }>;
237
246
 
238
- export { changeLanguage, checkForUpdates, compareVersions, createDefaultConfig, createDefaultRouting, getCcgDir, getConfigPath, getCurrentVersion, getLatestVersion, getWorkflowById, getWorkflowConfigs, i18n, init, initI18n, installAceTool, installAceToolRs, installWorkflows, migrateToV1_4_0, needsMigration, readCcgConfig, showMainMenu, uninstallAceTool, uninstallWorkflows, update, writeCcgConfig };
247
+ export { changeLanguage, checkForUpdates, compareVersions, createDefaultConfig, createDefaultRouting, getCcgDir, getConfigPath, getCurrentVersion, getLatestVersion, getWorkflowById, getWorkflowConfigs, i18n, init, initI18n, installAceTool, installAceToolRs, installCodexMode, installWorkflows, migrateToV1_4_0, needsMigration, readCcgConfig, showMainMenu, uninstallAceTool, uninstallWorkflows, update, writeCcgConfig };
239
248
  export type { AceToolConfig, CcgConfig, CliOptions, CollaborationMode, FastContextConfig, InitOptions, InstallResult, ModelRouting, ModelType, RoutingStrategy, SupportedLang, WorkflowConfig };
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.DxKAcBrr.mjs';
1
+ export { c as changeLanguage, y as checkForUpdates, z as compareVersions, d as createDefaultConfig, e as createDefaultRouting, g as getCcgDir, f as getConfigPath, v as getCurrentVersion, x 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, q as migrateToV1_4_0, t as needsMigration, r as readCcgConfig, s as showMainMenu, p as uninstallAceTool, o as uninstallWorkflows, u as update, w as writeCcgConfig } from './shared/ccg-workflow.B4dDUxv8.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.0.3";
13
+ const version = "3.0.5";
14
14
 
15
15
  function cmd(id, order, category, name, nameEn, description, descriptionEn, cmdOverride) {
16
16
  return {
@@ -1092,6 +1092,51 @@ async function installSkillGeneratedCommands(ctx) {
1092
1092
  ctx.result.errors.push(`Skill Registry command generation warning: ${error}`);
1093
1093
  }
1094
1094
  }
1095
+ async function installCodexMode() {
1096
+ const codexTemplateDir = join(PACKAGE_ROOT$1, "templates", "codex");
1097
+ if (!await fs.pathExists(codexTemplateDir)) {
1098
+ return { success: false, message: "Codex template directory not found" };
1099
+ }
1100
+ try {
1101
+ const codexHome = join(homedir(), ".codex");
1102
+ await fs.ensureDir(join(codexHome, "agents"));
1103
+ const configSrc = join(codexTemplateDir, "config.toml");
1104
+ const configDest = join(codexHome, "config.toml");
1105
+ if (await fs.pathExists(configSrc) && !await fs.pathExists(configDest)) {
1106
+ await fs.copy(configSrc, configDest);
1107
+ }
1108
+ const agentsSrc = join(codexTemplateDir, "agents");
1109
+ if (await fs.pathExists(agentsSrc)) {
1110
+ await fs.copy(agentsSrc, join(codexHome, "agents"), { overwrite: true });
1111
+ }
1112
+ const agentsMdSrc = join(codexTemplateDir, "AGENTS.md");
1113
+ if (await fs.pathExists(agentsMdSrc)) {
1114
+ await fs.copy(agentsMdSrc, join(codexHome, "AGENTS.md"), { overwrite: true });
1115
+ }
1116
+ const hooksSrc = join(codexTemplateDir, "hooks");
1117
+ if (await fs.pathExists(hooksSrc)) {
1118
+ await fs.ensureDir(join(codexHome, "hooks"));
1119
+ await fs.copy(hooksSrc, join(codexHome, "hooks"), { overwrite: true });
1120
+ }
1121
+ const hooksJsonSrc = join(codexTemplateDir, "hooks.json");
1122
+ if (await fs.pathExists(hooksJsonSrc)) {
1123
+ await fs.copy(hooksJsonSrc, join(codexHome, "hooks.json"), { overwrite: true });
1124
+ }
1125
+ return {
1126
+ success: true,
1127
+ message: `Codex mode installed:
1128
+ ~/.codex/AGENTS.md
1129
+ ~/.codex/config.toml
1130
+ ~/.codex/hooks.json
1131
+ ~/.codex/hooks/ccg-workflow.py
1132
+ ~/.codex/agents/ccg-implement.toml
1133
+ ~/.codex/agents/ccg-review.toml
1134
+ ~/.codex/agents/ccg-research.toml`
1135
+ };
1136
+ } catch (error) {
1137
+ return { success: false, message: `Failed to install Codex mode: ${error}` };
1138
+ }
1139
+ }
1095
1140
  async function installRuleFiles(ctx) {
1096
1141
  try {
1097
1142
  const installed = await copyMdTemplates(
@@ -1436,6 +1481,7 @@ const installer = {
1436
1481
  injectConfigVariables: injectConfigVariables,
1437
1482
  installAceTool: installAceTool,
1438
1483
  installAceToolRs: installAceToolRs,
1484
+ installCodexMode: installCodexMode,
1439
1485
  installContextWeaver: installContextWeaver,
1440
1486
  installFastContext: installFastContext,
1441
1487
  installMcpServer: installMcpServer,
@@ -4385,6 +4431,7 @@ async function showMainMenu() {
4385
4431
  item("5", i18n.t("menu:options.configStyle"), isZh ? "\u9009\u62E9\u8F93\u51FA\u4EBA\u683C" : "Choose output personality"),
4386
4432
  item("6", i18n.t("menu:options.configModel"), isZh ? "\u524D\u7AEF/\u540E\u7AEF\u6A21\u578B\u5207\u6362" : "Switch frontend/backend models"),
4387
4433
  groupSep(isZh ? "\u5176\u4ED6\u5DE5\u5177" : "Tools"),
4434
+ item("X", isZh ? "Codex \u6A21\u5F0F" : "Codex Mode", isZh ? "\u5B89\u88C5 Codex \u4E3B\u5BFC\u7684\u591A\u6A21\u578B\u7F16\u6392" : "Install Codex-led multi-model orchestration"),
4388
4435
  item("T", i18n.t("menu:options.tools"), "ccusage, CCometixLine"),
4389
4436
  item("C", i18n.t("menu:options.installClaude"), isZh ? "\u5B89\u88C5/\u91CD\u88C5 CLI" : "Install/reinstall CLI"),
4390
4437
  groupSep("CCG"),
@@ -4413,6 +4460,9 @@ async function showMainMenu() {
4413
4460
  case "6":
4414
4461
  await configModelRouting();
4415
4462
  break;
4463
+ case "X":
4464
+ await handleCodexMode();
4465
+ break;
4416
4466
  case "T":
4417
4467
  await handleTools();
4418
4468
  break;
@@ -4756,6 +4806,43 @@ async function configOutputStyle() {
4756
4806
  console.log(ansis.green(` \u2713 ${i18n.t("menu:style.set", { style })}`));
4757
4807
  console.log(ansis.gray(` ${i18n.t("common:restartToApply")}`));
4758
4808
  }
4809
+ async function handleCodexMode() {
4810
+ const isZh = i18n.language === "zh-CN";
4811
+ console.log();
4812
+ console.log(ansis.cyan.bold(isZh ? " Codex \u591A\u6A21\u578B\u7F16\u6392\u6A21\u5F0F" : " Codex Multi-Model Orchestration Mode"));
4813
+ console.log();
4814
+ console.log(
4815
+ isZh ? " \u5B89\u88C5 CCG Codex \u6A21\u5F0F\u5230 ~/.codex/\uFF0C\u8BA9 Codex CLI \u4F5C\u4E3A\u4E3B\u5BFC\u8005\u7F16\u6392 Gemini + Claude\u3002" : " Install CCG Codex mode to ~/.codex/, enabling Codex CLI as lead orchestrator for Gemini + Claude."
4816
+ );
4817
+ console.log();
4818
+ console.log(isZh ? " \u5C06\u5B89\u88C5:" : " Will install:");
4819
+ console.log(" ~/.codex/AGENTS.md \u2014 Codex auto-read instructions");
4820
+ console.log(" ~/.codex/config.toml \u2014 multi-agent + timeout config");
4821
+ console.log(" ~/.codex/agents/ccg-implement.toml");
4822
+ console.log(" ~/.codex/agents/ccg-review.toml");
4823
+ console.log(" ~/.codex/agents/ccg-research.toml");
4824
+ console.log();
4825
+ const { confirm } = await inquirer.prompt([{
4826
+ type: "confirm",
4827
+ name: "confirm",
4828
+ message: isZh ? "\u786E\u8BA4\u5B89\u88C5\uFF1F" : "Confirm install?",
4829
+ default: true
4830
+ }]);
4831
+ if (!confirm) return;
4832
+ const spinner = ora(isZh ? "\u5B89\u88C5 Codex \u6A21\u5F0F..." : "Installing Codex mode...").start();
4833
+ const result = await installCodexMode();
4834
+ if (result.success) {
4835
+ spinner.succeed(isZh ? "Codex \u6A21\u5F0F\u5B89\u88C5\u5B8C\u6210" : "Codex mode installed");
4836
+ console.log();
4837
+ console.log(ansis.green(result.message));
4838
+ console.log();
4839
+ console.log(ansis.yellow(
4840
+ isZh ? " \u4F7F\u7528\u65B9\u6CD5: \u5728\u9879\u76EE\u76EE\u5F55\u8FD0\u884C codex\uFF0CAGENTS.md \u4F1A\u81EA\u52A8\u751F\u6548" : " Usage: run codex in your project directory, AGENTS.md takes effect automatically"
4841
+ ));
4842
+ } else {
4843
+ spinner.fail(result.message);
4844
+ }
4845
+ }
4759
4846
  async function handleInstallClaude() {
4760
4847
  console.log();
4761
4848
  console.log(ansis.cyan.bold(` ${i18n.t("menu:claude.title")}`));
@@ -5010,4 +5097,4 @@ async function uninstallCCometixLine() {
5010
5097
  }
5011
5098
  }
5012
5099
 
5013
- export { isWindows as A, readClaudeCodeConfig as B, fixWindowsMcpConfig as C, writeClaudeCodeConfig as D, configMcp as E, version as F, i18n as a, initI18n as b, changeLanguage as c, createDefaultConfig as d, createDefaultRouting as e, getConfigPath as f, getCcgDir as g, getWorkflowConfigs as h, init as i, getWorkflowById as j, installWorkflows as k, installAceTool as l, installAceToolRs as m, uninstallWorkflows as n, uninstallAceTool as o, migrateToV1_4_0 as p, needsMigration as q, readCcgConfig as r, showMainMenu as s, getCurrentVersion as t, update as u, getLatestVersion as v, writeCcgConfig as w, checkForUpdates as x, compareVersions as y, diagnoseMcpConfig as z };
5100
+ export { diagnoseMcpConfig as A, isWindows as B, readClaudeCodeConfig as C, fixWindowsMcpConfig as D, writeClaudeCodeConfig as E, configMcp as F, version as G, i18n as a, initI18n as b, changeLanguage as c, createDefaultConfig as d, createDefaultRouting as e, getConfigPath as f, getCcgDir as g, getWorkflowConfigs as h, init as i, getWorkflowById as j, installWorkflows as k, installAceTool as l, installAceToolRs as m, installCodexMode as n, uninstallWorkflows as o, uninstallAceTool as p, migrateToV1_4_0 as q, readCcgConfig as r, showMainMenu as s, needsMigration as t, update as u, getCurrentVersion as v, writeCcgConfig as w, getLatestVersion as x, checkForUpdates as y, compareVersions as z };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ccg-workflow",
3
- "version": "3.0.3",
3
+ "version": "3.0.5",
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",
@@ -32,6 +32,7 @@
32
32
  "templates/engine/",
33
33
  "templates/hooks/",
34
34
  "templates/spec/",
35
+ "templates/codex/",
35
36
  "templates/prompts/codex/",
36
37
  "templates/prompts/gemini/analyzer.md",
37
38
  "templates/prompts/gemini/architect.md",
@@ -0,0 +1,253 @@
1
+ <!-- CCG:START — Managed by CCG Workflow. Do not edit this block manually. -->
2
+ # CCG Multi-Model Orchestration (Codex-Led)
3
+
4
+ You are the **lead orchestrator** of a multi-model development team. You think, you code, and you know when to call for backup.
5
+
6
+ ## 1. Decision Framework — 怎么思考
7
+
8
+ 收到任何任务时,先用 5 秒评估,不要立即动手:
9
+
10
+ ### 评估三维度
11
+
12
+ **复杂度**:
13
+ - **S** — 单文件,改几行,范围清晰 → 直接做
14
+ - **M** — 2-5 文件,单模块 → 分析后再做
15
+ - **L+** — 5+ 文件,跨模块,架构级 → 必须多模型分析 + 规划后再做
16
+
17
+ **风险**:
18
+ - **低** — 无生产影响,可逆 → 跳过审查也可以
19
+ - **中** — 修改现有行为 → 完成后必须审查
20
+ - **高** — auth/数据库/API 契约/加密 → 无论大小都必须审查
21
+
22
+ ### 决策矩阵
23
+
24
+ ```
25
+ S + 低风险 → 直接写,跑测试,完事
26
+ S + 高风险 → 直接写,但必须调双模型审查(Gemini + Claude)
27
+ M + 任意 → 双模型并行分析(Gemini + Claude 都调),再写,完成后双模型审查
28
+ L+ + 任意 → 双模型并行分析,制定 plan.md,spawn 子 Agent 并行写,双模型审查
29
+ ```
30
+
31
+ **⛔ M 以上复杂度,分析和审查都必须是双模型(Gemini + Claude 都调)。**
32
+ 这是 CCG 的核心价值——两个模型从不同角度分析同一个问题,交叉验证,弥补单模型盲区。只调一个模型 = 浪费了多模型协作的意义。
33
+
34
+ **不确定时,选高一级。** 宁可多做一步分析,不可写完才发现方向错了。
35
+
36
+ ## 2. Task System — 任务持久化
37
+
38
+ ### 何时创建 Task
39
+
40
+ **所有任务都必须创建 Task。** 即使是 S 复杂度的小改动。
41
+
42
+ ### 创建步骤
43
+
44
+ ```bash
45
+ # 1. 生成任务名(用户需求 → kebab-case)
46
+ TASK_NAME="add-jwt-auth" # 示例
47
+
48
+ # 2. 创建目录
49
+ mkdir -p .ccg/tasks/$TASK_NAME
50
+
51
+ # 3. 写 task.json
52
+ cat > .ccg/tasks/$TASK_NAME/task.json << 'TASKJSON'
53
+ {
54
+ "id": "add-jwt-auth",
55
+ "title": "用户请求摘要",
56
+ "status": "in_progress",
57
+ "complexity": "M",
58
+ "risk": "medium",
59
+ "domain": "backend",
60
+ "currentPhase": "analysis",
61
+ "nextAction": "分析需求",
62
+ "createdAt": "2026-05-17T10:00:00Z",
63
+ "branch": "main"
64
+ }
65
+ TASKJSON
66
+ ```
67
+
68
+ ### 阶段推进
69
+
70
+ 每完成一个阶段,更新 task.json 中的 `currentPhase` 和 `nextAction`:
71
+ - `"analysis"` → 分析中
72
+ - `"planning"` → 规划中(L+ 复杂度才有)
73
+ - `"implementation"` → 实施中
74
+ - `"review"` → 审查中
75
+ - `"completed"` → 已完成,待归档
76
+
77
+ ### 持久化文件
78
+
79
+ 按需创建:
80
+ - `requirements.md` — 增强后的需求描述(M+ 复杂度)
81
+ - `plan.md` — 实施计划(L+ 复杂度)
82
+ - `review.md` — 审查结果
83
+ - `context.jsonl` — 相关文件引用(一行一个 JSON)
84
+
85
+ ### ⛔ 归档(每个任务完成后必须执行)
86
+
87
+ ```bash
88
+ # 移动到归档目录
89
+ mkdir -p .ccg/tasks/archive/$(date +%Y-%m)
90
+ mv .ccg/tasks/$TASK_NAME .ccg/tasks/archive/$(date +%Y-%m)/
91
+
92
+ # 提交归档
93
+ git add .ccg/tasks/
94
+ git commit -m "chore: archive ccg task $TASK_NAME"
95
+ ```
96
+
97
+ **绝不可以跳过归档。** 任务完成后必须归档,不管大小。
98
+
99
+ ## 3. Spec System — 编码规范
100
+
101
+ ### 读取时机
102
+
103
+ **写代码前必须检查**:
104
+ ```bash
105
+ ls .ccg/spec/ 2>/dev/null
106
+ ```
107
+
108
+ 如果存在:
109
+ - `.ccg/spec/backend/index.md` — 后端约定
110
+ - `.ccg/spec/frontend/index.md` — 前端约定
111
+ - `.ccg/spec/guides/index.md` — 通用指南
112
+
113
+ **读了就要遵守。** Spec 是项目的编码法律。
114
+
115
+ ### Spec Evolution — 任务完成时回馈
116
+
117
+ 归档前,检查本次开发是否有值得沉淀的经验:
118
+ - 踩过的坑(非显而易见的)
119
+ - 发现的代码模式
120
+ - 新引入的库/API 的使用约定
121
+
122
+ 如果有 → 追加到对应的 `.ccg/spec/{domain}/index.md`。
123
+ 如果没有 → 跳过,不要强行凑。
124
+
125
+ ## 4. Calling External Models — 调用模板
126
+
127
+ ### ⛔ 默认调用方式:双模型并行(M+ 复杂度必须用这个)
128
+
129
+ ```bash
130
+ ~/.claude/bin/codeagent-wrapper --progress --backend gemini - "$(pwd)" <<'GEMINI_EOF'
131
+ ROLE_FILE: ~/.claude/.ccg/prompts/gemini/$ROLE.md
132
+ <TASK>
133
+ {任务描述 + 上下文}
134
+ </TASK>
135
+ OUTPUT: {期望输出格式}
136
+ GEMINI_EOF
137
+ &
138
+ ~/.claude/bin/codeagent-wrapper --progress --backend claude - "$(pwd)" <<'CLAUDE_EOF'
139
+ ROLE_FILE: ~/.claude/.ccg/prompts/claude/$ROLE.md
140
+ <TASK>
141
+ {任务描述 + 上下文}
142
+ </TASK>
143
+ OUTPUT: {期望输出格式}
144
+ CLAUDE_EOF
145
+ &
146
+ wait
147
+ ```
148
+
149
+ **M+ 复杂度时,分析和审查都用上面这个双模型并行模板。不要只调一个。**
150
+
151
+ ### 单模型调用(仅 S 复杂度可用)
152
+
153
+ #### Gemini(前端/UI 分析)
154
+ ```bash
155
+ ~/.claude/bin/codeagent-wrapper --progress --backend gemini - "$(pwd)" <<'EOF'
156
+ ROLE_FILE: ~/.claude/.ccg/prompts/gemini/$ROLE.md
157
+ <TASK>
158
+ {任务描述 + 上下文}
159
+ </TASK>
160
+ OUTPUT: {期望输出格式}
161
+ EOF
162
+ ```
163
+
164
+ #### Claude(架构/安全/复杂推理)
165
+ ```bash
166
+ ~/.claude/bin/codeagent-wrapper --progress --backend claude - "$(pwd)" <<'EOF'
167
+ ROLE_FILE: ~/.claude/.ccg/prompts/claude/$ROLE.md
168
+ <TASK>
169
+ {任务描述 + 上下文}
170
+ </TASK>
171
+ OUTPUT: {期望输出格式}
172
+ EOF
173
+ ```
174
+
175
+ ### 可用角色($ROLE)
176
+ `analyzer` / `architect` / `reviewer` / `debugger` / `tester` / `optimizer` / `builder`
177
+
178
+ ### 并行调用提醒
179
+ M+ 复杂度的分析和审查,使用上方的"双模型并行"模板。不要分开调用,用 `&` + `wait` 并行执行。
180
+
181
+ ## 5. Implementation — 你自己写代码
182
+
183
+ ### 执行模式:Inline(你自己按 plan 顺序逐文件写)
184
+
185
+ **不要 spawn 子代理。** 你自己按 plan.md 的步骤顺序逐个文件写代码。这比子代理更稳定、更快、更可控。
186
+
187
+ ### 执行流程
188
+
189
+ ```
190
+ 1. 读 plan.md(如有)或回顾分析阶段的结论
191
+ 2. 按依赖顺序逐文件写:先写底层(store/model/util),再写上层(route/middleware)
192
+ 3. 每写完一个文件,跑一次测试/类型检查,确保不破坏现有功能
193
+ 4. 全部写完后,跑完整测试套件
194
+ 5. git diff 确认所有变更在 plan 范围内
195
+ ```
196
+
197
+ ### 写代码原则
198
+
199
+ - **先读再写** — 修改文件前先读取完整内容,理解现有模式
200
+ - **遵守 Spec** — .ccg/spec/ 里的约定是法律
201
+ - **一个文件一个 commit 思路** — 每个文件的变更应该是自包含的
202
+ - **不扩大范围** — plan 没说改的文件不要动
203
+ - **测试驱动** — 新功能先写测试骨架,再写实现
204
+
205
+ ## 6. Quality — 交付前检查
206
+
207
+ ### 必须通过
208
+ - [ ] 测试通过(`npm test` / `pnpm test` / `go test` / `pytest`)
209
+ - [ ] 类型检查通过(如适用)
210
+ - [ ] 变更在请求范围内
211
+ - [ ] 无硬编码密钥
212
+ - [ ] git diff 只有预期变更
213
+
214
+ ### 何时调外部模型审查
215
+ - 变更 >30 行 → **必须**调双模型审查(Gemini + Claude 都调)
216
+ - 变更 ≤30 行但涉及 auth/数据库/加密 → **必须**调双模型审查
217
+ - 变更 ≤30 行且低风险 → 可以只调一个
218
+
219
+ ### ⛔ 审查流程(双模型交叉验证)
220
+
221
+ ```bash
222
+ # 必须并行调用两个模型审查 git diff
223
+ ~/.claude/bin/codeagent-wrapper --progress --backend gemini - "$(pwd)" <<'EOF'
224
+ ROLE_FILE: ~/.claude/.ccg/prompts/gemini/reviewer.md
225
+ <TASK>审查以下代码变更:$(git diff)</TASK>
226
+ OUTPUT: Critical/Warning/Info 分级审查报告
227
+ EOF
228
+ &
229
+ ~/.claude/bin/codeagent-wrapper --progress --backend claude - "$(pwd)" <<'EOF'
230
+ ROLE_FILE: ~/.claude/.ccg/prompts/claude/reviewer.md
231
+ <TASK>审查以下代码变更:$(git diff)</TASK>
232
+ OUTPUT: Critical/Warning/Info 分级审查报告
233
+ EOF
234
+ &
235
+ wait
236
+ ```
237
+
238
+ 1. **两个模型都要调** — 这是多模型协作的核心,不是二选一
239
+ 2. 综合双方意见,合并去重,分 Critical / Warning / Info
240
+ 3. Critical → 修复后重新双模型审查
241
+ 4. Warning → 建议修复
242
+ 5. 审查结果写入 `.ccg/tasks/$TASK_NAME/review.md`
243
+
244
+ ## 7. Iron Rules — 铁律
245
+
246
+ 1. **评估先于行动** — 5 秒评估复杂度/风险/领域,再决定力度
247
+ 2. **所有任务创建 Task** — 写 task.json,完成后归档,无例外
248
+ 3. **Spec 是法律** — 存在就遵守,完成就回馈
249
+ 4. **不确定就升级** — 不确定复杂度时选高一级,不确定风险时调审查
250
+ 5. **scope 是边界** — 只做用户要求的,不自作主张扩大范围
251
+ 6. **测试是底线** — 不跑测试不报告完成
252
+ 7. **归档是闭环** — 每个任务必须归档,让下次会话知道发生过什么
253
+ <!-- CCG:END -->
@@ -0,0 +1,26 @@
1
+ # CCG Implementation Sub-Agent
2
+ # Spawned by the lead Codex agent for parallel file implementation
3
+
4
+ name = "ccg-implement"
5
+ description = "Implementation worker — writes code for assigned files following the plan"
6
+
7
+ [sandbox]
8
+ mode = "workspace-write"
9
+
10
+ [features]
11
+ multi_agent = false # Prevent recursion — workers don't spawn workers
12
+
13
+ [developer_instructions]
14
+ text = """
15
+ You are a CCG implementation worker. You have been dispatched by the lead agent.
16
+
17
+ ## Rules
18
+ 1. You ONLY modify files assigned to you in the dispatch message
19
+ 2. Read .ccg/spec/ conventions before writing (if exists)
20
+ 3. Follow the plan exactly — no scope expansion
21
+ 4. Run validation commands after changes if specified
22
+ 5. Report: files changed, tests status, any blockers
23
+
24
+ ## You are NOT the lead agent
25
+ Do NOT spawn subagents. Do NOT call codeagent-wrapper. Just write the code assigned to you.
26
+ """
@@ -0,0 +1,31 @@
1
+ # CCG Research Sub-Agent
2
+ # Spawned by the lead Codex agent for codebase exploration
3
+
4
+ name = "ccg-research"
5
+ description = "Research worker — explores codebase, maps dependencies, gathers context"
6
+
7
+ [sandbox]
8
+ mode = "read-only" # Research never writes
9
+
10
+ [features]
11
+ multi_agent = false
12
+
13
+ [developer_instructions]
14
+ text = """
15
+ You are a CCG research worker. You have been dispatched to gather information.
16
+
17
+ ## Steps
18
+ 1. Search the codebase for files/patterns specified in the dispatch message
19
+ 2. Map dependencies and call chains
20
+ 3. Read relevant spec files (.ccg/spec/) for conventions
21
+ 4. Summarize findings in a structured report
22
+
23
+ ## Output Format
24
+ FILES_FOUND: [list of relevant files]
25
+ DEPENDENCIES: [dependency map]
26
+ PATTERNS: [existing code patterns to follow]
27
+ RISKS: [potential conflicts or breaking changes]
28
+
29
+ ## You are NOT the lead agent
30
+ Do NOT spawn subagents. Do NOT modify any files. Read only.
31
+ """
@@ -0,0 +1,33 @@
1
+ # CCG Review Sub-Agent
2
+ # Spawned by the lead Codex agent for code quality checking
3
+
4
+ name = "ccg-review"
5
+ description = "Review worker — runs lint, typecheck, tests and reports findings"
6
+
7
+ [sandbox]
8
+ mode = "workspace-write" # Needs write to auto-fix lint issues
9
+
10
+ [features]
11
+ multi_agent = false
12
+
13
+ [developer_instructions]
14
+ text = """
15
+ You are a CCG review worker. You have been dispatched to verify code quality.
16
+
17
+ ## Steps
18
+ 1. Run lint/typecheck for the project (detect from package.json / go.mod / pyproject.toml)
19
+ 2. Run tests
20
+ 3. Review git diff for: security issues, logic errors, scope violations
21
+ 4. Auto-fix trivial lint issues (max 3 attempts)
22
+ 5. Report findings as: Critical / Warning / Info
23
+
24
+ ## Output Format
25
+ REVIEW_RESULT: [PASS|FAIL]
26
+ Critical: [count]
27
+ Warning: [count]
28
+ Info: [count]
29
+ Details: [list of findings with file:line]
30
+
31
+ ## You are NOT the lead agent
32
+ Do NOT spawn subagents. Do NOT call codeagent-wrapper.
33
+ """
@@ -0,0 +1,9 @@
1
+ # CCG Codex Project Configuration
2
+ # Installed by: npx ccg-workflow
3
+
4
+ project_doc_fallback_filenames = ["AGENTS.md", "CLAUDE.md"]
5
+
6
+ [features.multi_agent_v2]
7
+ enabled = true
8
+ max_concurrent_threads_per_session = 6
9
+ min_wait_timeout_ms = 480000 # 8 min — external model calls need time
@@ -0,0 +1,217 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ CCG Workflow Hook for Codex CLI — Adaptive Guardrail
4
+ Injects per-turn guidance based on what Codex has/hasn't done.
5
+ Not a rigid state machine — adapts to task complexity and progress.
6
+
7
+ Hook type: UserPromptSubmit
8
+ """
9
+
10
+ import json
11
+ import os
12
+ import sys
13
+ import glob
14
+ import subprocess
15
+ from pathlib import Path
16
+ from datetime import datetime
17
+
18
+
19
+ def find_project_root():
20
+ """Walk up to find .ccg/ or .git/"""
21
+ d = os.environ.get("CODEX_PROJECT_DIR", os.getcwd())
22
+ for _ in range(20):
23
+ if os.path.isdir(os.path.join(d, ".ccg")) or os.path.isdir(os.path.join(d, ".git")):
24
+ return d
25
+ parent = os.path.dirname(d)
26
+ if parent == d:
27
+ break
28
+ d = parent
29
+ return None
30
+
31
+
32
+ def get_active_task(root):
33
+ """Find the most recent in_progress task."""
34
+ tasks_dir = os.path.join(root, ".ccg", "tasks")
35
+ if not os.path.isdir(tasks_dir):
36
+ return None
37
+ for name in sorted(os.listdir(tasks_dir), reverse=True):
38
+ if name == "archive":
39
+ continue
40
+ task_file = os.path.join(tasks_dir, name, "task.json")
41
+ if not os.path.isfile(task_file):
42
+ continue
43
+ try:
44
+ with open(task_file) as f:
45
+ task = json.load(f)
46
+ if task.get("status") not in ("completed", "archived"):
47
+ task["_dir"] = os.path.join(tasks_dir, name)
48
+ task["_name"] = name
49
+ return task
50
+ except Exception:
51
+ continue
52
+ return None
53
+
54
+
55
+ def detect_progress(root):
56
+ """Detect what Codex has done so far in this session."""
57
+ signals = {
58
+ "has_dirty_files": False,
59
+ "dirty_count": 0,
60
+ "changed_lines": 0,
61
+ "has_test_output": False,
62
+ "high_risk_files": False,
63
+ }
64
+ try:
65
+ status = subprocess.run(
66
+ ["git", "status", "--porcelain"],
67
+ cwd=root, capture_output=True, text=True, timeout=5
68
+ )
69
+ lines = [l for l in status.stdout.strip().split("\n") if l.strip()]
70
+ signals["dirty_count"] = len(lines)
71
+ signals["has_dirty_files"] = len(lines) > 0
72
+
73
+ risk_patterns = ["auth", "login", "password", "token", "secret", "crypto",
74
+ "encrypt", "migration", "schema", "permission", "admin"]
75
+ for line in lines:
76
+ fname = line[3:].strip().lower()
77
+ if any(p in fname for p in risk_patterns):
78
+ signals["high_risk_files"] = True
79
+ break
80
+
81
+ if signals["has_dirty_files"]:
82
+ diff = subprocess.run(
83
+ ["git", "diff", "--stat"],
84
+ cwd=root, capture_output=True, text=True, timeout=5
85
+ )
86
+ for dline in diff.stdout.strip().split("\n"):
87
+ if "insertion" in dline or "deletion" in dline:
88
+ parts = dline.split(",")
89
+ for p in parts:
90
+ p = p.strip()
91
+ if "insertion" in p:
92
+ signals["changed_lines"] += int(p.split()[0])
93
+ elif "deletion" in p:
94
+ signals["changed_lines"] += int(p.split()[0])
95
+ except Exception:
96
+ pass
97
+ return signals
98
+
99
+
100
+ def assess_complexity(task):
101
+ """Get complexity from task.json or default to M."""
102
+ if not task:
103
+ return "M"
104
+ return task.get("complexity", "M")
105
+
106
+
107
+ def build_guidance(task, progress, root):
108
+ """Build adaptive guidance based on task state + progress."""
109
+ parts = []
110
+ complexity = assess_complexity(task)
111
+ phase = task.get("currentPhase", "unknown") if task else "no_task"
112
+
113
+ # --- Task state breadcrumb ---
114
+ if task:
115
+ parts.append(f"Task: {task.get('title', task.get('id', '?'))} ({task.get('status', '?')})")
116
+ parts.append(f"Complexity: {complexity} | Risk: {task.get('risk', '?')} | Phase: {phase}")
117
+ if task.get("nextAction"):
118
+ parts.append(f"Next: {task['nextAction']}")
119
+ else:
120
+ parts.append("No active task. Create one in .ccg/tasks/ before starting work.")
121
+ parts.append("Even small fixes need a task.json for tracking.")
122
+ return parts
123
+
124
+ # --- Adaptive guidance based on phase × progress ---
125
+
126
+ # Phase: analysis — haven't started coding yet
127
+ if phase == "analysis":
128
+ if complexity in ("M", "L", "XL"):
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.")
132
+
133
+ # Phase: implementation — coding in progress
134
+ elif phase == "implementation":
135
+ if progress["dirty_count"] == 0:
136
+ parts.append("")
137
+ parts.append("Implementation phase started but no files changed yet. Start coding.")
138
+
139
+ # Phase: review — code is written, need review
140
+ elif phase == "review":
141
+ parts.append("")
142
+ parts.append("Review phase. Call external models for review, write results to review.md.")
143
+
144
+ # --- Cross-phase guardrails ---
145
+
146
+ # Big changes without review
147
+ if progress["changed_lines"] > 30 and phase != "review":
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.")
150
+
151
+ # Review phase: enforce dual model
152
+ if phase == "review":
153
+ parts.append("")
154
+ parts.append("⛔ Review phase: call BOTH Gemini (--backend gemini) AND Claude (--backend claude) with reviewer role. Two models, not one.")
155
+
156
+ # High-risk files detected
157
+ if progress["high_risk_files"] and phase not in ("review", "completed"):
158
+ parts.append("")
159
+ parts.append("⚠️ High-risk files detected (auth/db/crypto). External model security review is REQUIRED before delivery.")
160
+
161
+ # Has dirty files but hasn't run tests
162
+ if progress["has_dirty_files"] and not progress["has_test_output"]:
163
+ if phase == "implementation" and progress["changed_lines"] > 10:
164
+ parts.append("")
165
+ parts.append("Reminder: run tests after significant changes. Don't wait until the end.")
166
+
167
+ # --- Spec reminder ---
168
+ spec_dir = os.path.join(root, ".ccg", "spec")
169
+ if os.path.isdir(spec_dir) and phase in ("analysis", "implementation"):
170
+ specs = []
171
+ for sub in ("backend", "frontend", "guides"):
172
+ idx = os.path.join(spec_dir, sub, "index.md")
173
+ if os.path.isfile(idx):
174
+ specs.append(f".ccg/spec/{sub}/index.md")
175
+ if specs:
176
+ parts.append("")
177
+ parts.append(f"Spec files available: {', '.join(specs)} — read before writing code.")
178
+
179
+ # --- Archive reminder ---
180
+ if phase == "completed" or (task.get("status") == "completed"):
181
+ parts.append("")
182
+ parts.append("⛔ Task completed. You MUST archive it now:")
183
+ parts.append(f" mkdir -p .ccg/tasks/archive/$(date +%Y-%m) && mv .ccg/tasks/{task['_name']} .ccg/tasks/archive/$(date +%Y-%m)/")
184
+ parts.append(" git add .ccg/tasks/ && git commit -m \"chore: archive ccg task\"")
185
+
186
+ return parts
187
+
188
+
189
+ def main():
190
+ try:
191
+ root = find_project_root()
192
+ if not root:
193
+ return
194
+ if not os.path.isdir(os.path.join(root, ".ccg")):
195
+ return
196
+
197
+ task = get_active_task(root)
198
+ progress = detect_progress(root)
199
+ lines = build_guidance(task, progress, root)
200
+
201
+ if not lines:
202
+ return
203
+
204
+ context = "<ccg-state>\n" + "\n".join(lines) + "\n</ccg-state>"
205
+
206
+ print(json.dumps({
207
+ "hookSpecificOutput": {
208
+ "hookEventName": "UserPromptSubmit",
209
+ "additionalContext": context
210
+ }
211
+ }))
212
+ except Exception:
213
+ pass
214
+
215
+
216
+ if __name__ == "__main__":
217
+ main()
@@ -0,0 +1,7 @@
1
+ [
2
+ {
3
+ "event": "user_prompt_submit",
4
+ "script": "hooks/ccg-workflow.py",
5
+ "timeout_ms": 10000
6
+ }
7
+ ]
@@ -71,18 +71,17 @@ Gate: 实施已完成 ✓
71
71
 
72
72
  **Gate check**: 需求已增强 ✓ 上下文已收集 ✓
73
73
 
74
- **M 复杂度必须调用外部模型进行分析。** 不可跳过。
74
+ **⛔ M 复杂度必须调用双模型(Gemini + Codex)并行分析。不可只调一个,不可跳过。**
75
+
76
+ 这是多模型协作的核心价值——两个模型从不同角度分析同一个问题,交叉验证,弥补单模型盲区。
75
77
 
76
78
  执行步骤:
77
79
 
78
80
  1. 确定工作目录:`WORKDIR=$(pwd)`
79
- 2. 根据领域选择模型:
80
- - 后端任务 → backend 模型(codex)+ analyzer 角色
81
- - 前端任务 → frontend 模型(gemini)+ analyzer 角色
82
- - 全栈任务 → 双模型并行
83
81
 
84
- 3. **调用 codeagent-wrapper**(必须实际执行,不是读文件):
82
+ 2. **并行调用双模型**(`run_in_background: true`,两个同时启动):
85
83
 
84
+ Backend 模型:
86
85
  ```
87
86
  Bash({
88
87
  command: "~/.claude/bin/codeagent-wrapper {{LITE_MODE_FLAG}}--progress --backend codex {{GEMINI_MODEL_FLAG}}- \"$WORKDIR\" <<'CODEAGENT_EOF'\nROLE_FILE: ~/.claude/.ccg/prompts/codex/analyzer.md\n<TASK>\n需求:{增强后的需求}\n上下文:{Phase 2 收集的项目上下文、相关代码摘要}\n</TASK>\nOUTPUT: 技术分析报告(可行性、架构建议、风险评估、实施方案对比)\nCODEAGENT_EOF",
@@ -92,10 +91,10 @@ Bash({
92
91
  })
93
92
  ```
94
93
 
95
- 如果是全栈任务,同时启动 frontend 模型:
94
+ Frontend 模型(**必须同时启动,不是"如果是全栈才调"**):
96
95
  ```
97
96
  Bash({
98
- command: "~/.claude/bin/codeagent-wrapper {{LITE_MODE_FLAG}}--progress --backend gemini {{GEMINI_MODEL_FLAG}}- \"$WORKDIR\" <<'CODEAGENT_EOF'\nROLE_FILE: ~/.claude/.ccg/prompts/gemini/analyzer.md\n<TASK>\n需求:{增强后的需求}\n上下文:{Phase 2 收集的项目上下文}\n</TASK>\nOUTPUT: 前端/UX 视角分析报告\nCODEAGENT_EOF",
97
+ command: "~/.claude/bin/codeagent-wrapper {{LITE_MODE_FLAG}}--progress --backend gemini {{GEMINI_MODEL_FLAG}}- \"$WORKDIR\" <<'CODEAGENT_EOF'\nROLE_FILE: ~/.claude/.ccg/prompts/gemini/analyzer.md\n<TASK>\n需求:{增强后的需求}\n上下文:{Phase 2 收集的项目上下文}\n</TASK>\nOUTPUT: 从不同视角的分析报告(可行性、设计建议、风险评估)\nCODEAGENT_EOF",
99
98
  run_in_background: true,
100
99
  timeout: 3600000,
101
100
  description: "Frontend 模型分析"