Skip to main content

claude-hook

Claude Code commit-time hook lifecycle and runtime.

Use claude-hook install to wire repotoire into Claude Code's PreToolUse hook. The hook runs repotoire diff HEAD before each git commit and blocks on new critical/high findings. claude-hook run is the hook itself (hidden, used internally).

Overview

The repotoire claude-hook command manages a Claude Code PreToolUse hook scoped to the Bash matcher. Whenever Claude Code is about to invoke a Bash tool call, the hook runs; if the staged action is a git commit, repotoire reads the staged diff via repotoire diff HEAD, attributes findings to changed hunks, and denies the commit when new critical or high-severity findings appear in your hunks.

Usage: repotoire claude-hook [OPTIONS] [PATH] <COMMAND>

Commands:
  install    Install the Claude Code commit-time check
  uninstall  Remove the Claude Code commit-time check from settings.json
  help       Print this message or the help of the given subcommand(s)

Examples:
  repotoire claude-hook install        Wire the hook into ~/.claude/settings.json
  repotoire claude-hook uninstall      Remove the hook from settings.json
  repotoire claude-hook install --allow-dev-binary    Allow installing a target/debug build (rare)

Install

Wire the hook into Claude Code's settings. The command is idempotent — re-running it will not duplicate entries, and existing settings keys are preserved.

repotoire claude-hook install
Usage: repotoire claude-hook install [OPTIONS] [PATH]

Options:
      --allow-dev-binary    Allow installing with a dev binary (target/debug/ or target/release/). Off by default

Verified install output:

✓ Hook installed: repotoire claude-hook run
✓ Created: ~/.claude/settings.json
ℹ Run `repotoire analyze` to seed the diff baseline; the hook stays silent until then.
ℹ If you have Claude Code open, restart it to pick up the new hook.
ℹ Uninstall: repotoire claude-hook uninstall

Tip: run repotoire analyze . once before relying on the hook. The hook compares against the prior analyze snapshot, so without a baseline it has nothing to diff against.

What gets written

Install writes a single PreToolUse entry to ~/.claude/settings.json (or $CLAUDE_CONFIG_DIR/settings.json if set). Existing settings keys outside of this entry are left untouched.

{
  "hooks": {
    "PreToolUse": [
      {
        "hooks": [{ "command": "repotoire claude-hook run", "type": "command" }],
        "matcher": "Bash"
      }
    ]
  }
}

The matcher "Bash" scopes the hook to Claude Code's Bash tool calls. The hook itself parses stdin to detect git commit and short-circuits for any other Bash invocation.

Behavior

When Claude Code is about to run a Bash tool call:

  1. Claude Code pipes the pending tool input to repotoire claude-hook run on stdin.
  2. If the command is not a git commit, the hook exits silently and allows the call.
  3. If it is a git commit, the hook runs repotoire diff HEAD against the working tree.
  4. diff parses git diff -U0 and attributes findings to changed hunks (hunk-level attribution).
  5. If any new critical or high findings land inside changed hunks, the hook denies the tool call. Otherwise, it returns a brief score line and allows the commit.

Because attribution is hunk-level, pre-existing tech debt in unrelated parts of the file does not block your commit — only what your change introduces.

Bypass

For emergency overrides, use git's standard escape hatch:

git commit --no-verify -m "hotfix: ..."

--no-verify skips client-side hooks, including any tool-mediated checks Claude Code is gating with this hook.

Uninstall

Remove the Repotoire entry from settings.json. Unrelated PreToolUse entries are preserved.

repotoire claude-hook uninstall
Remove the Claude Code commit-time check from settings.json.
Leaves unrelated PreToolUse entries untouched.

Verified uninstall output:

✓ Uninstalled. Removed 1 hook entry.

Troubleshooting

Installing from a dev build

By default, install refuses to wire up a binary that lives under target/debug/ or target/release/ — those binaries are unstable and tied to a specific checkout. If you really do want to install a dev binary (typically when iterating on the hook itself):

repotoire claude-hook install --allow-dev-binary

Custom Claude config directory

Claude Code honors the CLAUDE_CONFIG_DIR environment variable. If you set it, repotoire writes to $CLAUDE_CONFIG_DIR/settings.json instead of ~/.claude/settings.json. Both install and uninstall respect this override.

CLAUDE_CONFIG_DIR=/path/to/config repotoire claude-hook install

Hook is silent

The hook intentionally stays silent until you have an analyze baseline. Run repotoire analyze . once at the repo root to seed the diff baseline; subsequent commits will be checked against it.

Restart Claude Code

If Claude Code was running when you installed the hook, restart it so the new settings.json is picked up.

See also