Hooks

Two hooks run the aibysitter CLI on rules files: a Git pre-commit hook on staged files, and a Claude Code hook after each edit. Both run offline with the same rules and scoring as the lint page.

CLI

Both hooks need aibysitter on PATH. The CLI is a .NET tool on NuGet:

dotnet tool install --global Aibysitter.Cli

Git pre-commit

Lints the staged content of each staged rules file, not the working copy: CLAUDE.md, AGENTS.md and GEMINI.md in any folder, .github/copilot-instructions.md, .cursorrules, .windsurfrules, and .mdc files under .cursor/rules/. Other files are ignored.

  1. Save pre-commit as .git/hooks/pre-commit.
  2. Make it executable: chmod +x .git/hooks/pre-commit. Git for Windows runs it as is.
Setting Effect
AIBYSITTER_HOOK_ARGS aibysitter lint flags. Default --fail-on-error. Example: --fail-below B --disable R004.
AIBYSITTER CLI command. Default aibysitter.

Before committing, aibysitter fix --dry-run CLAUDE.md shows the R011 and R012 fixes as a diff; aibysitter fix CLAUDE.md applies them.

A failed threshold blocks the commit and prints the findings. Skip once with git commit --no-verify. When the CLI is not found, the hook prints a warning and lets the commit through.

#!/bin/sh
# aibysitter pre-commit hook: lints the staged content of rules files (not the working copy).
# Flags: AIBYSITTER_HOOK_ARGS, default --fail-on-error. CLI command: AIBYSITTER, default aibysitter.
# Skip once: git commit --no-verify. Docs: https://aibysitting.net/Hooks

AIBYSITTER=${AIBYSITTER:-aibysitter}
ARGS=${AIBYSITTER_HOOK_ARGS:---fail-on-error}

# Same paths as RulesFormats.FromFileName.
is_rules_file() {
    case "$1" in
        CLAUDE.md | */CLAUDE.md | AGENTS.md | */AGENTS.md | GEMINI.md | */GEMINI.md) return 0 ;;
        .cursorrules | .windsurfrules | .github/copilot-instructions.md) return 0 ;;
        .cursor/rules/*.mdc | */.cursor/rules/*.mdc) return 0 ;;
    esac
    return 1
}

if ! command -v "$AIBYSITTER" >/dev/null 2>&1; then
    echo "aibysitter pre-commit: '$AIBYSITTER' not found; rules files not linted. Install: https://aibysitting.net/Hooks" >&2
    exit 0
fi

git diff --cached --name-only --diff-filter=ACMR | {
    status=0
    while IFS= read -r path; do
        is_rules_file "$path" || continue
        # shellcheck disable=SC2086
        if ! git show ":$path" | "$AIBYSITTER" lint - --stdin-path "$path" $ARGS; then
            status=1
        fi
    done
    if [ "$status" -ne 0 ]; then
        echo "aibysitter pre-commit: commit blocked. Fix the findings above, or skip once with git commit --no-verify." >&2
    fi
    exit "$status"
}

Claude Code

A PostToolUse hook runs aibysitter hook claude-code after each edit. When the edited file is a rules file with Error or Warning findings, the hook prints them and exits 2, so Claude reads them and fixes the file. Info findings, clean files and other files exit 0. Malformed hook input exits 0.

  1. Merge claude-code-settings.json into .claude/settings.json in the repository, or ~/.claude/settings.json for every project.
  2. Skip rules with aibysitter hook claude-code --disable R004 in the command, or AIBYSITTER_HOOK_ARGS="--disable R004".
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write|MultiEdit",
        "hooks": [
          {
            "type": "command",
            "command": "aibysitter hook claude-code"
          }
        ]
      }
    ]
  }
}

Output sent to Claude for a CLAUDE.md with "Always use tabs." and "Never use tabs.", one line per finding:

aibysitter: CLAUDE.md has 1 finding to fix (score 90/100 A):
CLAUDE.md:3 R003 Error: Contradicts line 2: "use tabs" is both required and forbidden. Fix: Keep one instruction and delete the other.