From bb86db711b0ccfc1cbabe954cfab11feaf7294d9 Mon Sep 17 00:00:00 2001 From: carlos-alm <127798846+carlos-alm@users.noreply.github.com> Date: Mon, 2 Mar 2026 19:58:10 -0700 Subject: [PATCH] chore: add pre-commit diff-impact hook MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add show-diff-impact.sh that automatically runs `codegraph diff-impact --staged -T` before git commit commands. The hook injects blast radius info as additionalContext — informational only, never blocks commits. --- .claude/hooks/show-diff-impact.sh | 70 +++++++++++++++++++++++++++++++ .claude/settings.json | 5 +++ 2 files changed, 75 insertions(+) create mode 100644 .claude/hooks/show-diff-impact.sh diff --git a/.claude/hooks/show-diff-impact.sh b/.claude/hooks/show-diff-impact.sh new file mode 100644 index 00000000..e3c583f7 --- /dev/null +++ b/.claude/hooks/show-diff-impact.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +# show-diff-impact.sh — PreToolUse hook for Bash (git commit) +# Runs `codegraph diff-impact --staged -T` before commits and injects +# the impact summary as additionalContext. Informational only — never blocks. + +set -euo pipefail + +INPUT=$(cat) + +# Extract the command from tool_input JSON +COMMAND=$(echo "$INPUT" | node -e " + let d=''; + process.stdin.on('data',c=>d+=c); + process.stdin.on('end',()=>{ + const p=JSON.parse(d).tool_input?.command||''; + if(p)process.stdout.write(p); + }); +" 2>/dev/null) || true + +if [ -z "$COMMAND" ]; then + exit 0 +fi + +# Only trigger on git commit commands +if ! echo "$COMMAND" | grep -qE '(^|\s|&&\s*)git\s+commit\b'; then + exit 0 +fi + +# Guard: codegraph DB must exist +WORK_ROOT=$(git rev-parse --show-toplevel 2>/dev/null) || WORK_ROOT="${CLAUDE_PROJECT_DIR:-.}" +if [ ! -f "$WORK_ROOT/.codegraph/graph.db" ]; then + exit 0 +fi + +# Guard: must have staged changes +STAGED=$(git diff --cached --name-only 2>/dev/null) || true +if [ -z "$STAGED" ]; then + exit 0 +fi + +# Run diff-impact and capture output +IMPACT=$(node "$WORK_ROOT/src/cli.js" diff-impact --staged -T 2>/dev/null) || true + +if [ -z "$IMPACT" ]; then + exit 0 +fi + +# Escape for JSON embedding +ESCAPED=$(printf '%s' "$IMPACT" | node -e " + let d=''; + process.stdin.on('data',c=>d+=c); + process.stdin.on('end',()=>process.stdout.write(JSON.stringify(d))); +" 2>/dev/null) || true + +if [ -z "$ESCAPED" ]; then + exit 0 +fi + +# Inject as additionalContext — never block +node -e " + console.log(JSON.stringify({ + hookSpecificOutput: { + hookEventName: 'PreToolUse', + permissionDecision: 'allow', + additionalContext: '[codegraph diff-impact] Pre-commit blast radius:\\n' + JSON.parse(process.argv[1]) + } + })); +" "$ESCAPED" 2>/dev/null || true + +exit 0 diff --git a/.claude/settings.json b/.claude/settings.json index 9d7e609b..4ffe2530 100644 --- a/.claude/settings.json +++ b/.claude/settings.json @@ -13,6 +13,11 @@ "type": "command", "command": "bash \"$CLAUDE_PROJECT_DIR/.claude/hooks/guard-git.sh\"", "timeout": 10 + }, + { + "type": "command", + "command": "bash \"$CLAUDE_PROJECT_DIR/.claude/hooks/show-diff-impact.sh\"", + "timeout": 15 } ] },