DEV Community

Cover image for Teaching Claude to Stop Reaching for git diff — git-prism v0.7.0
Mike Lane
Mike Lane

Posted on • Originally published at github.com

Teaching Claude to Stop Reaching for git diff — git-prism v0.7.0

The problem: AI agents and git muscle memory

Claude Code has git-prism registered as an MCP server. Five structured tools: change manifests, function context, file snapshots, commit history, and review diffs. Each one returns parsed, token-efficient JSON instead of raw patch text.

But Claude was trained on millions of git commands. That muscle memory runs deep. Give it a branch to review and it reaches for git diff. Hunk headers, plus and minus prefixes, a format built for humans reading patches in 2005. Registration is not enough.

This is the problem every MCP server author hits: your tools exist, but the model's default instincts predate them.

What v0.7.0 ships

git-prism v0.7.0 ships a bundled Claude Code PreToolUse redirect hook: a bash redirect interceptor that blocks dangerous commands before they reach the shell and nudges benign git porcelain toward structured alternatives.

How the redirect hook works

The hook is a Claude Code PreToolUse program. It reads a JSON payload on stdin describing the tool call about to execute, parses the bash command with Python's shlex tokenizer (not regex; compound commands, subshells, and pipelines all parse structurally), and decides via exit code:

  • Exit 0: pass through silently (vanilla shell commands)
  • Exit 0 + JSON on stdout: advisory. The command runs, but the agent sees a suggestion
  • Exit 2: hard block. The command never reaches the shell

Hard block (exit 2): gh pr diff returns raw GitHub patch text. Not something an agent can act on reliably.

Advisory (exit 0 + JSON): git diff main..HEAD gets a nudge toward get_change_manifest. The command runs, but next time the agent knows the structured path.

Silent (exit 0): echo hello world. No output, no delay, no interference.

The tokenizer is stdlib-only Python: shlex.shlex(posix=True, punctuation_chars=True), zero third-party dependencies. Compound commands split correctly. Subshells are recognized. Heredoc bodies are suppressed so a 200-line heredoc doesn't blow through the tokenizer. Pipeline segments are parsed independently.

Install

git-prism hooks install
Enter fullscreen mode Exit fullscreen mode

It copies the bundled scripts into ~/.claude/hooks/ and writes a PreToolUse entry into Claude Code's settings.json. Works for both top-level agents and custom subagents (default scope is user to dodge a known Claude Code project-scope MCP bug). Re-install is idempotent; git-prism hooks status shows what's installed and at what version.

During development, I tried to run gh pr diff inside a Claude Code session to review a PR. The hook blocked it. I used git-prism manifest instead.

review_change: the agent-native git diff

Alongside the hook, v0.7.0 adds a fifth MCP tool: review_change. It returns a combined { manifest, function_context } payload for a ref range in a single call, splitting the response budget 40/60 between the two halves.

This is the tool the redirect hook points agents toward. Instead of:

git diff main..HEAD   # → 5-50k tokens of unstructured hunk noise
Enter fullscreen mode Exit fullscreen mode

Agents call:

review_change(base_ref="main", head_ref="HEAD")
Enter fullscreen mode Exit fullscreen mode

And get back:

  • Per-file metadata (language, change type, line counts)
  • Function-level diffs (added / deleted / modified / renamed, with body hashes)
  • Callers, callees, and test references per changed function
  • A blast-radius risk score (none / low / medium / high) for every changed function
  • Dependency changes (Cargo.toml, go.mod, package.json, etc.)

Two independent pagination cursors let you advance the halves separately. Paginate the manifest without re-fetching the context, or vice versa.

Guardrails that keep agents from overflowing

LLM context windows are expensive and finite. A raw diff of a large PR easily burns 50k tokens before the agent has read a single source file. v0.7.0 adds response-size guardrails across all read tools:

  • Manifest token budget (default 8192). When the response would exceed the budget, function/import analysis is progressively trimmed per file: full → signatures-only → bare. Pass max_response_tokens: 0 to disable enforcement when you genuinely need the full payload.
  • Function context pagination (default 25 entries per page). Opaque cursor, page-size knob (1–500), and a function_names filter for re-querying specific entries that were clamped on a prior page.
  • Per-entry truncated flags. When an entry gets clamped (top 5 callers, top 5 callees, top 3 test references), its truncated: true flag and a mirrored name in metadata.function_analysis_truncated tell the agent exactly what got cut. No silent data loss.

All internal callers (like get_function_context calling get_change_manifest) bypass the budget so the second-resort tools always get complete data regardless of the user-facing guard.

Breaking changes for 0.7.0

Pre-1.0 semver means breaking changes can land in minor bumps. Two changes from pre-v0.7.0 behavior:

  • get_change_manifest flips the default for include_function_analysis to false. Function-level diffs are now opt-in, matching the tool's "cheapest first-resort" contract. Pass include_function_analysis: true to restore the old behavior.
  • record_truncated metric gains a reason label. Existing dashboards relying on the old label format will need a one-field update. Cardinality is bounded.

Install

brew install mikelane/tap/git-prism
# or
cargo install git-prism
# or
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/mikelane/git-prism/releases/download/v0.7.0/git-prism-installer.sh | sh
Enter fullscreen mode Exit fullscreen mode

Source and docs: github.com/mikelane/git-prism

The full changelog, BDD scenarios (Python/behave, 13-language test matrix), and ADRs are in the repo. v0.7.0 was built across 5 implementation PRs plus 3 dependency bumps. Tagged, released, and on crates.io as of today.

Top comments (0)