Skip to main content

Custom Hooks

11.1 Hook Types

11.2 settings.json Configuration Format

Configure Hooks in .claude/settings.json:
Configuration notes:
  • Each event type is an array containing { matcher, hooks } objects
  • matcher: Matching rule ("startup" matches session start, "Task" matches Task tool calls, "check" matches check Agent stop)
  • hooks: Array of Hooks to execute when matched, executed in order
  • $CLAUDE_PROJECT_DIR: Automatically expanded by Claude Code to the project root
  • timeout: Timeout in seconds; Hook is skipped if exceeded

11.3 Existing Hook Source Code Walkthrough

session-start.py — Context Loading

Trigger: SessionStart Functionality:
  • Reads .trellis/.developer to get developer identity
  • Reads workflow.md to get workflow guide
  • Reads workspace/{name}/index.md to get session history
  • Reads git log to get recent commits
  • Reads the active task list
Output: Injects all context as a system message at the beginning of the session.

inject-subagent-context.py — Spec Injection Engine

Trigger: PreToolUse, matching Task tool calls Functionality (see section 4.3 for details):
  • Intercepts Task tool calls
  • Reads the corresponding JSONL file based on subagent_type
  • Reads all files referenced in the JSONL
  • Builds the complete Agent prompt (specs + requirements + original instructions)
  • Replaces the original prompt
  • Updates current_phase in task.json
Key design decisions:
  • Dispatch Agent does not read specs, keeping it simple
  • Each Agent receives full context, no resume needed
  • [finish] marker triggers lightweight context injection

ralph-loop.py — Quality Loop

Trigger: SubagentStop, matching check Agent Functionality (see section 4.4 for details):
  • Checks verify commands or completion markers
  • Pass allows stop, failure blocks stop
  • Maximum 5 iterations
  • State tracked in .ralph-state.json

11.4 Writing Custom Hooks

Hooks receive JSON input via stdin and output JSON results via stdout. Input format (PreToolUse example):
Output format:

11.5 Example: Adding an Auto-Test Hook

.claude/hooks/auto-test.py:
Register it in settings.json: