@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/CHANGELOG.md +119 -0
- package/LICENSE +21 -0
- package/README.ja.md +220 -0
- package/README.ko.md +219 -0
- package/README.md +220 -0
- package/README.zh-CN.md +219 -0
- package/bin/ccg.js +391 -0
- package/ccg.md +303 -0
- package/ccg.sh +928 -0
- package/package.json +54 -0
- package/scripts/curl-install.sh +97 -0
- package/scripts/install.sh +55 -0
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mcgrapeng/ccg",
|
|
3
|
+
"version": "3.1.0",
|
|
4
|
+
"description": "Code Divergence Detector for Claude Code — runs Codex + Gemini in parallel on the same diff and surfaces where they disagree.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"claude-code",
|
|
7
|
+
"code-review",
|
|
8
|
+
"codex",
|
|
9
|
+
"gemini",
|
|
10
|
+
"ai",
|
|
11
|
+
"slash-command",
|
|
12
|
+
"cli",
|
|
13
|
+
"divergence",
|
|
14
|
+
"diff"
|
|
15
|
+
],
|
|
16
|
+
"homepage": "https://github.com/mcgrapeng/ccg#readme",
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/mcgrapeng/ccg/issues"
|
|
19
|
+
},
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/mcgrapeng/ccg.git"
|
|
23
|
+
},
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"author": "mcgrapeng",
|
|
26
|
+
"type": "commonjs",
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=16"
|
|
29
|
+
},
|
|
30
|
+
"os": [
|
|
31
|
+
"darwin",
|
|
32
|
+
"linux"
|
|
33
|
+
],
|
|
34
|
+
"bin": {
|
|
35
|
+
"ccg": "bin/ccg.js"
|
|
36
|
+
},
|
|
37
|
+
"main": "bin/ccg.js",
|
|
38
|
+
"files": [
|
|
39
|
+
"bin/",
|
|
40
|
+
"ccg.sh",
|
|
41
|
+
"ccg.md",
|
|
42
|
+
"scripts/",
|
|
43
|
+
"LICENSE",
|
|
44
|
+
"README.md",
|
|
45
|
+
"README.zh-CN.md",
|
|
46
|
+
"README.ja.md",
|
|
47
|
+
"README.ko.md",
|
|
48
|
+
"CHANGELOG.md"
|
|
49
|
+
],
|
|
50
|
+
"scripts": {
|
|
51
|
+
"test": "bash tests/test_ccg.sh",
|
|
52
|
+
"lint:sh": "shellcheck ccg.sh scripts/install.sh || true"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# curl-install.sh — one-line remote installer for /ccg.
|
|
3
|
+
#
|
|
4
|
+
# Usage:
|
|
5
|
+
# curl -fsSL https://raw.githubusercontent.com/mcgrapeng/ccg/main/scripts/curl-install.sh | bash
|
|
6
|
+
# curl -fsSL https://raw.githubusercontent.com/mcgrapeng/ccg/main/scripts/curl-install.sh | bash -s -- --version v3.0.0
|
|
7
|
+
#
|
|
8
|
+
# What it does:
|
|
9
|
+
# 1. Downloads the requested release tarball from GitHub Releases (default: latest)
|
|
10
|
+
# 2. Extracts ccg.sh + ccg.md into ~/.claude/commands/
|
|
11
|
+
# 3. Runs preflight checks (Codex / Gemini / API key)
|
|
12
|
+
#
|
|
13
|
+
# No npm / Node.js required. Just bash + curl + tar.
|
|
14
|
+
set -eu
|
|
15
|
+
|
|
16
|
+
REPO="${CCG_REPO_OVERRIDE:-mcgrapeng/ccg}"
|
|
17
|
+
TAG="${CCG_VERSION:-latest}"
|
|
18
|
+
TARGET_DIR="${HOME}/.claude/commands"
|
|
19
|
+
TMPDIR="$(mktemp -d -t ccg-install.XXXXXXXX)"
|
|
20
|
+
cleanup() { rm -rf "$TMPDIR"; }
|
|
21
|
+
trap cleanup EXIT
|
|
22
|
+
|
|
23
|
+
# parse flags
|
|
24
|
+
while [ $# -gt 0 ]; do
|
|
25
|
+
case "$1" in
|
|
26
|
+
--version) TAG="$2"; shift 2 ;;
|
|
27
|
+
--version=*) TAG="${1#*=}"; shift ;;
|
|
28
|
+
-h|--help)
|
|
29
|
+
cat <<EOF
|
|
30
|
+
Usage: install.sh [--version <tag>]
|
|
31
|
+
|
|
32
|
+
Installs the /ccg slash command into ~/.claude/commands/ from GitHub Releases.
|
|
33
|
+
|
|
34
|
+
Options:
|
|
35
|
+
--version <tag> Install a specific release (default: latest)
|
|
36
|
+
Example: --version v3.0.0
|
|
37
|
+
|
|
38
|
+
Environment:
|
|
39
|
+
CCG_REPO_OVERRIDE Override repo (default: mcgrapeng/ccg)
|
|
40
|
+
EOF
|
|
41
|
+
exit 0 ;;
|
|
42
|
+
*) echo "Unknown flag: $1" >&2; exit 2 ;;
|
|
43
|
+
esac
|
|
44
|
+
done
|
|
45
|
+
|
|
46
|
+
# Resolve "latest" → actual tag via GitHub API (no auth required for public repos)
|
|
47
|
+
if [ "$TAG" = "latest" ]; then
|
|
48
|
+
echo "→ Resolving latest release of $REPO ..."
|
|
49
|
+
if command -v jq >/dev/null 2>&1; then
|
|
50
|
+
TAG=$(curl -fsSL "https://api.github.com/repos/$REPO/releases/latest" | jq -r .tag_name)
|
|
51
|
+
else
|
|
52
|
+
TAG=$(curl -fsSL "https://api.github.com/repos/$REPO/releases/latest" \
|
|
53
|
+
| grep -E '"tag_name"' | head -1 | sed -E 's/.*"tag_name":[[:space:]]*"([^"]+)".*/\1/')
|
|
54
|
+
fi
|
|
55
|
+
[ -n "$TAG" ] && [ "$TAG" != "null" ] || { echo "FATAL: could not resolve latest release tag" >&2; exit 2; }
|
|
56
|
+
fi
|
|
57
|
+
echo "→ Installing $REPO@$TAG"
|
|
58
|
+
|
|
59
|
+
TARBALL_URL="https://github.com/$REPO/archive/refs/tags/$TAG.tar.gz"
|
|
60
|
+
ARCHIVE="$TMPDIR/ccg.tar.gz"
|
|
61
|
+
|
|
62
|
+
echo "→ Downloading $TARBALL_URL"
|
|
63
|
+
curl -fsSL -o "$ARCHIVE" "$TARBALL_URL" || { echo "FATAL: download failed" >&2; exit 2; }
|
|
64
|
+
|
|
65
|
+
echo "→ Extracting"
|
|
66
|
+
tar -xzf "$ARCHIVE" -C "$TMPDIR"
|
|
67
|
+
SRC_DIR=$(find "$TMPDIR" -maxdepth 1 -type d -name 'ccg-*' | head -1)
|
|
68
|
+
[ -d "$SRC_DIR" ] || { echo "FATAL: extracted dir not found" >&2; exit 2; }
|
|
69
|
+
|
|
70
|
+
[ -r "$SRC_DIR/ccg.sh" ] || { echo "FATAL: ccg.sh missing in archive" >&2; exit 2; }
|
|
71
|
+
[ -r "$SRC_DIR/ccg.md" ] || { echo "FATAL: ccg.md missing in archive" >&2; exit 2; }
|
|
72
|
+
|
|
73
|
+
echo "→ Installing to $TARGET_DIR"
|
|
74
|
+
mkdir -p "$TARGET_DIR"
|
|
75
|
+
install -m 0755 "$SRC_DIR/ccg.sh" "$TARGET_DIR/ccg.sh"
|
|
76
|
+
install -m 0644 "$SRC_DIR/ccg.md" "$TARGET_DIR/ccg.md"
|
|
77
|
+
echo " ✓ $TARGET_DIR/ccg.sh"
|
|
78
|
+
echo " ✓ $TARGET_DIR/ccg.md"
|
|
79
|
+
|
|
80
|
+
echo
|
|
81
|
+
echo "→ Preflight checks:"
|
|
82
|
+
. "$TARGET_DIR/ccg.sh"
|
|
83
|
+
out=$(ccg_preflight)
|
|
84
|
+
echo "$out" | sed 's/^/ /'
|
|
85
|
+
|
|
86
|
+
if echo "$out" | grep -q "CCG_PREFLIGHT_CODEX=missing"; then
|
|
87
|
+
echo " ⚠ install: npm i -g @openai/codex"
|
|
88
|
+
fi
|
|
89
|
+
if echo "$out" | grep -q "CCG_PREFLIGHT_GEMINI=missing"; then
|
|
90
|
+
echo " ⚠ install: npm i -g @google/gemini-cli"
|
|
91
|
+
fi
|
|
92
|
+
if echo "$out" | grep -q "CCG_PREFLIGHT_GEMINI=no-api-key"; then
|
|
93
|
+
echo " ⚠ add to ~/.zshenv: export GEMINI_API_KEY=<your-key>"
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
echo
|
|
97
|
+
echo "✓ Installed @ $TAG. Open Claude Code and type: /ccg"
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# install.sh — install /ccg into ~/.claude/commands for Claude Code.
|
|
3
|
+
# Idempotent; safe to re-run for upgrades. Pass --dry-run to preview.
|
|
4
|
+
set -eu
|
|
5
|
+
|
|
6
|
+
DRY=0
|
|
7
|
+
case "${1:-}" in
|
|
8
|
+
--dry-run|-n) DRY=1 ;;
|
|
9
|
+
--help|-h)
|
|
10
|
+
cat <<EOF
|
|
11
|
+
Usage: $0 [--dry-run]
|
|
12
|
+
Installs ccg.md + ccg.sh into ~/.claude/commands/ so /ccg becomes available
|
|
13
|
+
in Claude Code. Also runs preflight checks for Codex CLI / Gemini CLI / API key.
|
|
14
|
+
EOF
|
|
15
|
+
exit 0 ;;
|
|
16
|
+
esac
|
|
17
|
+
|
|
18
|
+
HERE="$(cd "$(dirname "$0")/.." && pwd)"
|
|
19
|
+
CCG_SH="$HERE/ccg.sh"
|
|
20
|
+
CCG_MD="$HERE/ccg.md"
|
|
21
|
+
TARGET_DIR="${HOME}/.claude/commands"
|
|
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; }
|
|
25
|
+
|
|
26
|
+
echo "→ Installing /ccg to: $TARGET_DIR"
|
|
27
|
+
|
|
28
|
+
if [ "$DRY" = "0" ]; then
|
|
29
|
+
mkdir -p "$TARGET_DIR"
|
|
30
|
+
install -m 0755 "$CCG_SH" "$TARGET_DIR/ccg.sh"
|
|
31
|
+
install -m 0644 "$CCG_MD" "$TARGET_DIR/ccg.md"
|
|
32
|
+
echo " ✓ wrote $TARGET_DIR/ccg.sh ($(wc -l <"$CCG_SH" | tr -d ' ') lines)"
|
|
33
|
+
echo " ✓ wrote $TARGET_DIR/ccg.md"
|
|
34
|
+
else
|
|
35
|
+
echo " [dry-run] would write: $TARGET_DIR/{ccg.sh,ccg.md}"
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
echo
|
|
39
|
+
echo "→ Preflight checks:"
|
|
40
|
+
. "$CCG_SH"
|
|
41
|
+
out=$(ccg_preflight)
|
|
42
|
+
echo "$out" | sed 's/^/ /'
|
|
43
|
+
|
|
44
|
+
if echo "$out" | grep -q "CCG_PREFLIGHT_CODEX=missing"; then
|
|
45
|
+
echo " ⚠ install: npm i -g @openai/codex"
|
|
46
|
+
fi
|
|
47
|
+
if echo "$out" | grep -q "CCG_PREFLIGHT_GEMINI=missing"; then
|
|
48
|
+
echo " ⚠ install: npm i -g @google/gemini-cli"
|
|
49
|
+
fi
|
|
50
|
+
if echo "$out" | grep -q "CCG_PREFLIGHT_GEMINI=no-api-key"; then
|
|
51
|
+
echo " ⚠ add to ~/.zshenv: export GEMINI_API_KEY=<your-key>"
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
echo
|
|
55
|
+
echo "→ Done. Open a new Claude Code session and type: /ccg <your task>"
|