@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/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>"