@mcgrapeng/ccg 3.1.0 → 4.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/.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/.plan.md +62 -0
- package/README.md +637 -140
- 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 +491 -0
- package/ccg-workflow.sh +1108 -0
- package/ccg.md +290 -50
- package/ccg.sh +2964 -114
- 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 +443 -0
- package/docs/README.ko.md +442 -0
- package/docs/README.zh-CN.md +512 -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/curl-install.sh
CHANGED
|
@@ -3,22 +3,19 @@
|
|
|
3
3
|
#
|
|
4
4
|
# Usage:
|
|
5
5
|
# curl -fsSL https://raw.githubusercontent.com/mcgrapeng/ccg/main/scripts/curl-install.sh | bash
|
|
6
|
-
# curl -fsSL
|
|
6
|
+
# curl -fsSL ... | bash -s -- --version v3.2.0
|
|
7
7
|
#
|
|
8
|
-
#
|
|
9
|
-
#
|
|
10
|
-
# 2. Extracts ccg.sh + ccg.md into ~/.claude/commands/
|
|
11
|
-
# 3. Runs preflight checks (Codex / Gemini / API key)
|
|
8
|
+
# Defaults to jsdelivr CDN for cross-region reliability (especially mainland China),
|
|
9
|
+
# falls back to raw.githubusercontent.com if jsdelivr is unreachable.
|
|
12
10
|
#
|
|
13
|
-
# No npm / Node.js required. Just bash + curl
|
|
11
|
+
# No npm / Node.js required. Just bash + curl.
|
|
14
12
|
set -eu
|
|
15
13
|
|
|
16
14
|
REPO="${CCG_REPO_OVERRIDE:-mcgrapeng/ccg}"
|
|
17
15
|
TAG="${CCG_VERSION:-latest}"
|
|
18
16
|
TARGET_DIR="${HOME}/.claude/commands"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
trap cleanup EXIT
|
|
17
|
+
|
|
18
|
+
CURL_OPTS="-fsSL --connect-timeout 15 --max-time 120 --retry 2 --retry-delay 2"
|
|
22
19
|
|
|
23
20
|
# parse flags
|
|
24
21
|
while [ $# -gt 0 ]; do
|
|
@@ -29,56 +26,132 @@ while [ $# -gt 0 ]; do
|
|
|
29
26
|
cat <<EOF
|
|
30
27
|
Usage: install.sh [--version <tag>]
|
|
31
28
|
|
|
32
|
-
Installs the /ccg slash command into ~/.claude/commands/ from GitHub
|
|
29
|
+
Installs the /ccg slash command into ~/.claude/commands/ from GitHub
|
|
30
|
+
(via jsdelivr CDN by default; falls back to raw.githubusercontent.com).
|
|
33
31
|
|
|
34
32
|
Options:
|
|
35
33
|
--version <tag> Install a specific release (default: latest)
|
|
36
|
-
Example: --version v3.
|
|
34
|
+
Example: --version v3.2.0
|
|
37
35
|
|
|
38
36
|
Environment:
|
|
39
37
|
CCG_REPO_OVERRIDE Override repo (default: mcgrapeng/ccg)
|
|
38
|
+
CCG_NO_CDN=1 Skip jsdelivr; use raw.githubusercontent.com only
|
|
40
39
|
EOF
|
|
41
40
|
exit 0 ;;
|
|
42
41
|
*) echo "Unknown flag: $1" >&2; exit 2 ;;
|
|
43
42
|
esac
|
|
44
43
|
done
|
|
45
44
|
|
|
46
|
-
# Resolve "latest" → actual tag via GitHub API
|
|
45
|
+
# Resolve "latest" → actual tag via GitHub API
|
|
46
|
+
# (api.github.com is usually reachable even when github.com archive is slow)
|
|
47
47
|
if [ "$TAG" = "latest" ]; then
|
|
48
48
|
echo "→ Resolving latest release of $REPO ..."
|
|
49
49
|
if command -v jq >/dev/null 2>&1; then
|
|
50
|
-
TAG=$(curl
|
|
50
|
+
TAG=$(curl $CURL_OPTS "https://api.github.com/repos/$REPO/releases/latest" | jq -r .tag_name)
|
|
51
51
|
else
|
|
52
|
-
TAG=$(curl
|
|
52
|
+
TAG=$(curl $CURL_OPTS "https://api.github.com/repos/$REPO/releases/latest" \
|
|
53
53
|
| grep -E '"tag_name"' | head -1 | sed -E 's/.*"tag_name":[[:space:]]*"([^"]+)".*/\1/')
|
|
54
54
|
fi
|
|
55
|
-
[ -
|
|
55
|
+
if [ -z "$TAG" ] || [ "$TAG" = "null" ]; then
|
|
56
|
+
echo "FATAL: could not resolve latest release tag" >&2
|
|
57
|
+
echo " Try: bash -s -- --version v3.2.0" >&2
|
|
58
|
+
exit 2
|
|
59
|
+
fi
|
|
56
60
|
fi
|
|
57
61
|
echo "→ Installing $REPO@$TAG"
|
|
58
62
|
|
|
59
|
-
|
|
60
|
-
|
|
63
|
+
# Download a single file. Tries jsdelivr first (fast in mainland China + global CDN),
|
|
64
|
+
# then falls back to raw.githubusercontent.com.
|
|
65
|
+
download_file() {
|
|
66
|
+
rel_path="$1"
|
|
67
|
+
dest="$2"
|
|
68
|
+
|
|
69
|
+
if [ "${CCG_NO_CDN:-0}" != "1" ]; then
|
|
70
|
+
url="https://cdn.jsdelivr.net/gh/$REPO@$TAG/$rel_path"
|
|
71
|
+
echo " → $url"
|
|
72
|
+
if curl $CURL_OPTS -o "$dest" "$url" 2>/dev/null; then
|
|
73
|
+
return 0
|
|
74
|
+
fi
|
|
75
|
+
echo " (jsdelivr failed, trying raw.githubusercontent.com)"
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
url="https://raw.githubusercontent.com/$REPO/$TAG/$rel_path"
|
|
79
|
+
echo " → $url"
|
|
80
|
+
if curl $CURL_OPTS -o "$dest" "$url" 2>/dev/null; then
|
|
81
|
+
return 0
|
|
82
|
+
fi
|
|
83
|
+
|
|
84
|
+
return 1
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
# Use a non-standard variable name to avoid polluting the global TMPDIR
|
|
88
|
+
# which other tools (including ccg.sh itself) depend on.
|
|
89
|
+
CCG_INSTALL_TMPDIR="$(mktemp -d -t ccg-install.XXXXXXXX)"
|
|
90
|
+
TMPDIR="$CCG_INSTALL_TMPDIR"
|
|
91
|
+
trap 'rm -rf "$CCG_INSTALL_TMPDIR"' EXIT
|
|
92
|
+
|
|
93
|
+
echo "→ Downloading ccg.sh"
|
|
94
|
+
if ! download_file "ccg.sh" "$TMPDIR/ccg.sh"; then
|
|
95
|
+
echo "FATAL: could not download ccg.sh from any source" >&2
|
|
96
|
+
echo " Network issue? Try setting a proxy or use:" >&2
|
|
97
|
+
echo " CCG_NO_CDN=1 bash -s -- --version $TAG" >&2
|
|
98
|
+
exit 2
|
|
99
|
+
fi
|
|
61
100
|
|
|
62
|
-
echo "→ Downloading
|
|
63
|
-
|
|
101
|
+
echo "→ Downloading ccg.md"
|
|
102
|
+
if ! download_file "ccg.md" "$TMPDIR/ccg.md"; then
|
|
103
|
+
echo "FATAL: could not download ccg.md from any source" >&2
|
|
104
|
+
exit 2
|
|
105
|
+
fi
|
|
64
106
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
107
|
+
# Sanity check downloaded files
|
|
108
|
+
[ -s "$TMPDIR/ccg.sh" ] || { echo "FATAL: ccg.sh downloaded but empty" >&2; exit 2; }
|
|
109
|
+
[ -s "$TMPDIR/ccg.md" ] || { echo "FATAL: ccg.md downloaded but empty" >&2; exit 2; }
|
|
110
|
+
head -1 "$TMPDIR/ccg.sh" | grep -q '^#!' \
|
|
111
|
+
|| { echo "FATAL: ccg.sh doesn't look like a shell script" >&2; exit 2; }
|
|
69
112
|
|
|
70
|
-
|
|
71
|
-
|
|
113
|
+
# Integrity check: verify SHA-256 checksums against GitHub release assets if available.
|
|
114
|
+
# This prevents CDN poisoning or MITM attacks from executing arbitrary code.
|
|
115
|
+
echo "→ Verifying integrity..."
|
|
116
|
+
_ccg_install_verify_checksum() {
|
|
117
|
+
local file="$1"
|
|
118
|
+
local checksum_url="https://raw.githubusercontent.com/$REPO/$TAG/scripts/checksums.sha256"
|
|
119
|
+
local checksums
|
|
120
|
+
if checksums=$(curl -fsSL --connect-timeout 10 --max-time 30 "$checksum_url" 2>/dev/null); then
|
|
121
|
+
local expected
|
|
122
|
+
expected=$(printf '%s\n' "$checksums" | grep "$(basename "$file")" | awk '{print $1}')
|
|
123
|
+
if [ -n "$expected" ]; then
|
|
124
|
+
local actual
|
|
125
|
+
if command -v shasum >/dev/null 2>&1; then
|
|
126
|
+
actual=$(shasum -a 256 "$file" | awk '{print $1}')
|
|
127
|
+
elif command -v sha256sum >/dev/null 2>&1; then
|
|
128
|
+
actual=$(sha256sum "$file" | awk '{print $1}')
|
|
129
|
+
fi
|
|
130
|
+
if [ -n "$actual" ] && [ "$actual" != "$expected" ]; then
|
|
131
|
+
echo "FATAL: checksum mismatch for $(basename "$file")" >&2
|
|
132
|
+
echo " expected: $expected" >&2
|
|
133
|
+
echo " actual: $actual" >&2
|
|
134
|
+
echo " This may indicate a compromised download. Aborting." >&2
|
|
135
|
+
return 1
|
|
136
|
+
fi
|
|
137
|
+
fi
|
|
138
|
+
fi
|
|
139
|
+
# If checksums file is not available (older releases), proceed with a warning
|
|
140
|
+
return 0
|
|
141
|
+
}
|
|
142
|
+
_ccg_install_verify_checksum "$TMPDIR/ccg.sh" || exit 2
|
|
143
|
+
_ccg_install_verify_checksum "$TMPDIR/ccg.md" || exit 2
|
|
72
144
|
|
|
73
145
|
echo "→ Installing to $TARGET_DIR"
|
|
74
146
|
mkdir -p "$TARGET_DIR"
|
|
75
|
-
install -m 0755 "$
|
|
76
|
-
install -m 0644 "$
|
|
147
|
+
install -m 0755 "$TMPDIR/ccg.sh" "$TARGET_DIR/ccg.sh"
|
|
148
|
+
install -m 0644 "$TMPDIR/ccg.md" "$TARGET_DIR/ccg.md"
|
|
77
149
|
echo " ✓ $TARGET_DIR/ccg.sh"
|
|
78
150
|
echo " ✓ $TARGET_DIR/ccg.md"
|
|
79
151
|
|
|
80
152
|
echo
|
|
81
153
|
echo "→ Preflight checks:"
|
|
154
|
+
# shellcheck disable=SC1091
|
|
82
155
|
. "$TARGET_DIR/ccg.sh"
|
|
83
156
|
out=$(ccg_preflight)
|
|
84
157
|
echo "$out" | sed 's/^/ /'
|
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).
|