Skip to main content

Claude Code and Git hooks

Operate the repository-local Claude Code hooks and distinguish them from Codex hooks. See the examples and checks before applying it.

Integrations

This page documents the .claude/hooks pack in the CodeGraph source checkout. It enriches Claude Code sessions with CPG context around prompts, edits, commands, commits, and the final response. It is a maintainer integration, not the portable customer plugin.

CodeGraph also contains .codex/hooks for Codex. The two directories have different event contracts and are not interchangeable. Customer-facing Codex installation uses the packaged plugin; OpenCode uses opencode-codegraph.

Current registered hooks

.claude/settings.json is the registration source:

Current registered hooks
Claude event Script Purpose
SessionStart session_context.py Detect the active project and report CPG scope/status
UserPromptSubmit enrich_prompt.py Add matching symbols and basic graph facts
PreToolUse pre_tool_use.py Warn before supported Edit/Write operations
PostToolUse on Bash cli_error_monitor.py Explain recognized CLI failures
PostToolUse on Bash commit_analysis.py Analyze a completed Git commit and CPG freshness
Stop post_analysis.py Add final quality warnings for mentioned files

The hooks return context and warnings. Git protection, CI, review, and release gates provide the corresponding controls; an advisory warning records a condition for that workflow.

Installation boundary

The checked-in settings currently contain an absolute maintainer path. Do not copy it unchanged to another workstation. Resolve the checkout path and register each command with the local Python runtime, for example:

{
  "type": "command",
  "command": "python <absolute-repository-path>/.claude/hooks/session_context.py",
  "timeout": 10000
}

Keep .claude/settings.json valid JSON. matcher is a string; the current Bash post-tool hooks use "Bash". Start a new Claude Code session after changing registrations.

Runtime behavior

The hooks read structured JSON from stdin and return Claude-compatible JSON on stdout. CPG queries go through the GoCPG subprocess boundary in .claude/hooks/_utils.py; hook code must not open the project DuckDB directly. Project selection is resolved from the checkout and cached under .claude/.cache.

Metrics are written best-effort to data/hook_metrics.jsonl or the path selected by CODEGRAPH_HOOK_METRICS_FILE. Secret-like fields are redacted, but operators should still protect the log as diagnostic data.

Verify before use

python -m json.tool .claude/settings.json
python -m pytest tests/unit/hooks -q
python -m src.cli review --staged --format json

The first command proves syntax, the tests prove the local hook contracts, and review exercises the current review CLI. None proves that Claude Code loaded the file: start a clean session and observe one SessionStart result and one bounded edit warning.

Git and CPG expectations

commit_analysis.py reacts only after a Bash tool result representing a Git commit. It can refresh or inspect CPG state within its timeout and emit blast-radius or quality findings. A timeout, missing CPG, partial parse scope, or advisory output must be reported explicitly; it must not be translated into a successful review.

Use the canonical review workflow for acceptance decisions:

python -m src.cli review --base-ref origin/main --format json

Troubleshooting and removal

  • No hook output: confirm event registration, absolute path, Python, stdin JSON, and timeout.
  • Wrong project: clear the checkout-local .claude/.cache entry and restart the session.
  • Stale graph: refresh the project through the supported CodeGraph workflow before relying on CPG findings.
  • To remove the integration, delete only the corresponding registrations from the user’s Claude settings. Do not remove .codex/hooks or OpenCode configuration as part of that rollback.

Source of truth

  • Registration: .claude/settings.json
  • Hook implementation: .claude/hooks
  • Separate Codex implementation: .codex/hooks
  • Review workflow: Code review