@mcgrapeng/ccg 3.1.0

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 ADDED
@@ -0,0 +1,220 @@
1
+ # ccg — Code Divergence Detector
2
+
3
+ > A Claude Code slash command. Install once, type `/ccg` on a diff.
4
+
5
+ [![Tests](https://img.shields.io/badge/tests-99%20passing-brightgreen.svg)]()
6
+ [![npm](https://img.shields.io/npm/v/@mcgrapeng/ccg.svg)](https://www.npmjs.com/package/@mcgrapeng/ccg)
7
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
8
+
9
+ **English** | [简体中文](README.zh-CN.md) | [日本語](README.ja.md) | [한국어](README.ko.md) · [Architecture →](docs/ARCHITECTURE.md)
10
+
11
+ ---
12
+
13
+ ## What is ccg
14
+
15
+ You're about to merge a change to `auth/login.go`. You want a sanity check. Today you have three options, all of them flawed:
16
+
17
+ - **Single-model review** (Copilot, Cursor `/review`, Aider) gives you **one perspective**. If Claude misses a timing attack, you miss it too.
18
+ - **Multi-model gateways** (zen-mcp-server etc.) **average opinions**, hiding exactly the places where smart models disagreed — which is the only place you actually needed help.
19
+ - **Manual cross-checking** is what you'd do if you had unlimited time. You don't.
20
+
21
+ ccg is a `/ccg` slash command for Claude Code that fixes all three. On any diff, it:
22
+
23
+ 1. Sends the same prompt to **Codex (OpenAI)** and **Gemini (Google)** in parallel
24
+ 2. Has **Claude** read both reports and surface **specifically where they disagree** — that's where human judgment is needed
25
+ 3. Tracks cost, picks the cheapest model good enough for the risk level, and remembers past reviews
26
+
27
+ **Think of it like:** asking two senior engineers from different teams to review the same PR, then having a tech lead synthesize: "they agree on these issues, they disagree on this one — you decide, and here's my read."
28
+
29
+ ## When to use ccg
30
+
31
+ The trigger isn't a *domain* — it's a *feeling*. Use ccg when, looking at your own diff, you catch yourself thinking:
32
+
33
+ | Inner monologue | Use ccg? |
34
+ |---|---|
35
+ | "If I get this wrong, I'll get paged at 3am." | ✅ Yes |
36
+ | "This is a judgment call — no obviously right answer." | ✅ Yes |
37
+ | "I wish someone else would look at this first." | ✅ Yes |
38
+ | "I just renamed a variable." | ❌ No |
39
+ | "Docs-only change." | ❌ No |
40
+ | "I want streaming chat with one model." | ❌ No (use the CLI directly) |
41
+
42
+ **Examples across domains** — none of these are auth/crypto, all of them are real "two senior engineers would disagree" moments:
43
+
44
+ - **Social platforms** — re-ranking the feed with a new engagement signal · comment-thread fan-out strategy · A/B test bucketing logic · anti-abuse rate-limit policy · graph-DB schema for follow relationships
45
+ - **Data / AI infra** — switching embedding model (do you re-index?) · changing chunking strategy · RAG retrieval scoring · prompt-injection defense layering
46
+ - **Frontend** — SSR vs ISR vs RSC for a new page · cache invalidation strategy · state-management refactor · accessibility trade-offs
47
+ - **API design** — cursor vs offset pagination · error response model · versioning approach · idempotency-key handling
48
+ - **Distributed systems** — timeout/retry policy · cache TTL vs event-driven invalidation · partition tolerance trade-off · leader-election semantics
49
+ - **Database** — multi-step migration sequencing · index choice on a hot path · transaction isolation level · soft-delete vs hard-delete
50
+ - **Security** — yes, auth / crypto / payments too — but just one of many domains
51
+
52
+ **The pattern:** any change where a reasonable engineer might pick option A and another reasonable engineer might pick option B. That's when divergence detection earns its $0.04.
53
+
54
+ ## Why ccg (vs everything else)
55
+
56
+ **1. Disagreement is the signal, not the noise.**
57
+ When Codex says "use `subtle.ConstantTimeCompare`" and Gemini says "bcrypt is already constant-time, that's cargo-cult", *that* is where you need to think. Other tools blend these into a vague "consider timing attacks". ccg shows you the conflict verbatim.
58
+
59
+ **2. Cost telemetry built in.**
60
+ Codex/Gemini CLIs don't tell you what you spent. ccg logs every call, picks the cheapest sufficient model automatically (risk-aware routing), and caches identical prompts for 24h. `ccg_usage --this-month` answers "how much have I spent so far?".
61
+
62
+ **3. A review history that survives across sessions.**
63
+ "What did the model say about `src/auth.ts` two weeks ago?" — ccg's append-only ledger answers that. No stateless tool can.
64
+
65
+ ## Install
66
+
67
+ Pick one:
68
+
69
+ ```bash
70
+ # npm (recommended)
71
+ npx @mcgrapeng/ccg install
72
+
73
+ # or curl one-liner, no Node
74
+ curl -fsSL https://raw.githubusercontent.com/mcgrapeng/ccg/main/scripts/curl-install.sh | bash
75
+ ```
76
+
77
+ Then install the AI CLIs once:
78
+
79
+ ```bash
80
+ npm i -g @openai/codex @google/gemini-cli
81
+ echo 'export GEMINI_API_KEY="<your-key>"' >> ~/.zshenv
82
+ ```
83
+
84
+ Verify:
85
+
86
+ ```bash
87
+ npx @mcgrapeng/ccg doctor # check Codex / Gemini / API key
88
+ npx @mcgrapeng/ccg about # 7-layer capability probe + runtime state
89
+ ```
90
+
91
+ ## Try it — a walkthrough
92
+
93
+ Say you just edited `auth/login.go`:
94
+
95
+ ```go
96
+ // before // after
97
+ func Login(user, pw string) bool { func Login(user, pw string) bool {
98
+ u := lookupUser(user) u := lookupUser(user)
99
+ - return u.Hash == sha256.Sum256([]byte(pw)) hashed, err := bcrypt.GenerateFromPassword([]byte(pw), 12)
100
+ + if err != nil { return false }
101
+ + return subtle.ConstantTimeCompare(u.Hash, hashed) == 1
102
+ }
103
+ ```
104
+
105
+ You open Claude Code and type:
106
+
107
+ ```
108
+ /ccg
109
+ ```
110
+
111
+ After ~30 seconds you see something like this — **real output**, not a placeholder:
112
+
113
+ ```
114
+ 📍 Scope: worktree · 1 file · +4 -1 lines
115
+ 🎯 Mode: quality (risk=65 · auth+35 size>0+5 crypto-mention+25)
116
+ 🩺 Both reviewers OK: Codex ✓ · Gemini ✓
117
+ 💰 Cost: $0.041
118
+
119
+ ═══ AGREEMENT (2) — both flagged, low signal ═══
120
+ • auth/login.go:3 — sha256 wasn't a password hash; bcrypt is correct
121
+ • auth/login.go:5 — handle the bcrypt error explicitly (you do)
122
+
123
+ ═══ DIVERGENCE (1) — the models disagreed ★ you decide ═══
124
+
125
+ ▸ auth/login.go:6 — how to compare bcrypt hashes
126
+ 🔵 Codex: "Wrap with subtle.ConstantTimeCompare to prevent timing attacks
127
+ even with bcrypt."
128
+ 🟢 Gemini: "bcrypt.CompareHashAndPassword is already constant-time. Wrapping
129
+ it is cargo-cult and can mask bugs (length mismatch panics)."
130
+ ⚖️ Claude: Gemini is correct. bcrypt.CompareHashAndPassword is the canonical
131
+ comparison; ConstantTimeCompare on its raw output is a category
132
+ error — you'd be comparing the freshly-hashed `pw` against the
133
+ stored hash, but bcrypt salts each hash uniquely so direct
134
+ comparison ALWAYS returns false.
135
+ ➡️ Action: Replace the ConstantTimeCompare line with:
136
+ `err := bcrypt.CompareHashAndPassword(u.Hash, []byte(pw))`
137
+ `return err == nil`
138
+
139
+ ═══ BLINDSPOT (1) — neither saw, Claude suspects ═══
140
+ • Error path: returning `false` on bcrypt error is correct for the caller but
141
+ silently swallows infrastructure errors (e.g. bcrypt OOM). Log the error.
142
+
143
+ ═══ VERDICT: fix-required ═══
144
+ The comparison logic as written will always reject valid passwords. Apply
145
+ the DIVERGENCE action, add error logging, and you're good to merge.
146
+ ```
147
+
148
+ ### How to read this output
149
+
150
+ | Section | What it means | What to do |
151
+ |---|---|---|
152
+ | **AGREEMENT** | Both Codex and Gemini flagged the same thing. Your single-source Claude likely catches these too — **low new information**. | Skim, fix if not already done. |
153
+ | **DIVERGENCE** ★ | The two models disagreed. **This is the whole reason ccg exists.** Claude's "Action" line gives you a recommendation, but you're the final decider. | Read carefully. Apply Claude's call or override it. |
154
+ | **BLINDSPOT** | Neither model raised it, but Claude noticed something while synthesizing. **Use sparingly** — limit 2 per run. | Treat as a hint, not gospel. |
155
+ | **VERDICT** | `merge` / `fix-required` / `discuss`. One-line summary. | Use as merge gate. |
156
+
157
+ After the review, `ccg_ledger_record` writes one JSONL line to your ledger. Two weeks from now you can:
158
+
159
+ ```bash
160
+ source ~/.claude/commands/ccg.sh
161
+ ccg_ledger_query "auth/login.go"
162
+ # → "auth/login.go: 3 reviews · last 2026-05-23 (fix-required) · 2026-05-09 (merge) · 2026-04-28 (discuss)"
163
+ ```
164
+
165
+ ## Configure (defaults are usually fine)
166
+
167
+ Mode and model picks are automatic. Override only when needed:
168
+
169
+ ```bash
170
+ CCG_MODE=quality /ccg # force quality models on any diff
171
+ CCG_CODEX_MODEL=o3 /ccg # override one model
172
+ CCG_NO_CACHE=1 /ccg # skip 24h cache for this call
173
+ ```
174
+
175
+ Common knobs (full list in [Architecture → §5](docs/ARCHITECTURE.md#5-extension-points)):
176
+
177
+ | Variable | Default | Purpose |
178
+ |---|---|---|
179
+ | `CCG_MODE` | `auto` | `auto` / `cost` / `balanced` / `quality` |
180
+ | `CCG_CACHE_TTL_HOURS` | `24` | Cache TTL |
181
+ | `CCG_MAX_PROMPT_KB` | `100` | Per-call prompt size cap |
182
+
183
+ Cost reference (USD per call, after cache):
184
+
185
+ | Mode | Codex | Gemini | Typical cost |
186
+ |---|---|---|---|
187
+ | `cost` | gpt-5-nano | gemini-2.5-flash-lite | ~$0.0007 |
188
+ | `balanced` | gpt-5-mini | gemini-2.5-flash | ~$0.0046 |
189
+ | `quality` | gpt-5 | gemini-2.5-pro | ~$0.0440 |
190
+
191
+ See accumulated spend any time:
192
+
193
+ ```bash
194
+ source ~/.claude/commands/ccg.sh
195
+ ccg_usage --this-month
196
+ ```
197
+
198
+ ## Not for
199
+
200
+ - IDEs other than Claude Code (try [zen-mcp-server](https://github.com/BeehiveInnovations/zen-mcp-server))
201
+ - Replacing static analysis (pair with Semgrep / CodeQL)
202
+ - Auto-running on every PR (ccg is a triage tool, not a bot)
203
+ - Streaming or multi-turn conversation
204
+
205
+ ## Architecture & contributing
206
+
207
+ ccg is **7 layers**, only the top one is "divergence detection". The other six (cache, ledger, usage, risk routing, smart diff, safe CLI scheduling) each independently solve a real problem. Read [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) before changing anything in `ccg.sh`.
208
+
209
+ Tests:
210
+
211
+ ```bash
212
+ bash tests/test_ccg.sh # 99 regression tests, ~31s
213
+ REAL_CLI=1 bash tests/test_ccg.sh # +2 live API tests (incurs cost)
214
+ ```
215
+
216
+ ## License & credits
217
+
218
+ MIT — see [LICENSE](LICENSE).
219
+
220
+ Built on [oh-my-claudecode](https://github.com/Yeachan-Heo/oh-my-claudecode)'s original `/ccg` concept · Claude Code · OpenAI Codex CLI · Google Gemini CLI.
@@ -0,0 +1,219 @@
1
+ # ccg — 代码分歧检测器
2
+
3
+ > Claude Code 的 slash command。装一次,在 diff 上输入 `/ccg`。
4
+
5
+ [![Tests](https://img.shields.io/badge/tests-99%20passing-brightgreen.svg)]()
6
+ [![npm](https://img.shields.io/npm/v/@mcgrapeng/ccg.svg)](https://www.npmjs.com/package/@mcgrapeng/ccg)
7
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
8
+
9
+ [English](README.md) | **简体中文** | [日本語](README.ja.md) | [한국어](README.ko.md) · [架构文档 →](docs/ARCHITECTURE.zh-CN.md)
10
+
11
+ ---
12
+
13
+ ## ccg 是什么
14
+
15
+ 你刚改完 `auth/login.go`,准备 merge。你想"保险一下"再走。今天你只有三种选择,每种都有硬伤:
16
+
17
+ - **单模型 review**(Copilot、Cursor `/review`、Aider)只给**一种视角**。如果 Claude 漏看了 timing attack,你也会一起漏。
18
+ - **多模型聚合工具**(zen-mcp-server 等)把多个模型的意见**平均化**,恰好遮盖了它们意见分歧的地方——而那才是你真正需要思考的位置。
19
+ - **手工双查**理论上最稳,但你没那个时间。
20
+
21
+ ccg 是 Claude Code 的 `/ccg` slash command,针对这三件事都做了真正的解决:
22
+
23
+ 1. 把同一个 prompt **并行**发给 **Codex(OpenAI)** 和 **Gemini(Google)**
24
+ 2. 让 **Claude** 读完两份报告,**聚焦它们意见不一致的地方**——人需要拍板的就在那里
25
+ 3. 自动按代码风险选最便宜够用的模型、记录每次调用成本、保留历史评审账本
26
+
27
+ **类比理解**:就像让两个不同团队的 senior 工程师 review 同一份 PR,再让一个 tech lead 综合:"这几点他们都同意,这一点他们意见不一致——你来定,下面是我的看法。"
28
+
29
+ ## 什么时候用 ccg
30
+
31
+ 触发条件不是**领域**,而是**感觉**。当你看着自己刚写完的 diff,心里冒出下面这种念头,就是 ccg 的场景:
32
+
33
+ | 你心里在想 | 用 ccg? |
34
+ |---|---|
35
+ | "这个改错了,我凌晨会被叫起来" | ✅ 用 |
36
+ | "这是个判断题,没有一定对的答案" | ✅ 用 |
37
+ | "我希望有第二个人帮我看一眼" | ✅ 用 |
38
+ | "我就是改了个变量名" | ❌ 不用 |
39
+ | "只改了文档" | ❌ 不用 |
40
+ | "我想跟单个模型流式对话" | ❌ 不用(直接用 CLI) |
41
+
42
+ **跨领域真实例子** —— 都不是 auth / 加密的场景,但都是"两个资深工程师真会吵起来"的瞬间:
43
+
44
+ - **社交平台** —— feed 排序换了新的互动信号 · 评论树 fan-out 策略 · A/B 实验分桶逻辑 · 反滥用限流策略 · 关注关系的图数据库 schema
45
+ - **数据 / AI 基建** —— 换 embedding 模型(向量库要不要重建?) · 改 chunking 策略 · RAG 检索打分 · prompt injection 防御分层
46
+ - **前端** —— 新页面用 SSR 还是 ISR 还是 RSC · 缓存失效策略 · 状态管理重构 · 可访问性取舍
47
+ - **API 设计** —— 分页用 cursor 还是 offset · 错误响应模型 · 版本管理策略 · 幂等性 key 处理
48
+ - **分布式系统** —— 超时 / 重试策略 · cache TTL vs 事件驱动失效 · 分区容忍度取舍 · leader election 语义
49
+ - **数据库** —— 多步迁移的拆分顺序 · 热点路径的索引选择 · 事务隔离级别 · 软删 vs 硬删
50
+ - **安全** —— 对,auth / 加密 / 支付也属于这类 —— 但只是众多领域之一
51
+
52
+ **判断标准**:任何一个"合理的工程师可能选 A、另一个合理的工程师可能选 B"的改动,就是分歧检测赚回 $0.04 的时刻。
53
+
54
+ ## 为什么是 ccg(和其他工具的对比)
55
+
56
+ **1. 分歧才是信号,不是噪音。**
57
+ 当 Codex 说"加上 `subtle.ConstantTimeCompare` 防 timing attack",而 Gemini 说"bcrypt 自己就是恒定时间的,加包装是 cargo-cult"——**这才是你需要思考的地方**。别的工具会把这种冲突糊成一句模糊的"注意 timing 攻击"。ccg 把两边原话端给你。
58
+
59
+ **2. 内置成本可见性。**
60
+ Codex / Gemini CLI 都不告诉你花了多少钱。ccg 记录每次调用,按风险自动选最便宜够用的模型(risk-aware routing),相同 prompt 24h 内命中缓存零成本。`ccg_usage --this-month` 立刻回答"这个月我花了多少?"。
61
+
62
+ **3. 跨会话保留的评审历史。**
63
+ "两周前模型对 `src/auth.ts` 说了什么?"——ccg 的 append-only 账本能回答。任何无状态工具都做不到。
64
+
65
+ ## 怎么安装
66
+
67
+ 二选一:
68
+
69
+ ```bash
70
+ # npm(推荐)
71
+ npx @mcgrapeng/ccg install
72
+
73
+ # 或 curl 一行装,无需 Node
74
+ curl -fsSL https://raw.githubusercontent.com/mcgrapeng/ccg/main/scripts/curl-install.sh | bash
75
+ ```
76
+
77
+ 再装两个 AI CLI(一次性):
78
+
79
+ ```bash
80
+ npm i -g @openai/codex @google/gemini-cli
81
+ echo 'export GEMINI_API_KEY="<你的-key>"' >> ~/.zshenv
82
+ ```
83
+
84
+ 验证:
85
+
86
+ ```bash
87
+ npx @mcgrapeng/ccg doctor # 检查 Codex / Gemini / API key
88
+ npx @mcgrapeng/ccg about # 看 7 层能力 + 当前环境状态
89
+ ```
90
+
91
+ ## 完整使用示例
92
+
93
+ 假设你刚改了 `auth/login.go`:
94
+
95
+ ```go
96
+ // 改前 // 改后
97
+ func Login(user, pw string) bool { func Login(user, pw string) bool {
98
+ u := lookupUser(user) u := lookupUser(user)
99
+ - return u.Hash == sha256.Sum256([]byte(pw)) hashed, err := bcrypt.GenerateFromPassword([]byte(pw), 12)
100
+ + if err != nil { return false }
101
+ + return subtle.ConstantTimeCompare(u.Hash, hashed) == 1
102
+ }
103
+ ```
104
+
105
+ 你在 Claude Code 输入:
106
+
107
+ ```
108
+ /ccg
109
+ ```
110
+
111
+ 约 30 秒后你会看到——**真实输出示例**,不是占位符:
112
+
113
+ ```
114
+ 📍 范围:worktree · 1 个文件 · +4 -1 行
115
+ 🎯 模式:quality (风险=65 · auth+35 size>0+5 crypto-mention+25)
116
+ 🩺 两个评审者都正常:Codex ✓ · Gemini ✓
117
+ 💰 成本:$0.041
118
+
119
+ ═══ AGREEMENT (2) — 两边都标记,信号弱 ═══
120
+ • auth/login.go:3 — sha256 不是密码哈希;换成 bcrypt 是对的
121
+ • auth/login.go:5 — bcrypt 错误要显式处理(你做了)
122
+
123
+ ═══ DIVERGENCE (1) — 两个模型不一致 ★ 你来决定 ═══
124
+
125
+ ▸ auth/login.go:6 — 怎么比较 bcrypt 哈希
126
+ 🔵 Codex 说: "外包一层 subtle.ConstantTimeCompare 防 timing 攻击,
127
+ 即使用了 bcrypt 也要加。"
128
+ 🟢 Gemini 说:"bcrypt.CompareHashAndPassword 自身就是恒定时间的。
129
+ 外包一层是 cargo-cult,反而可能因为长度不一致 panic。"
130
+ ⚖️ Claude 综合:Gemini 是对的。bcrypt.CompareHashAndPassword 才是
131
+ 标准比较方式;对它的原始输出做 ConstantTimeCompare 是
132
+ 根本性错误——你比较的是"刚 hash 的 pw"和"存储的 hash",
133
+ 而 bcrypt 每次 hash 都用新的盐,所以直接比较永远返回 false。
134
+ ➡️ 建议动作: 把 ConstantTimeCompare 那行替换为:
135
+ `err := bcrypt.CompareHashAndPassword(u.Hash, []byte(pw))`
136
+ `return err == nil`
137
+
138
+ ═══ BLINDSPOT (1) — 两边都没看到 Claude 怀疑 ═══
139
+ • 错误处理路径:bcrypt 出错时返回 false 对调用方是对的,但是会静默吞掉
140
+ 基础设施错误(比如 bcrypt OOM)。建议加日志。
141
+
142
+ ═══ VERDICT: fix-required ═══
143
+ 当前比较逻辑会永远拒绝合法密码。按 DIVERGENCE 的建议改完 + 加错误日志,
144
+ 就可以 merge 了。
145
+ ```
146
+
147
+ ### 怎么看懂这份输出
148
+
149
+ | 段落 | 是什么意思 | 你该怎么办 |
150
+ |---|---|---|
151
+ | **AGREEMENT** | Codex 和 Gemini 都标记的同一个问题。你单源用 Claude 也大概率能发现——**新信息量低**。 | 扫一眼,没改的就改。 |
152
+ | **DIVERGENCE** ★ | 两个模型意见不一致。**这才是 ccg 存在的真正原因。** Claude 的"建议动作"给你推荐,但你是最终拍板的人。 | 仔细读,接受 Claude 判断或自己覆盖。 |
153
+ | **BLINDSPOT** | 两个模型都没看到,但 Claude 综合时怀疑。**慎用**——每次最多 2 条。 | 当提示看,不是金科玉律。 |
154
+ | **VERDICT** | `merge` / `fix-required` / `discuss`。一句话结论。 | 当 merge 门禁用。 |
155
+
156
+ 评审完,`ccg_ledger_record` 会写一行 JSONL 到账本。两周后你可以:
157
+
158
+ ```bash
159
+ source ~/.claude/commands/ccg.sh
160
+ ccg_ledger_query "auth/login.go"
161
+ # → "auth/login.go: 3 次评审 · 最近 2026-05-23 (fix-required) · 2026-05-09 (merge) · 2026-04-28 (discuss)"
162
+ ```
163
+
164
+ ## 配置(默认值通常够用)
165
+
166
+ 模式和模型都是自动的。需要时再覆盖:
167
+
168
+ ```bash
169
+ CCG_MODE=quality /ccg # 任意 diff 都强制 quality 模型
170
+ CCG_CODEX_MODEL=o3 /ccg # 单独换某个模型
171
+ CCG_NO_CACHE=1 /ccg # 本次跳过 24h 缓存
172
+ ```
173
+
174
+ 常用配置(全部在 [架构文档 § 5](docs/ARCHITECTURE.zh-CN.md#5-扩展点)):
175
+
176
+ | 变量 | 默认 | 用途 |
177
+ |---|---|---|
178
+ | `CCG_MODE` | `auto` | `auto` / `cost` / `balanced` / `quality` |
179
+ | `CCG_CACHE_TTL_HOURS` | `24` | 缓存 TTL |
180
+ | `CCG_MAX_PROMPT_KB` | `100` | 单次 prompt 大小硬上限 |
181
+
182
+ 成本参考(USD / 次,缓存命中 $0):
183
+
184
+ | 模式 | Codex | Gemini | 单次典型 |
185
+ |---|---|---|---|
186
+ | `cost` | gpt-5-nano | gemini-2.5-flash-lite | ~$0.0007 |
187
+ | `balanced` | gpt-5-mini | gemini-2.5-flash | ~$0.0046 |
188
+ | `quality` | gpt-5 | gemini-2.5-pro | ~$0.0440 |
189
+
190
+ 随时查累计:
191
+
192
+ ```bash
193
+ source ~/.claude/commands/ccg.sh
194
+ ccg_usage --this-month
195
+ ```
196
+
197
+ ## 不适合的场景
198
+
199
+ - Claude Code 之外的 IDE(试试 [zen-mcp-server](https://github.com/BeehiveInnovations/zen-mcp-server))
200
+ - 替代静态分析(要配合 Semgrep / CodeQL 用)
201
+ - 每个 PR 自动跑(ccg 是分诊工具,不是机器人)
202
+ - 流式输出或多轮对话
203
+
204
+ ## 架构与贡献
205
+
206
+ ccg 一共 **7 层**,"分歧检测"只是最上面一层。下面 6 层(缓存、账本、用量、风险路由、智能 diff、安全 CLI 调度)各自独立解决真问题。改 `ccg.sh` 之前先读 [docs/ARCHITECTURE.zh-CN.md](docs/ARCHITECTURE.zh-CN.md)。
207
+
208
+ 测试:
209
+
210
+ ```bash
211
+ bash tests/test_ccg.sh # 99 个回归测试,~31s
212
+ REAL_CLI=1 bash tests/test_ccg.sh # +2 个真实 API 测试(会扣费)
213
+ ```
214
+
215
+ ## 许可证与致谢
216
+
217
+ MIT —— 见 [LICENSE](LICENSE)。
218
+
219
+ 基于 [oh-my-claudecode](https://github.com/Yeachan-Heo/oh-my-claudecode) 最初的 `/ccg` 概念 · Claude Code · OpenAI Codex CLI · Google Gemini CLI。