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 +2 -1
- package/README.zh-CN.md +2 -1
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.mjs +1 -1
- package/dist/shared/{ccg-workflow.DxKAcBrr.mjs → ccg-workflow.B4dDUxv8.mjs} +89 -2
- package/package.json +2 -1
- package/templates/codex/AGENTS.md +253 -0
- package/templates/codex/agents/ccg-implement.toml +26 -0
- package/templates/codex/agents/ccg-research.toml +31 -0
- package/templates/codex/agents/ccg-review.toml +33 -0
- package/templates/codex/config.toml +9 -0
- package/templates/codex/hooks/ccg-workflow.py +217 -0
- package/templates/codex/hooks.json +7 -0
- package/templates/engine/strategies/guided-develop.md +7 -8
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.
|
|
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.
|
|
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 {
|
|
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,
|
|
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.
|
|
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 {
|
|
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
|
+
"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()
|
|
@@ -71,18 +71,17 @@ Gate: 实施已完成 ✓
|
|
|
71
71
|
|
|
72
72
|
**Gate check**: 需求已增强 ✓ 上下文已收集 ✓
|
|
73
73
|
|
|
74
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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 模型分析"
|