Files
claude-foundations/HOOKS.md
Paul O'Reilly d3a92326de Add composable multi-language linting and formatting system
PostToolUse hook auto-formats files after Edit/Write/MultiEdit with
git-blob checkpoints for safe revert. Pre-commit hook for staged files.
Canonical formatter scripts for py, sh, ts, sql, json (+ symlinks for
js, yaml, md). Install and setup scripts for project opt-in.

Includes best-practices/linting.md, HOOKS.md docs, README.md, and
session log.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 11:50:36 +13:00

3.6 KiB

Hooks

Claude Code hooks that run automatically in response to events. Source of truth lives here; symlinks point from ~/.claude/hooks/ back to this directory.

Available Hooks

Hook Event File
Pre-compact backup PreCompact (auto + manual) hooks/pre-compact-backup.sh
Post-edit lint PostToolUse (Edit/Write/MultiEdit) hooks/post-edit-lint.sh
Pre-commit lint Git pre-commit hooks/pre-commit-lint.sh

Post-edit Lint

Formats and lints files after every Edit/Write/MultiEdit. Dispatches to project-local formatters/ directory (symlinks to claude-foundations/formatters/).

Flow:

  1. Extracts file_path and cwd from stdin JSON
  2. Walks up from cwd to find formatters/ directory
  3. Creates a git hash-object checkpoint (.pre-lint file with blob SHA)
  4. Runs the matching formatter script
  5. On clean pass: removes checkpoint, exits 0 (silent)
  6. On lint errors: keeps checkpoint, exits 2 (feeds errors back to Claude via stderr)

Requires: python3 (for JSON parsing from stdin). Formatter tools are optional — missing tools silently pass.

Revert: git cat-file blob $(cat <file>.pre-lint) > <file>

Pre-commit Lint

Git pre-commit hook that runs project formatters on staged files. Reuses the same formatter scripts.

Flow: iterates staged files → runs matching formatter → re-stages formatted files → exits non-zero if lint errors remain (blocks commit).

Install: symlink .git/hooks/pre-commitpre-commit-lint.sh, or use scripts/setup-formatters.sh.

Pre-compact Backup

Saves a copy of the session transcript before context compaction so no conversation history is lost. Backs up to ~/.claude/transcript-backups/ with timestamped filenames. Auto-prunes backups older than 30 days.

Triggers: Both auto-compaction (context window full) and manual (/compact command).

Requires: python3 (for JSON parsing from stdin).

Installation

The easiest way is to run the install script:

cd ~/dev/claude/projects/claude-foundations
scripts/install-hooks.sh

This symlinks all hooks into ~/.claude/hooks/ and prints the settings.json config to add.

Manual installation

  1. Symlink each hook into ~/.claude/hooks/:

    mkdir -p ~/.claude/hooks
    ln -sf "$(pwd)/hooks/pre-compact-backup.sh" ~/.claude/hooks/pre-compact-backup.sh
    ln -sf "$(pwd)/hooks/post-edit-lint.sh" ~/.claude/hooks/post-edit-lint.sh
    ln -sf "$(pwd)/hooks/pre-commit-lint.sh" ~/.claude/hooks/pre-commit-lint.sh
    
  2. Add the hook configuration to ~/.claude/settings.json:

    {
      "hooks": {
        "PreCompact": [
          {
            "matcher": "auto",
            "hooks": [{ "type": "command", "command": "~/.claude/hooks/pre-compact-backup.sh", "timeout": 15, "statusMessage": "Backing up transcript before compaction..." }]
          },
          {
            "matcher": "manual",
            "hooks": [{ "type": "command", "command": "~/.claude/hooks/pre-compact-backup.sh", "timeout": 15, "statusMessage": "Backing up transcript before compaction..." }]
          }
        ],
        "PostToolUse": [
          {
            "matcher": "Edit|Write|MultiEdit",
            "hooks": [{ "type": "command", "command": "~/.claude/hooks/post-edit-lint.sh", "timeout": 30, "statusMessage": "Formatting and linting..." }]
          }
        ]
      }
    }
    
  3. For per-project formatters, run:

    scripts/setup-formatters.sh <project-dir> <ext> [<ext> ...]
    

Adding New Hooks

  1. Create the script in hooks/
  2. Add an entry to this file
  3. Symlink into ~/.claude/hooks/
  4. Add the matcher config to ~/.claude/settings.json