Seatbelt for Claude Code

How to stop Claude Code from running git add -A

I had two Claude Code sessions open in the same repo. One was fixing a header, the other was halfway through a refactor. The first one finished, ran git add -A && git commit, and committed half of the refactor with it. Nothing was broken yet, but the history was, and untangling it took longer than the header fix.

My CLAUDE.md already said "add files by name, never git add -A". Claude followed it most of the time. Most of the time is the problem: a rule in a prompt competes with everything else in the context, and on a long session it loses sometimes.

A hook runs every time

Claude Code can run a script before each tool call. If the script exits with code 2, the call is cancelled and whatever the script printed on stderr goes back to Claude as the reason. Claude reads it and changes approach.

Here is the whole hook:

#!/usr/bin/env python3
import json, re, sys

event = json.load(sys.stdin)
cmd = (event.get("tool_input") or {}).get("command", "")
if re.search(r"\bgit\b[^;&|\n]*\badd\b[^;&|\n]*(\s-A\b|\s--all\b|\s\.(\s|$))", cmd):
    print("Seatbelt blocked this command: git add -A / git add . sweeps in .env files "
          "and other sessions' work. "
          "Add files by name.", file=sys.stderr)
    sys.exit(2)

Save it as ~/.claude/hooks/no_add_all.py and register it in ~/.claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [{ "type": "command", "command": "python3 ~/.claude/hooks/no_add_all.py" }]
      }
    ]
  }
}

Restart Claude Code. Next time it tries, you see this:

● Bash(git add -A && git commit -m "fix header spacing")
  ⎿ Seatbelt blocked this command: git add -A / git add . sweeps in
    .env files and other sessions' work. Add files by name.
● Bash(git add src/Header.tsx && git commit -m "fix header spacing")
  ⎿ [main 4e1c9a2] fix header spacing

Three details that matter

The free version

I packaged this one with rm -rf ~ and force push as a plugin: seatbelt-lite, MIT, two commands to install.

The paid kit adds a longer shell list, a guard against API keys in code, a SQL guard for Supabase and a hook that checks deploys before Claude says "it's live": Seatbelt.