Files
claude-foundations/HOOKS.md
Paul O'Reilly c3557a3d97 Add formatters, hooks, memory entries and context-load improvements
- formatters/js, md, yaml: new/updated formatter scripts
- hooks/set-wezterm-profile.sh: new hook for WezTerm profile switching
- scripts/context-load: improvements from recent sessions
- HOOKS.md, MEMORY.md: updated documentation and index entries
- memory/log, memory/reference-infrastructure-docs.md: session logs and reference

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 10:54:49 +13:00

4.4 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
WezTerm profile theme SessionStart (per-profile) hooks/set-wezterm-profile.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> ...]
    

WezTerm Profile Theme

Sets the WezTerm terminal theme when a Claude session starts or resumes, by emitting an OSC 1337 SetUserVar escape sequence. WezTerm fires its user-var-changed Lua event and applies the matching color scheme and background image from wezterm.lua.

Derives profile name from CLAUDE_CONFIG_DIR (e.g. ~/.claude-octopusoctopus). No-ops for the default profile.

Writes to /dev/tty to reach WezTerm directly, bypassing Claude Code's stdout capture. Safe in non-WezTerm terminals — the sequence is silently ignored.

Configure per profile in ~/.claude-<name>/settings.json:

"SessionStart": [
  { "hooks": [{ "type": "command", "command": "~/.claude/hooks/set-wezterm-profile.sh" }] }
]

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