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.
- Save pre-commit as
.git/hooks/pre-commit. - 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.
- Merge claude-code-settings.json into
.claude/settings.jsonin the repository, or~/.claude/settings.jsonfor every project. - Skip rules with
aibysitter hook claude-code --disable R004in the command, orAIBYSITTER_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.