Hooks Reference¶
Complete reference for the Agent Flow hook system, including all lifecycle events, matchers, and hook implementations.
Overview¶
Hooks are automated actions that trigger at specific points in the Claude Code lifecycle. Agent Flow uses hooks to:
- Refine user prompts before processing
- Guide delegation behavior
- Validate file operations
- Enforce verification gates
- Load project context
Hook Architecture¶
sequenceDiagram
participant U as User
participant C as Claude Code
participant H as Hook System
participant A as Agent
participant T as Tool
U->>C: Submit prompt
C->>H: UserPromptSubmit
H-->>C: Refined prompt
C->>A: Delegate to agent
A->>H: PreToolUse
H-->>A: Allow/Block/Guidance
A->>T: Execute tool
T-->>A: Result
A->>H: PostToolUse
H-->>A: Verification guidance
A-->>C: Agent complete
C->>H: Stop (before completion)
H-->>C: Verification result
C->>U: Response
Hook Configuration¶
Hooks are defined in hooks/hooks.json:
{
"description": "Multi-agent orchestration hooks for verification and context",
"hooks": {
"UserPromptSubmit": [...],
"PreToolUse": [...],
"PostToolUse": [...],
"SessionStart": [...],
"Stop": [...],
"TeammateIdle": [...],
"TaskCompleted": [...]
}
}
Hook Types¶
Prompt Hooks¶
Prompt hooks use the LLM to analyze and potentially modify behavior:
Properties:
- prompt: Instructions for the LLM
- timeout: Maximum seconds to wait (optional)
Command Hooks¶
Command hooks execute shell scripts:
{
"type": "command",
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/verify-completion.sh",
"timeout": 60
}
Properties:
- command: Shell command to execute
- timeout: Maximum seconds to wait (optional)
Environment Variables:
- CLAUDE_PLUGIN_ROOT: Plugin installation directory
- TOOL_NAME: Name of the tool being used (PreToolUse/PostToolUse)
- TOOL_INPUT: JSON input to the tool (PreToolUse/PostToolUse)
Lifecycle Events¶
Core Lifecycle Events¶
The following hooks trigger during standard orchestration workflows.
UserPromptSubmit¶
Triggers when the user submits a message, before processing begins.
Use Cases: - Prompt refinement - Task classification - Orchestration detection
Agent Flow Implementation:
{
"type": "prompt",
"prompt": "Analyze this user prompt for task clarity.
If this is an AFFIRMATIVE RESPONSE (yes, ok, sure, continue...):
Respond with just 'No refinement needed.'
If this is an orchestration/planning task (fix, implement, add...):
- If SPECIFIC: Transform to **Goal** / **Description** / **Actions** format
- If AMBIGUOUS: Ask ONE clarifying question with 2-4 options
If NOT an orchestration task:
Respond with just 'No refinement needed.'
Be concise.",
"timeout": 15
}
PreToolUse¶
Triggers before a tool is executed. Can block, modify, or allow the operation.
Matcher: Tool name pattern (e.g., Write|Edit)
Use Cases: - Validate file paths - Provide delegation guidance - Block dangerous operations
Agent Flow Implementation:
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/enforce-delegation.sh",
"timeout": 5
},
{
"type": "command",
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/validate-changes.sh",
"timeout": 30
}
]
}
enforce-delegation.sh:
- Allows writes to .senku/ silently (planning files)
- Provides delegation guidance for other file writes
- Does not block - agents handle their own tool restrictions
validate-changes.sh:
- Blocks path traversal (.. in paths)
- Blocks writes to sensitive files (.env, credentials, keys)
- Blocks writes to system paths (/etc, /usr, /bin)
PostToolUse¶
Triggers after a tool completes execution.
Matcher: Tool name pattern (e.g., Task, Write|Edit)
Use Cases: - Verify delegation results - Validate file writes - Provide context-aware guidance
Agent Flow Implementation (Task):
{
"matcher": "Task",
"hooks": [
{
"type": "prompt",
"prompt": "Agent completed. Verify based on task type:
- **Riko (exploration)**: Accept findings, no code verification needed
- **Senku (planning)**: Review plan completeness
- **Loid (implementation)**: READ changed files, RUN tests, CHECK types
- **Lawliet (review)**: Consider feedback
- **Alphonse (verification)**: Check test results
Only Loid tasks require full code verification.",
"timeout": 30
}
]
}
Agent Flow Implementation (Write|Edit):
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/validate-changes.sh",
"timeout": 30
}
]
}
SessionStart¶
Triggers when a new Claude Code session begins.
Matcher: * (matches all sessions)
Use Cases: - Detect project type - Load project context - Set environment variables
Agent Flow Implementation:
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/load-project-context.sh",
"timeout": 10
}
]
}
load-project-context.sh detects: - Project type (nodejs, python, rust, go, java) - Test framework (jest, pytest, cargo-test, etc.) - Available tooling (TypeScript, ESLint, Ruff)
Stop¶
Triggers before task completion, allowing verification gates.
Use Cases: - Run test suites - Verify type checking - Check lint errors - Validate build
Agent Flow Implementation:
{
"hooks": [
{
"type": "command",
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/verify-completion.sh",
"timeout": 60
}
]
}
verify-completion.sh:
- Runs npm test / pytest
- Runs npx tsc --noEmit / mypy (when mypy.ini is present)
- Reports pass/fail status
Advanced features:
1. Bypass: Create .claude/skip-test-verification file to skip all verification (first line = reason)
2. Custom test commands: Create .claude/test-command file to override default test command
3. Known failures: Create .claude/known-test-failures file with expected failures (one per line, # for comments)
4. uv support: Uses uv run pytest when uv is available and uv.lock exists
5. Priority: custom command > uv run pytest > bare pytest
Team Orchestration Events¶
The following hooks trigger during team orchestration workflows when using Agent Teams.
TeammateIdle¶
Triggers when a teammate in an Agent Team has no active tasks.
Use Cases: - Monitor teammate status - Check if task completed - Provide guidance for idle teammates - Detect completion of parallel tasks
Agent Flow Implementation:
{
"TeammateIdle": [
{
"hooks": [
{
"type": "command",
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/teammate-idle-check.sh",
"timeout": 30
}
]
}
]
}
teammate-idle-check.sh behavior:
1. Receives JSON input from stdin with teammate_role and teammate_output fields
2. Performs role-based quality checks
3. Returns approval decision or blocks with reason
Input:
- JSON from stdin with teammate_role and teammate_output fields
Role-based checks: - Reviewer (Lawliet): Must contain verdict (APPROVED/NEEDS_CHANGES/BLOCKED) + static analysis evidence - Verifier (Alphonse): Must contain at least 2 verification gate results + command output - Other roles: Approved without specific checks
Typical Flow:
sequenceDiagram
participant T as Teammate
participant H as Hook System
participant S as State File
participant O as Orchestrator
T->>T: Complete assigned task
Note over T: Becomes idle
T->>H: TeammateIdle event
H->>H: teammate-idle-check.sh
H->>S: Check task status
alt Task completed successfully
H->>S: Mark task complete
H-->>O: Notify completion
else Task incomplete
H-->>O: Alert: Teammate idle but task pending
end
TaskCompleted¶
Triggers when a task within an Agent Team completes.
Use Cases: - Update parallel group state - Check if all parallel tasks completed - Trigger result merging - Transition to next phase
Agent Flow Implementation:
{
"TaskCompleted": [
{
"hooks": [
{
"type": "command",
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/task-completed-check.sh",
"timeout": 15
}
]
}
]
}
task-completed-check.sh behavior:
1. Receives JSON input from stdin with task_status and completion_message fields
2. Only validates tasks marked as complete/done/finished
3. Checks completion message for concrete evidence
4. Returns approval decision or blocks with reason
Input:
- JSON from stdin with task_status and completion_message fields
Evidence checks: - Message length >= 20 characters - Contains file mentions, verification indicators, concrete actions, or results/metrics - Tasks not marked complete are approved without validation
Typical Flow:
sequenceDiagram
participant T as Task
participant H as Hook System
participant S as State File
participant M as Merge Script
participant O as Orchestrator
T->>H: Task completed
H->>H: task-completed-check.sh
H->>S: Update sub-phase status
alt All parallel tasks complete
H->>M: Run merge-parallel-results.sh
M->>S: Read all sub-phase results
M-->>H: Merged result
H->>S: Update parallel group status
H-->>O: All tasks complete
else Some tasks still running
H-->>O: Task complete, waiting for others
end
State Updates:
Before task completion:
parallel_groups:
review_verification:
status: "in_progress"
review:
status: "in_progress"
verification:
status: "in_progress"
After one task completes:
parallel_groups:
review_verification:
status: "in_progress"
review:
status: "passed"
result: "APPROVED"
timestamp: "2024-01-15T10:46:30Z"
verification:
status: "in_progress"
After all tasks complete:
parallel_groups:
review_verification:
status: "passed"
completed_at: "2024-01-15T10:47:15Z"
review:
status: "passed"
result: "APPROVED"
timestamp: "2024-01-15T10:46:30Z"
verification:
status: "passed"
result: "VERIFIED"
timestamp: "2024-01-15T10:47:15Z"
Hook Scripts¶
enforce-delegation.sh¶
Provides guidance on delegation patterns when file writes are detected.
Behavior:
1. Check if path is .senku/ directory
2. If yes: Allow silently (planning files)
3. If no: Output delegation guidance message
Note: This hook provides context, not enforcement. Agent tool restrictions are the primary control mechanism.
validate-changes.sh¶
Validates file operations for security.
Checks:
| Check | Pattern | Action |
|-------|---------|--------|
| Path traversal | .. in path | Block |
| Environment files | *.env, *.env.* | Block |
| Credential files | *credentials*, *secret*, *.key, *.pem, *id_rsa*, *id_ed25519* | Block |
| System paths | /etc/*, /usr/*, /bin/*, /sbin/*, /var/*, /root/* | Block |
Exit Codes:
- 0: Validation passed
- 1: Validation failed (operation blocked)
verify-completion.sh¶
Runs verification gates before task completion.
Process: 1. Detect project type from markers 2. Run appropriate test command 3. Run type checking if available 4. Report results
Project Detection:
| Marker | Project Type | Test Command |
|--------|--------------|--------------|
| package.json | Node.js | npm test |
| pyproject.toml | Python | pytest |
| Cargo.toml | Rust | cargo test |
| go.mod | Go | go test ./... |
teammate-idle-check.sh¶
Validates teammate output quality using role-based criteria.
Purpose: Ensure teammates produce sufficient evidence for their role before approval.
Input:
- JSON from stdin with teammate_role and teammate_output fields
Behavior: 1. Extract teammate role and output from JSON stdin 2. Apply role-specific quality checks: - Reviewer (Lawliet): Requires verdict (APPROVED/NEEDS_CHANGES/BLOCKED) + static analysis evidence (type check, lint, code quality, security, pattern) - Verifier (Alphonse): Requires at least 2 verification gate results (tests, types, lint, build) + command output (not just status) - Other roles: Approved without specific checks 3. Return approval or block decision
Exit Codes:
- 0: Approve teammate output
- 2: Block due to insufficient quality
Output Format:
{
"decision": "approve|block",
"reason": "Quality check result description",
"systemMessage": "System status message"
}
Example Outputs:
{
"decision": "block",
"reason": "Reviewer output must contain verdict (APPROVED/NEEDS_CHANGES/BLOCKED)",
"systemMessage": "Reviewer idle check failed: missing verdict"
}
{
"decision": "approve",
"reason": "Teammate idle check passed",
"systemMessage": "Teammate quality requirements met"
}
task-completed-check.sh¶
Validates task completion messages for concrete evidence of work.
Purpose: Ensure task completions contain meaningful evidence, not just status updates.
Input:
- JSON from stdin with task_status and completion_message fields
Behavior: 1. Extract task status and completion message from JSON stdin 2. Only validate tasks marked as "complete", "done", or "finished" 3. Check completion message for concrete evidence: - Message length >= 20 characters - File mentions (file paths, extensions, directories) - Verification indicators (test, verified, checked, passed, validated, built, compiled) - Concrete actions (created, updated, modified, fixed, added, removed, refactored, implemented) - Results/metrics (numbers with units like "5 files", "10 tests", "0 errors") 4. Return approval or block decision
Exit Codes:
- 0: Approve task completion
- 2: Block due to insufficient evidence
Output Format:
{
"decision": "approve|block",
"reason": "Evidence check result description",
"systemMessage": "System status message"
}
Example Outputs:
{
"decision": "block",
"reason": "Completion message too short - must provide concrete evidence of completion",
"systemMessage": "Task completion check failed: insufficient completion message"
}
{
"decision": "approve",
"reason": "Task completion check passed",
"systemMessage": "Task completion has adequate evidence"
}
Creating Custom Hooks¶
Prompt Hook Template¶
{
"type": "prompt",
"prompt": "Your instructions here. Be specific about:
- What to analyze
- What actions to take
- What output format to use
Context available: $TOOL_NAME, $TOOL_INPUT (for tool hooks)",
"timeout": 30
}
Command Hook Template¶
#!/bin/bash
# hooks/scripts/my-hook.sh
set -euo pipefail
# Access environment variables
TOOL_NAME="${TOOL_NAME:-}"
TOOL_INPUT="${TOOL_INPUT:-}"
# Your logic here
if [[ some_condition ]]; then
echo '{"continue": true, "systemMessage": "Guidance message"}'
exit 0 # Allow operation
else
echo '{"continue": false, "systemMessage": "Error: reason"}'
exit 2 # Block operation
fi
Adding Hooks¶
- Create script in
hooks/scripts/ - Add hook definition to
hooks/hooks.json - Test with a sample operation
{
"matcher": "YourTool",
"hooks": [
{
"type": "command",
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/my-hook.sh",
"timeout": 10
}
]
}
Hook Execution Order¶
When multiple hooks match, they execute in array order:
{
"matcher": "Write|Edit",
"hooks": [
{ "command": "first-hook.sh" }, // Runs first
{ "command": "second-hook.sh" } // Runs second
]
}
If any hook fails (exits non-zero), subsequent hooks do not run and the operation is blocked.
Debugging Hooks¶
Check Hook Registration¶
Verify hooks are loaded by examining the configuration:
Test Hook Scripts¶
Run scripts directly with test inputs:
TOOL_NAME="Write" TOOL_INPUT='{"file_path": "/test/file.ts"}' \
bash hooks/scripts/validate-changes.sh
View Hook Output¶
Hook output appears in the Claude Code response. For command hooks: - stdout: JSON response (both allow and block responses) - Exit code: 0 = allow, 2 = block
Related Documentation¶
- Verification Gates - Verification philosophy
- State Files - State tracking format
- Commands Reference - Command specifications