@mcgrapeng/ccg 3.1.0 → 4.0.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/.claude/settings.local.json +110 -0
- package/.idea/MypyPlugin.xml +7 -0
- package/.idea/ccg.iml +8 -0
- package/.idea/inspectionProfiles/Project_Default.xml +23 -0
- package/.idea/inspectionProfiles/profiles_settings.xml +6 -0
- package/.idea/misc.xml +7 -0
- package/.idea/modules.xml +8 -0
- package/.idea/ruff.xml +6 -0
- package/.idea/vcs.xml +6 -0
- package/README.md +576 -141
- package/a.txt +9 -0
- package/asym_test.sh +18 -0
- package/bin/ccg-precommit.bat +22 -0
- package/bin/ccg.js +12 -10
- package/ccg +15 -0
- package/ccg-bailian-integration.sh +210 -0
- package/ccg-bailian-models.sh +123 -0
- package/ccg-multi-provider.sh +399 -0
- package/ccg-workflow.sh +1088 -0
- package/ccg.md +290 -50
- package/ccg.sh +2727 -112
- package/docs/ARCHITECTURE.ja.md +463 -0
- package/docs/ARCHITECTURE.ko.md +463 -0
- package/docs/ARCHITECTURE.md +490 -0
- package/docs/ARCHITECTURE.zh-CN.md +469 -0
- package/docs/CAPABILITIES.md +206 -0
- package/docs/CHANGELOG.md +252 -0
- package/docs/README.ja.md +424 -0
- package/docs/README.ko.md +423 -0
- package/docs/README.zh-CN.md +450 -0
- package/package.json +13 -20
- package/scripts/curl-install.sh +100 -27
- package/scripts/install.sh +21 -5
- package/test-bailian-full.sh +90 -0
- package/test-bailian.sh +49 -0
- package/CHANGELOG.md +0 -119
- package/README.ja.md +0 -220
- package/README.ko.md +0 -219
- package/README.zh-CN.md +0 -219
package/scripts/install.sh
CHANGED
|
@@ -20,19 +20,35 @@ CCG_SH="$HERE/ccg.sh"
|
|
|
20
20
|
CCG_MD="$HERE/ccg.md"
|
|
21
21
|
TARGET_DIR="${HOME}/.claude/commands"
|
|
22
22
|
|
|
23
|
-
[ -r "$CCG_SH" ] || { echo "FATAL: $CCG_SH not found"; exit 2; }
|
|
24
|
-
[ -r "$CCG_MD" ] || { echo "FATAL: $CCG_MD not found"; exit 2; }
|
|
23
|
+
[ -r "$CCG_SH" ] || { echo "FATAL: $CCG_SH not found or not readable" >&2; exit 2; }
|
|
24
|
+
[ -r "$CCG_MD" ] || { echo "FATAL: $CCG_MD not found or not readable" >&2; exit 2; }
|
|
25
25
|
|
|
26
26
|
echo "→ Installing /ccg to: $TARGET_DIR"
|
|
27
27
|
|
|
28
28
|
if [ "$DRY" = "0" ]; then
|
|
29
|
-
mkdir -p "$TARGET_DIR"
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
if ! mkdir -p "$TARGET_DIR" 2>/dev/null; then
|
|
30
|
+
echo "❌ Failed to create directory: $TARGET_DIR" >&2
|
|
31
|
+
echo " Check permissions or run: mkdir -p $TARGET_DIR" >&2
|
|
32
|
+
exit 2
|
|
33
|
+
fi
|
|
34
|
+
if ! install -m 0755 "$CCG_SH" "$TARGET_DIR/ccg.sh" 2>/dev/null; then
|
|
35
|
+
echo "❌ Failed to install ccg.sh to $TARGET_DIR/ccg.sh" >&2
|
|
36
|
+
echo " Check file permissions and disk space" >&2
|
|
37
|
+
exit 2
|
|
38
|
+
fi
|
|
39
|
+
if ! install -m 0644 "$CCG_MD" "$TARGET_DIR/ccg.md" 2>/dev/null; then
|
|
40
|
+
echo "❌ Failed to install ccg.md to $TARGET_DIR/ccg.md" >&2
|
|
41
|
+
echo " Check file permissions and disk space" >&2
|
|
42
|
+
exit 2
|
|
43
|
+
fi
|
|
32
44
|
echo " ✓ wrote $TARGET_DIR/ccg.sh ($(wc -l <"$CCG_SH" | tr -d ' ') lines)"
|
|
33
45
|
echo " ✓ wrote $TARGET_DIR/ccg.md"
|
|
34
46
|
else
|
|
35
47
|
echo " [dry-run] would write: $TARGET_DIR/{ccg.sh,ccg.md}"
|
|
48
|
+
echo " [dry-run] skipping preflight checks (no code executed)"
|
|
49
|
+
echo
|
|
50
|
+
echo "→ Done (dry-run). Run without --dry-run to install."
|
|
51
|
+
exit 0
|
|
36
52
|
fi
|
|
37
53
|
|
|
38
54
|
echo
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# 完整测试 Bailian 集成
|
|
3
|
+
|
|
4
|
+
set -e
|
|
5
|
+
|
|
6
|
+
source "$(dirname "$0")/ccg.sh"
|
|
7
|
+
|
|
8
|
+
echo "=== Bailian 集成测试 ==="
|
|
9
|
+
echo ""
|
|
10
|
+
|
|
11
|
+
# 1. 检查配置
|
|
12
|
+
echo "1️⃣ 检查配置..."
|
|
13
|
+
eval "$(ccg_init)"
|
|
14
|
+
eval "$(ccg_preflight)"
|
|
15
|
+
|
|
16
|
+
if [ "$CCG_PREFLIGHT_BAILIAN" != "ok" ]; then
|
|
17
|
+
echo "❌ BAILIAN_API_KEY 未设置"
|
|
18
|
+
exit 1
|
|
19
|
+
fi
|
|
20
|
+
echo "✅ API 密钥已配置"
|
|
21
|
+
echo ""
|
|
22
|
+
|
|
23
|
+
# 2. 测试模型解析
|
|
24
|
+
echo "2️⃣ 测试模型解析..."
|
|
25
|
+
for mode in cost balanced quality; do
|
|
26
|
+
export CCG_MODE="$mode"
|
|
27
|
+
model=$(_ccg_resolve_bailian_model)
|
|
28
|
+
echo " $mode → $model"
|
|
29
|
+
done
|
|
30
|
+
echo ""
|
|
31
|
+
|
|
32
|
+
# 3. 测试基础调用
|
|
33
|
+
echo "3️⃣ 测试基础调用..."
|
|
34
|
+
TEST_PROMPT="Review this code:
|
|
35
|
+
function test() { return 42; }
|
|
36
|
+
Any issues?"
|
|
37
|
+
|
|
38
|
+
echo "$TEST_PROMPT" > "$CCG_BAILIAN_PROMPT"
|
|
39
|
+
|
|
40
|
+
if ccg_bailian "$CCG_BAILIAN_PROMPT" "$CCG_BAILIAN_RESULT"; then
|
|
41
|
+
echo "✅ 基础调用成功"
|
|
42
|
+
echo " 响应大小: $(wc -c < "$CCG_BAILIAN_RESULT") 字节"
|
|
43
|
+
else
|
|
44
|
+
echo "❌ 基础调用失败"
|
|
45
|
+
cat "$CCG_BAILIAN_ERR"
|
|
46
|
+
exit 1
|
|
47
|
+
fi
|
|
48
|
+
echo ""
|
|
49
|
+
|
|
50
|
+
# 4. 测试缓存
|
|
51
|
+
echo "4️⃣ 测试缓存..."
|
|
52
|
+
if ccg_bailian "$CCG_BAILIAN_PROMPT" "$CCG_BAILIAN_RESULT"; then
|
|
53
|
+
if grep -q "cache=hit" <<< "$(ccg_bailian "$CCG_BAILIAN_PROMPT" "$CCG_BAILIAN_RESULT" 2>&1)"; then
|
|
54
|
+
echo "✅ 缓存命中"
|
|
55
|
+
else
|
|
56
|
+
echo "⚠️ 缓存未命中(首次调用)"
|
|
57
|
+
fi
|
|
58
|
+
fi
|
|
59
|
+
echo ""
|
|
60
|
+
|
|
61
|
+
# 5. 测试参数控制
|
|
62
|
+
echo "5️⃣ 测试参数控制..."
|
|
63
|
+
export CCG_BAILIAN_TEMP="0.3"
|
|
64
|
+
export CCG_BAILIAN_MAX_TOKENS="2048"
|
|
65
|
+
echo "✅ 参数已设置 (temp=0.3, max_tokens=2048)"
|
|
66
|
+
echo ""
|
|
67
|
+
|
|
68
|
+
# 6. 测试重试机制
|
|
69
|
+
echo "6️⃣ 测试重试机制..."
|
|
70
|
+
export CCG_BAILIAN_RETRIES="2"
|
|
71
|
+
echo "✅ 重试次数: 2"
|
|
72
|
+
echo ""
|
|
73
|
+
|
|
74
|
+
# 7. 测试流式输出
|
|
75
|
+
echo "7️⃣ 测试流式输出..."
|
|
76
|
+
echo "Streaming response:"
|
|
77
|
+
timeout 10 ccg_bailian_stream "$CCG_BAILIAN_PROMPT" 2>/dev/null | head -5 || echo "⚠️ 流式输出超时或失败"
|
|
78
|
+
echo ""
|
|
79
|
+
|
|
80
|
+
# 8. 测试所有模型
|
|
81
|
+
echo "8️⃣ 测试所有模型..."
|
|
82
|
+
for model in qwen-3.7 qwen-3.6 qwen-3.6-plus qwen-3.5-sonnet qwen-3.5-haiku; do
|
|
83
|
+
export CCG_BAILIAN_MODEL="$model"
|
|
84
|
+
price_in=$(_ccg_price "$model" input)
|
|
85
|
+
price_out=$(_ccg_price "$model" output)
|
|
86
|
+
echo " $model: \$$price_in/\$$price_out per 1M tokens"
|
|
87
|
+
done
|
|
88
|
+
echo ""
|
|
89
|
+
|
|
90
|
+
echo "✅ 所有测试完成!"
|
package/test-bailian.sh
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Test Bailian integration for CCG
|
|
3
|
+
|
|
4
|
+
set -e
|
|
5
|
+
|
|
6
|
+
# Source CCG functions
|
|
7
|
+
source "$(dirname "$0")/ccg.sh"
|
|
8
|
+
|
|
9
|
+
# Initialize
|
|
10
|
+
eval "$(ccg_init)"
|
|
11
|
+
eval "$(ccg_preflight)"
|
|
12
|
+
|
|
13
|
+
echo "=== CCG Bailian Integration Test ==="
|
|
14
|
+
echo ""
|
|
15
|
+
echo "Preflight Status:"
|
|
16
|
+
echo " Codex: $CCG_PREFLIGHT_CODEX"
|
|
17
|
+
echo " Gemini: $CCG_PREFLIGHT_GEMINI"
|
|
18
|
+
echo " Bailian: $CCG_PREFLIGHT_BAILIAN"
|
|
19
|
+
echo ""
|
|
20
|
+
|
|
21
|
+
if [ "$CCG_PREFLIGHT_BAILIAN" != "ok" ]; then
|
|
22
|
+
echo "❌ Bailian not configured. Set BAILIAN_API_KEY environment variable."
|
|
23
|
+
exit 1
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
# Create test prompt
|
|
27
|
+
TEST_PROMPT="Review this code for bugs:
|
|
28
|
+
function add(a, b) {
|
|
29
|
+
return a + b
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
Is this correct?"
|
|
33
|
+
|
|
34
|
+
echo "$TEST_PROMPT" > "$CCG_BAILIAN_PROMPT"
|
|
35
|
+
|
|
36
|
+
echo "Testing Bailian API call..."
|
|
37
|
+
if ccg_bailian "$CCG_BAILIAN_PROMPT" "$CCG_BAILIAN_RESULT"; then
|
|
38
|
+
echo "✅ Bailian call successful"
|
|
39
|
+
echo ""
|
|
40
|
+
echo "Response:"
|
|
41
|
+
head -20 "$CCG_BAILIAN_RESULT"
|
|
42
|
+
else
|
|
43
|
+
echo "❌ Bailian call failed"
|
|
44
|
+
cat "$CCG_BAILIAN_ERR" 2>/dev/null || echo "No error details"
|
|
45
|
+
exit 1
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
echo ""
|
|
49
|
+
echo "=== Test Complete ==="
|
package/CHANGELOG.md
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to /ccg.
|
|
4
|
-
|
|
5
|
-
## [3.1.0] — 2026-05-23
|
|
6
|
-
|
|
7
|
-
Documentation and discoverability release. No core behavior changes; safe drop-in upgrade from 3.0.0.
|
|
8
|
-
|
|
9
|
-
### Added
|
|
10
|
-
- **`ccg about` subcommand** — 7-layer capability probe. Shows what ccg can do in *this* environment (not what the README claims), with green/yellow/red status per layer, environment readiness checks (Codex CLI / Gemini CLI / GEMINI_API_KEY / git / slash command installation), XDG storage state (ledger entries, usage entries, cache size), and a quick-reference command palette.
|
|
11
|
-
- Aliases: `ccg capabilities`, `ccg caps`
|
|
12
|
-
- Use case: "I'm a new user / contributor — what is ccg actually doing on my machine right now?"
|
|
13
|
-
- **`docs/ARCHITECTURE.md`** — 387-line engineering reference for contributors and integrators. Documents the 7-layer architecture (L1 Safe CLI scheduling → L7 Divergence synthesis), each layer's purpose / problem / solution / "what breaks if you remove it", end-to-end data flow, extension points (signed contract for new risk rules / new LLM providers / new storage paths / pricing customization), invariants enforced by the test suite, and load-bearing design decisions that look weird at first glance.
|
|
14
|
-
- **4-language ARCHITECTURE translations**: `docs/ARCHITECTURE.zh-CN.md`, `docs/ARCHITECTURE.ja.md`, `docs/ARCHITECTURE.ko.md`. Cross-linked from each language's README.
|
|
15
|
-
|
|
16
|
-
### Changed
|
|
17
|
-
- **README fully rewritten** with a concrete bcrypt walkthrough — actual output (not placeholder mockups) showing how AGREEMENT / DIVERGENCE / BLINDSPOT sections render in practice. The example shows two real-world disagreement: should `bcrypt` be wrapped with `subtle.ConstantTimeCompare`? Claude synthesizes that Codex's recommendation would break the comparison entirely because bcrypt uses a fresh salt every call.
|
|
18
|
-
- **"When to use ccg" rewritten** — replaced the security-only framing (auth / payments / migrations / crypto) with judgment-difficulty framing. New trigger: *feeling*, not *domain*. Added cross-domain examples across social platforms, data/AI infra, frontend, API design, distributed systems, database, and security — emphasizing that divergence detection earns its cost on *any* change where two reasonable engineers might disagree.
|
|
19
|
-
- **README structure** restructured into three-part flow: What / Why-vs-alternatives / Install / Walkthrough — designed to answer "what does it do" and "what does the output mean" before diving into config.
|
|
20
|
-
- README v-prefix removed from H1 headings (no more "v3" branding in titles; version lives in CHANGELOG + npm).
|
|
21
|
-
|
|
22
|
-
### Internal
|
|
23
|
-
- `PROMO.md` added to `.gitignore` (marketing copy file, not part of npm package).
|
|
24
|
-
|
|
25
|
-
## [3.0.0] — 2026-05-23
|
|
26
|
-
|
|
27
|
-
Repositioning: from "multi-model review tool" to **"code divergence detector"**. Three structural pillars added; product opinion sharpened. 99-test regression (stable across 3 consecutive runs).
|
|
28
|
-
|
|
29
|
-
### Identity shift
|
|
30
|
-
**Before (v2):** "Get multi-model second opinions, see consensus + disagreement + actions."
|
|
31
|
-
**After (v3):** "Surface where Codex and Gemini *disagree* — that's where you actually need to make a call. Agreement is low-signal; divergence is the gold."
|
|
32
|
-
|
|
33
|
-
This is a category change. v3 deliberately downgrades the AGREEMENT section (one-liners only) and elevates DIVERGENCE (full expansion + `NEEDS HUMAN DECISION` markers).
|
|
34
|
-
|
|
35
|
-
### Added — Pillar 1: Divergence Engine
|
|
36
|
-
- Structured `[FINDING]…[/FINDING]` prompt protocol; both reviewers must conform
|
|
37
|
-
- Three-section synthesis output: `AGREEMENT (N) / DIVERGENCE (M) / BLINDSPOT (≤2)`
|
|
38
|
-
- `VERDICT` line: merge | fix-required | discuss
|
|
39
|
-
- `NEEDS HUMAN DECISION` is an explicit signal, not implied
|
|
40
|
-
|
|
41
|
-
### Added — Pillar 2: Risk-Aware Routing
|
|
42
|
-
- `ccg_risk_score <diff_file>` — deterministic 0..100+ scoring
|
|
43
|
-
- Path signals: auth/payment/migration/crypto/security/infra/ci (+15..+40)
|
|
44
|
-
- Body signals: shell exec/SQL interp/fs delete/privilege ops (+5..+30)
|
|
45
|
-
- Size signals: lines and files-changed (+5..+25)
|
|
46
|
-
- Docs-only subtraction (-40)
|
|
47
|
-
- Auto mode selection: <20 cost, <60 balanced, ≥60 quality
|
|
48
|
-
- Manual `CCG_MODE=` override always wins
|
|
49
|
-
- Outputs reason string for full transparency: `auth+35 sql_interp+30 size>300+15`
|
|
50
|
-
- Pure rules, zero LLM cost, social-PR friendly
|
|
51
|
-
|
|
52
|
-
### Added — Pillar 3: Review Ledger
|
|
53
|
-
- `ccg_ledger_record <workdir>` — append JSONL row to `~/.ccg/ledger.jsonl`
|
|
54
|
-
- Fields: ts, repo, branch, sha, mode, risk, files, lines, paths[], synthesis (redacted, ≤400 chars)
|
|
55
|
-
- `ccg_ledger_query [path-substring]` — search prior reviews
|
|
56
|
-
- `CCG_LEDGER_LOG` env override
|
|
57
|
-
- Synthesis excerpt runs through `_ccg_redact` before write (secret hygiene)
|
|
58
|
-
|
|
59
|
-
### Fixed — diff capture deep gap
|
|
60
|
-
- Old behavior: `git diff HEAD` only → empty after commit
|
|
61
|
-
- New 4-level fallback: `worktree → staged → upstream:@{u}…HEAD → origin/HEAD…HEAD`
|
|
62
|
-
- Reports `CCG_DIFF_SOURCE=<level>` so caller knows what scope was captured
|
|
63
|
-
- Resolves "I committed and now /ccg sees nothing" footgun
|
|
64
|
-
|
|
65
|
-
### Changed
|
|
66
|
-
- Default `CCG_MODE=auto` (was `balanced`); auto uses risk score
|
|
67
|
-
- `ccg_init` now also exposes `CCG_SYNTHESIS_FILE` and `CCG_RISK_FILE` paths
|
|
68
|
-
- Dispatch subcommands added: `risk_score`, `ledger_record`, `ledger_query`
|
|
69
|
-
|
|
70
|
-
### Tests
|
|
71
|
-
- 13 new test cases (13.1 - 13.13) covering all three pillars + diff fallback
|
|
72
|
-
- All 99 tests pass; 31s runtime; stable across consecutive runs
|
|
73
|
-
|
|
74
|
-
## [2.0.0] — 2026-05-23
|
|
75
|
-
|
|
76
|
-
Major refactor based on honest self-critique: drop low-value features, add high-leverage ones.
|
|
77
|
-
86-test regression (stable across 10 consecutive runs).
|
|
78
|
-
|
|
79
|
-
### Removed
|
|
80
|
-
- **Pre-execution cost estimate** (`ccg_estimate`). Estimating output tokens by assumption produced 3-5× wrong predictions, misleading users. Post-execution `ccg_actual` remains — it uses real byte counts.
|
|
81
|
-
- **Asymmetric prompt split** (codex=architecture, gemini=UX). It was pure intuition with no evidence. v2 sends the **same prompt to both providers** — training-data differences create natural diversity.
|
|
82
|
-
- `ccg_mode_resolve` public subcommand (resolution is now internal/silent)
|
|
83
|
-
- `CCG_USD_CNY_RATE`, `CCG_OUTPUT_TOKENS_ESTIMATE`, `CCG_TOKEN_CHARS_RATIO` knobs (no one tuned them)
|
|
84
|
-
|
|
85
|
-
### Added
|
|
86
|
-
- **Auto `git diff` mode**: naked `/ccg` (no args) captures `git diff HEAD` and runs a pre-commit triangulated review. One-keystroke workflow.
|
|
87
|
-
- `ccg_diff_capture <out_file>` — captures `git diff HEAD`, falls back to `--cached`, returns `CCG_DIFF_OK/FAIL`
|
|
88
|
-
- **24h prompt-hash cache** keyed by SHA-256(model + prompt). Same prompt + same model → cached result, $0.00 cost. Iterating on the same code saves 90%+ on repeat calls.
|
|
89
|
-
- `CCG_CACHE_DIR` (default `~/.ccg/cache`) and `CCG_CACHE_TTL_HOURS` (default 24)
|
|
90
|
-
- `CCG_NO_CACHE=1` opt-out per-call
|
|
91
|
-
- **Usage log** at `~/.ccg/usage.log` (TSV: timestamp, provider, model, in_tokens, out_tokens, USD, cached). Only successful calls logged. Override path via `CCG_USAGE_LOG`.
|
|
92
|
-
- `ccg_usage [--this-month|--all|--since=YYYY-MM]` aggregates spend by provider with cache-hit count
|
|
93
|
-
- **Prompt size guard**: `CCG_MAX_PROMPT_KB=100` default. Hard reject prompts above this. Prevents the "I piped my whole repo and got a $5 bill" footgun.
|
|
94
|
-
- New dispatch subcommands: `diff_capture`, `usage`, `actual`
|
|
95
|
-
|
|
96
|
-
### Fixed
|
|
97
|
-
- Test suite now isolates cache via `CCG_CACHE_DIR` (not `HOME`), so test runs no longer break codex/gemini auth lookup
|
|
98
|
-
- Mock-mode test helpers always set `CCG_NO_CACHE=1` so failure-mode tests can't be masked by an earlier success-mode cache entry
|
|
99
|
-
|
|
100
|
-
## [1.0.0] — 2026-05-22
|
|
101
|
-
|
|
102
|
-
First production-ready release.
|
|
103
|
-
|
|
104
|
-
### Added
|
|
105
|
-
- `CCG_MODE=cost|balanced|quality` for model selection
|
|
106
|
-
- `CCG_CODEX_MODEL`/`CCG_GEMINI_MODEL` explicit overrides
|
|
107
|
-
- `ccg_codex` passes `-m <model>` when set
|
|
108
|
-
- LICENSE (MIT), CHANGELOG, scripts/install.sh
|
|
109
|
-
- 86-test regression in `tests/test_ccg.sh`
|
|
110
|
-
|
|
111
|
-
### Fixed
|
|
112
|
-
- **CRITICAL**: pure-bash timeout fallback lost stdin in async children. Real Codex/Gemini stdin delivery now works in all bash modes via explicit `<&0`.
|
|
113
|
-
- Timeout polling granularity: 1s → 0.1s + wall-clock deadline for sub-second responsiveness.
|
|
114
|
-
- Orphan sweep threshold: 60min → 1440min (24h).
|
|
115
|
-
- `eval`-safety for any printed shell-meta in mode descriptions.
|
|
116
|
-
|
|
117
|
-
## [0.x] — pre-release
|
|
118
|
-
|
|
119
|
-
Initial two-file plugin (commands/ccg.md + commands/ccg.sh).
|
package/README.ja.md
DELETED
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
# ccg — Code Divergence Detector
|
|
2
|
-
|
|
3
|
-
> Claude Code のスラッシュコマンド。一度インストールして、diff の上で `/ccg` と入力するだけ。
|
|
4
|
-
|
|
5
|
-
[]()
|
|
6
|
-
[](https://www.npmjs.com/package/@mcgrapeng/ccg)
|
|
7
|
-
[](LICENSE)
|
|
8
|
-
|
|
9
|
-
[English](README.md) | [简体中文](README.zh-CN.md) | **日本語** | [한국어](README.ko.md) · [アーキテクチャ →](docs/ARCHITECTURE.ja.md)
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## ccg とは
|
|
14
|
-
|
|
15
|
-
あなたは `auth/login.go` を編集し終え、マージしようとしています。念のため確認したい。今の選択肢は 3 つしかなく、全て欠点があります:
|
|
16
|
-
|
|
17
|
-
- **単一モデルのレビュー**(Copilot、Cursor `/review`、Aider)は **1 つの視点** しか提供しません。Claude が timing attack を見逃せば、あなたも一緒に見逃します。
|
|
18
|
-
- **複数モデル集約ツール**(zen-mcp-server 等)は意見を **平均化** してしまい、優秀なモデル同士が意見を異にした箇所——人間が本当に助けを必要とする箇所——を覆い隠してしまいます。
|
|
19
|
-
- **手動の二重チェック** は時間が無限にあればやりますが、ありませんね。
|
|
20
|
-
|
|
21
|
-
ccg は Claude Code 用の `/ccg` スラッシュコマンドで、この 3 つを本当に解決します。任意の diff に対して:
|
|
22
|
-
|
|
23
|
-
1. 同じ prompt を **Codex(OpenAI)** と **Gemini(Google)** に並列で送信
|
|
24
|
-
2. **Claude** に両方のレポートを読ませ、**両者が意見を異にした箇所を浮かび上がらせる**——そこが人間の判断が必要な場所
|
|
25
|
-
3. コストを記録、リスクに応じて最安充足モデルを自動選択、過去のレビュー履歴を保持
|
|
26
|
-
|
|
27
|
-
**例え話**:別チームの 2 人のシニアエンジニアに同じ PR をレビューさせ、テックリードに統合させる:「ここは両方同意、ここは意見が分かれた——あなたが決めて、私の見解は以下」。
|
|
28
|
-
|
|
29
|
-
## いつ ccg を使うか
|
|
30
|
-
|
|
31
|
-
トリガーは **領域** ではなく **感覚** です。書き終えた自分の diff を見ながら、心の中で次のように考えていたら、ccg の場面です:
|
|
32
|
-
|
|
33
|
-
| 心の中の独り言 | ccg を使う? |
|
|
34
|
-
|---|---|
|
|
35
|
-
| 「これを間違えたら午前 3 時に呼び出される」 | ✅ Yes |
|
|
36
|
-
| 「これは判断問題 — 明らかに正しい答えはない」 | ✅ Yes |
|
|
37
|
-
| 「誰か他に先に見てほしい」 | ✅ Yes |
|
|
38
|
-
| 「変数の名前を変えただけ」 | ❌ No |
|
|
39
|
-
| 「ドキュメント変更だけ」 | ❌ No |
|
|
40
|
-
| 「単一モデルとストリーミング対話したい」 | ❌ No(CLI を直接使う) |
|
|
41
|
-
|
|
42
|
-
**ドメイン横断の実例** —— auth / 暗号ではないが、すべて「シニア 2 人が意見を異にしうる」瞬間:
|
|
43
|
-
|
|
44
|
-
- **ソーシャルプラットフォーム** —— フィードに新エンゲージメントシグナルを追加して再ランキング · コメントツリー fan-out 戦略 · A/B テストバケッティングロジック · 反スパムレート制限ポリシー · フォロー関係のグラフ DB スキーマ
|
|
45
|
-
- **データ / AI インフラ** —— embedding モデル切替(再インデックスする?) · chunking 戦略変更 · RAG 検索スコアリング · prompt injection 防御レイヤリング
|
|
46
|
-
- **フロントエンド** —— 新ページに SSR vs ISR vs RSC · キャッシュ無効化戦略 · 状態管理リファクタリング · アクセシビリティのトレードオフ
|
|
47
|
-
- **API 設計** —— cursor vs offset ページング · エラーレスポンスモデル · バージョニング方式 · 冪等性キーの扱い
|
|
48
|
-
- **分散システム** —— タイムアウト / 再試行ポリシー · cache TTL vs イベント駆動無効化 · partition tolerance トレードオフ · leader election のセマンティクス
|
|
49
|
-
- **データベース** —— マルチステップマイグレーションの順序 · ホットパスのインデックス選択 · トランザクション分離レベル · 論理削除 vs 物理削除
|
|
50
|
-
- **セキュリティ** —— ええ、auth / 暗号 / 決済もここ —— ただし多くのドメインの 1 つに過ぎない
|
|
51
|
-
|
|
52
|
-
**パターン**:「妥当なエンジニアが選択肢 A を選ぶこともあれば、別の妥当なエンジニアが B を選ぶこともある」変更 —— これが分岐検出が $0.04 を稼ぐ瞬間。
|
|
53
|
-
|
|
54
|
-
## なぜ ccg なのか(他ツールとの比較)
|
|
55
|
-
|
|
56
|
-
**1. 意見の相違こそがシグナル、ノイズではない。**
|
|
57
|
-
Codex が「`subtle.ConstantTimeCompare` を使え」と言い、Gemini が「bcrypt は既に恒定時間、それは cargo-cult」と言った時、**そここそ考える必要がある場所**。他のツールはこれを「timing attack に注意」とぼやかして混ぜます。ccg は両者の生の言葉を見せます。
|
|
58
|
-
|
|
59
|
-
**2. コスト可視化が組み込み。**
|
|
60
|
-
Codex / Gemini CLI は支出を教えません。ccg は全呼び出しを記録、リスクに応じて最安充足モデルを自動選択(リスクルーティング)、同一プロンプトは 24h キャッシュでゼロコスト。`ccg_usage --this-month` が「今月いくら使った?」に即答。
|
|
61
|
-
|
|
62
|
-
**3. セッションを跨いで残るレビュー履歴。**
|
|
63
|
-
「2 週間前、モデルは `src/auth.ts` について何と言ったか?」——ccg の追記専用台帳がこれに答えます。ステートレスなツールには不可能です。
|
|
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="<your-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
|
-
// 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
|
-
Claude Code を開いて入力:
|
|
106
|
-
|
|
107
|
-
```
|
|
108
|
-
/ccg
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
約 30 秒後に表示されるもの——**実際の出力例**、プレースホルダーではない:
|
|
112
|
-
|
|
113
|
-
```
|
|
114
|
-
📍 範囲:worktree · 1 ファイル · +4 -1 行
|
|
115
|
-
🎯 モード:quality (risk=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: 「bcrypt を使っても timing attack を防ぐため
|
|
127
|
-
subtle.ConstantTimeCompare でラップせよ」
|
|
128
|
-
🟢 Gemini:「bcrypt.CompareHashAndPassword は既に恒定時間。
|
|
129
|
-
ラッピングは cargo-cult、長さ不一致 panic を生み得る」
|
|
130
|
-
⚖️ Claude: Gemini が正しい。bcrypt.CompareHashAndPassword が標準的な
|
|
131
|
-
比較方法;その生の出力に対する ConstantTimeCompare は
|
|
132
|
-
カテゴリ誤り——「ハッシュした pw」と「保存されたハッシュ」を
|
|
133
|
-
比較しているが、bcrypt は毎回新しいソルトを使うので
|
|
134
|
-
直接比較は常に false を返す。
|
|
135
|
-
➡️ アクション:ConstantTimeCompare 行を以下に置換:
|
|
136
|
-
`err := bcrypt.CompareHashAndPassword(u.Hash, []byte(pw))`
|
|
137
|
-
`return err == nil`
|
|
138
|
-
|
|
139
|
-
═══ BLINDSPOT (1) — どちらも見ていないが Claude が疑う ═══
|
|
140
|
-
• エラーパス:bcrypt エラー時に false を返すのは呼び出し側には正しいが、
|
|
141
|
-
インフラエラー(bcrypt OOM 等)を静かに飲み込む。ログを追加せよ。
|
|
142
|
-
|
|
143
|
-
═══ VERDICT: fix-required ═══
|
|
144
|
-
現在の比較ロジックは正しいパスワードを常に拒否する。DIVERGENCE の
|
|
145
|
-
アクションを適用 + エラーログ追加で、マージ可能。
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### この出力をどう読むか
|
|
149
|
-
|
|
150
|
-
| セクション | 意味 | 何をすべきか |
|
|
151
|
-
|---|---|---|
|
|
152
|
-
| **AGREEMENT** | Codex と Gemini の両方が同じ問題を指摘。単一の Claude でも見つかる可能性が高い——**新規情報量低**。 | 流し読み、未修正なら修正。 |
|
|
153
|
-
| **DIVERGENCE** ★ | 両モデルが意見不一致。**これが ccg の存在意義**。Claude の「アクション」行が推奨をくれるが、最終判断はあなた。 | 注意深く読む、Claude の判断を受け入れるかオーバーライド。 |
|
|
154
|
-
| **BLINDSPOT** | どちらのモデルも気付かなかったが Claude が合成時に疑った。**控えめに**——1 回あたり最大 2 件。 | ヒントとして扱う、聖典ではない。 |
|
|
155
|
-
| **VERDICT** | `merge` / `fix-required` / `discuss`。1 行サマリー。 | マージゲートとして使用。 |
|
|
156
|
-
|
|
157
|
-
レビュー後、`ccg_ledger_record` が JSONL 1 行を台帳に書きます。2 週間後:
|
|
158
|
-
|
|
159
|
-
```bash
|
|
160
|
-
source ~/.claude/commands/ccg.sh
|
|
161
|
-
ccg_ledger_query "auth/login.go"
|
|
162
|
-
# → "auth/login.go: 3 レビュー · 最新 2026-05-23 (fix-required) · 2026-05-09 (merge) · 2026-04-28 (discuss)"
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
## 設定(デフォルトで通常は十分)
|
|
166
|
-
|
|
167
|
-
モードとモデルの選択は自動です。必要なときだけ上書き:
|
|
168
|
-
|
|
169
|
-
```bash
|
|
170
|
-
CCG_MODE=quality /ccg # 任意の diff で quality モデルを強制
|
|
171
|
-
CCG_CODEX_MODEL=o3 /ccg # 1 つのモデルだけ上書き
|
|
172
|
-
CCG_NO_CACHE=1 /ccg # この呼び出しのみ 24h キャッシュをスキップ
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
よく使うもの(全部は [アーキテクチャ §5](docs/ARCHITECTURE.ja.md#5-拡張ポイント)):
|
|
176
|
-
|
|
177
|
-
| 変数 | デフォルト | 用途 |
|
|
178
|
-
|---|---|---|
|
|
179
|
-
| `CCG_MODE` | `auto` | `auto` / `cost` / `balanced` / `quality` |
|
|
180
|
-
| `CCG_CACHE_TTL_HOURS` | `24` | キャッシュ TTL |
|
|
181
|
-
| `CCG_MAX_PROMPT_KB` | `100` | 1 回あたりのプロンプトサイズ上限 |
|
|
182
|
-
|
|
183
|
-
コスト目安(USD / 呼び出し、キャッシュヒット後):
|
|
184
|
-
|
|
185
|
-
| モード | Codex | Gemini | 標準コスト |
|
|
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
|
-
累計支出はいつでも確認可能:
|
|
192
|
-
|
|
193
|
-
```bash
|
|
194
|
-
source ~/.claude/commands/ccg.sh
|
|
195
|
-
ccg_usage --this-month
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
## 適さない用途
|
|
199
|
-
|
|
200
|
-
- Claude Code 以外の IDE([zen-mcp-server](https://github.com/BeehiveInnovations/zen-mcp-server) を試してください)
|
|
201
|
-
- 静的解析の置き換え(Semgrep / CodeQL と併用してください)
|
|
202
|
-
- 全 PR で自動実行(ccg はトリアージツール、ボットではありません)
|
|
203
|
-
- ストリーミング出力やマルチターン会話
|
|
204
|
-
|
|
205
|
-
## アーキテクチャとコントリビュート
|
|
206
|
-
|
|
207
|
-
ccg は **7 層** で構成されており、「分岐検出」は最上位 1 層にすぎません。下の 6 層(キャッシュ、台帳、使用量、リスクルーティング、スマート diff、安全な CLI スケジューリング)はそれぞれ独立して実問題を解決します。`ccg.sh` を変更する前に [docs/ARCHITECTURE.ja.md](docs/ARCHITECTURE.ja.md) を読んでください。
|
|
208
|
-
|
|
209
|
-
テスト:
|
|
210
|
-
|
|
211
|
-
```bash
|
|
212
|
-
bash tests/test_ccg.sh # 99 個の回帰テスト、~31s
|
|
213
|
-
REAL_CLI=1 bash tests/test_ccg.sh # +2 個のライブ API テスト(課金あり)
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
## ライセンスと謝辞
|
|
217
|
-
|
|
218
|
-
MIT —— [LICENSE](LICENSE) を参照。
|
|
219
|
-
|
|
220
|
-
[oh-my-claudecode](https://github.com/Yeachan-Heo/oh-my-claudecode) の元々の `/ccg` コンセプト · Claude Code · OpenAI Codex CLI · Google Gemini CLI を基に構築。
|