ccgx-workflow 2.2.0 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +1 -1
- package/dist/index.mjs +2 -2
- package/dist/shared/{ccgx-workflow.k6gRMX3r.mjs → ccgx-workflow.DDYfdCuM.mjs} +9 -1
- package/package.json +1 -1
- package/templates/commands/analyze.md +1 -1
- package/templates/commands/codex-exec.md +114 -68
- package/templates/commands/debate.md +3 -4
- package/templates/commands/execute.md +1 -3
- package/templates/commands/optimize.md +1 -1
- package/templates/commands/plan.md +1 -3
- package/templates/commands/review.md +1 -1
- package/templates/commands/spec-impl.md +114 -23
- package/templates/commands/spec-plan.md +53 -15
- package/templates/commands/spec-research.md +62 -15
- package/templates/commands/spec-review.md +73 -37
- package/templates/commands/team.md +117 -32
- package/templates/commands/test.md +1 -1
- package/templates/commands/workflow.md +56 -21
- package/templates/scripts/check-plugins.cjs +49 -0
|
@@ -39,41 +39,74 @@ subagent_freshness: required
|
|
|
39
39
|
- 如果用户通过 `/add-dir` 添加了多个工作区,先用 Glob/Grep 确定任务相关的工作区
|
|
40
40
|
- 如果无法确定,用 `AskUserQuestion` 询问用户选择目标工作区
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
**调用通道路由(CCG codeagent 退役,v2.2.0+)**
|
|
43
|
+
|
|
44
|
+
1. **优先 plugin spawn**(默认):plugin 已装 → `Agent(subagent_type="<codex:codex-rescue|gemini:gemini-rescue>")`。session 复用通过 prompt 内 `--resume` flag 表达(subagent 映射为 codex/gemini `--resume-last`,**注意是 last,不是 by-id**)。
|
|
45
|
+
2. **降级 codeagent-wrapper**(BC fallback):plugin 未装 → Bash 调用,保留 `resume <SESSION_ID>` 显式会话管理。
|
|
46
|
+
|
|
47
|
+
**判定**:preflight `Bash` 跑 `node ~/.claude/.ccg/scripts/check-plugins.cjs`(解析 Claude Code 权威 `installed_plugins.json`)。exit `0` + stdout `{"codex":"<ver>","gemini":"<ver>"}` → 通道 A(plugin 默认);非 `0` → 通道 B(wrapper BC fallback)。
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
**通道 A — plugin spawn(默认)**:
|
|
52
|
+
|
|
53
|
+
**预备动作**:spawn 前主线先 Read 对应阶段的角色提示词(见下方表),把内容拼入 `<role>` 块。
|
|
43
54
|
|
|
44
55
|
```
|
|
45
56
|
# 新会话调用
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
57
|
+
Agent({
|
|
58
|
+
subagent_type: "<codex:codex-rescue|gemini:gemini-rescue>",
|
|
59
|
+
description: "简短描述",
|
|
60
|
+
prompt: `<role>
|
|
61
|
+
${roleContent} // 主线 Read 后的角色提示词内容
|
|
62
|
+
</role>
|
|
63
|
+
|
|
64
|
+
<workdir>{{WORKDIR}}</workdir>
|
|
65
|
+
|
|
66
|
+
<task>
|
|
50
67
|
需求:<增强后的需求(如未增强则用 $ARGUMENTS)>
|
|
51
68
|
上下文:<前序阶段收集的项目上下文、分析结果等>
|
|
52
|
-
</
|
|
53
|
-
|
|
54
|
-
|
|
69
|
+
</task>
|
|
70
|
+
|
|
71
|
+
<structured_output_contract>
|
|
72
|
+
<期望输出格式 / JSON schema>
|
|
73
|
+
Return ≤200 token structured summary.
|
|
74
|
+
</structured_output_contract>`
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
# 复用会话(同一 Claude session 内的连续阶段)
|
|
78
|
+
Agent({
|
|
79
|
+
subagent_type: "<codex:codex-rescue|gemini:gemini-rescue>",
|
|
80
|
+
description: "简短描述",
|
|
81
|
+
prompt: `--resume
|
|
82
|
+
|
|
83
|
+
<task>
|
|
84
|
+
<delta 指令(仅本阶段变化,不重述前序上下文,由 codex/gemini thread 自带历史)>
|
|
85
|
+
</task>`
|
|
86
|
+
})
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**通道 B — wrapper BC fallback**(plugin 未装时):
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
# 新会话
|
|
93
|
+
Bash({
|
|
94
|
+
command: "~/.claude/bin/codeagent-wrapper {{LITE_MODE_FLAG}}--progress --backend <{{BACKEND_PRIMARY}}|{{FRONTEND_PRIMARY}}> {{GEMINI_MODEL_FLAG}}- \"{{WORKDIR}}\" <<'EOF'\nROLE_FILE: <角色提示词路径>\n<TASK>\n需求:<增强后的需求>\n上下文:<前序阶段上下文>\n</TASK>\nOUTPUT: 期望输出格式\nEOF",
|
|
55
95
|
run_in_background: true,
|
|
56
96
|
timeout: 3600000,
|
|
57
|
-
description: "简短描述"
|
|
97
|
+
description: "简短描述 (BC)"
|
|
58
98
|
})
|
|
59
99
|
|
|
60
|
-
#
|
|
100
|
+
# 复用会话(显式 SESSION_ID)
|
|
61
101
|
Bash({
|
|
62
|
-
command: "~/.claude/bin/codeagent-wrapper {{LITE_MODE_FLAG}}--progress --backend <{{BACKEND_PRIMARY}}|{{FRONTEND_PRIMARY}}> {{GEMINI_MODEL_FLAG}}resume <SESSION_ID> - \"{{WORKDIR}}\" <<'EOF'
|
|
63
|
-
ROLE_FILE: <角色提示词路径>
|
|
64
|
-
<TASK>
|
|
65
|
-
需求:<增强后的需求(如未增强则用 $ARGUMENTS)>
|
|
66
|
-
上下文:<前序阶段收集的项目上下文、分析结果等>
|
|
67
|
-
</TASK>
|
|
68
|
-
OUTPUT: 期望输出格式
|
|
69
|
-
EOF",
|
|
102
|
+
command: "~/.claude/bin/codeagent-wrapper {{LITE_MODE_FLAG}}--progress --backend <{{BACKEND_PRIMARY}}|{{FRONTEND_PRIMARY}}> {{GEMINI_MODEL_FLAG}}resume <SESSION_ID> - \"{{WORKDIR}}\" <<'EOF'\nROLE_FILE: <角色提示词路径>\n<TASK>\n需求:<增强后的需求>\n上下文:<前序阶段上下文>\n</TASK>\nEOF",
|
|
70
103
|
run_in_background: true,
|
|
71
104
|
timeout: 3600000,
|
|
72
|
-
description: "简短描述"
|
|
105
|
+
description: "简短描述 (BC, resume)"
|
|
73
106
|
})
|
|
74
107
|
```
|
|
75
108
|
|
|
76
|
-
|
|
109
|
+
**角色提示词路径**(通道 A 主线 Read 后拼入 `<role>` 块;通道 B 仍用 `ROLE_FILE:` 写在 EOF 内):
|
|
77
110
|
|
|
78
111
|
| 阶段 | 后端 | 前端 |
|
|
79
112
|
|------|-------|--------|
|
|
@@ -81,7 +114,9 @@ EOF",
|
|
|
81
114
|
| 规划 | `~/.claude/.ccg/prompts/{{BACKEND_PRIMARY}}/architect.md` | `~/.claude/.ccg/prompts/{{FRONTEND_PRIMARY}}/architect.md` |
|
|
82
115
|
| 审查 | `~/.claude/.ccg/prompts/{{BACKEND_PRIMARY}}/reviewer.md` | `~/.claude/.ccg/prompts/{{FRONTEND_PRIMARY}}/reviewer.md` |
|
|
83
116
|
|
|
84
|
-
|
|
117
|
+
**会话复用模型差异**:
|
|
118
|
+
- **通道 A(plugin)**:同 Claude session 内连续阶段用 `--resume`,自动接上一次同 backend 的 thread(codex/gemini 各自独立的 `--resume-last` 行为)。**不支持跨任务跳点 resume by ID**——若中间插了其他 codex 调用会串。
|
|
119
|
+
- **通道 B(wrapper)**:每次 spawn 返回 `SESSION_ID: xxx`,后续 `resume xxx` 任意复用(注意:是 `resume`,不是 `--resume`)。
|
|
85
120
|
|
|
86
121
|
**并行调用 + 事件驱动等待**:
|
|
87
122
|
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// CCG plugin detection helper (v2.3.1+)
|
|
3
|
+
//
|
|
4
|
+
// Reads Claude Code's authoritative plugin registry at
|
|
5
|
+
// ~/.claude/plugins/installed_plugins.json and reports whether the
|
|
6
|
+
// codex and gemini plugins required by ccgx Channel A (plugin spawn)
|
|
7
|
+
// are registered.
|
|
8
|
+
//
|
|
9
|
+
// Exit codes:
|
|
10
|
+
// 0 = both plugins ok (use Channel A)
|
|
11
|
+
// 1 = at least one missing (use Channel B / wrapper BC fallback)
|
|
12
|
+
// 2 = registry missing or unparsable (use Channel B)
|
|
13
|
+
//
|
|
14
|
+
// stdout (single line JSON):
|
|
15
|
+
// {"codex": "<version>"|null, "gemini": "<version>"|null, "error"?: "<msg>"}
|
|
16
|
+
|
|
17
|
+
const fs = require('fs');
|
|
18
|
+
const os = require('os');
|
|
19
|
+
const path = require('path');
|
|
20
|
+
|
|
21
|
+
const registryPath = path.join(os.homedir(), '.claude', 'plugins', 'installed_plugins.json');
|
|
22
|
+
|
|
23
|
+
function emit(payload, exitCode) {
|
|
24
|
+
process.stdout.write(JSON.stringify(payload) + '\n');
|
|
25
|
+
process.exit(exitCode);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
if (!fs.existsSync(registryPath)) {
|
|
30
|
+
emit({ codex: null, gemini: null, error: 'registry-missing' }, 2);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const raw = fs.readFileSync(registryPath, 'utf8');
|
|
34
|
+
const data = JSON.parse(raw);
|
|
35
|
+
const plugins = (data && data.plugins) || {};
|
|
36
|
+
|
|
37
|
+
const codexKey = Object.keys(plugins).find((k) => k.startsWith('codex@'));
|
|
38
|
+
const geminiKey = Object.keys(plugins).find((k) => k.startsWith('gemini@'));
|
|
39
|
+
|
|
40
|
+
const codexEntry = codexKey ? plugins[codexKey] : null;
|
|
41
|
+
const geminiEntry = geminiKey ? plugins[geminiKey] : null;
|
|
42
|
+
|
|
43
|
+
const codex = Array.isArray(codexEntry) && codexEntry[0] ? (codexEntry[0].version || 'unknown') : null;
|
|
44
|
+
const gemini = Array.isArray(geminiEntry) && geminiEntry[0] ? (geminiEntry[0].version || 'unknown') : null;
|
|
45
|
+
|
|
46
|
+
emit({ codex, gemini }, codex && gemini ? 0 : 1);
|
|
47
|
+
} catch (e) {
|
|
48
|
+
emit({ codex: null, gemini: null, error: String(e && e.message || e) }, 2);
|
|
49
|
+
}
|