name: Hook Sync description: This skill should be used when implementing "hook-based coordination", "file change detection", "event-driven agent triggering", "PostToolUse hooks", "hybrid hooks", or building systems where file changes automatically trigger agent responses. Provides comprehensive guidance for hook-based synchronization in multi-agent systems. version: 0.1.0
Hook Sync Skill
Overview
This skill provides guidance for implementing hook-based synchronization systems where file changes automatically trigger agent responses. Hooks enable event-driven coordination between agents without polling or manual intervention.
Core Concepts
Hook-Based Coordination
Hooks are event handlers that execute in response to Claude Code events:
Key events for file coordination:
- PostToolUse(Write): After any file write operation
- PreToolUse: Before tool execution (for validation)
- UserPromptSubmit: After user sends a message
Benefits:
- Automatic response to state changes
- No polling or busy-waiting required
- Declarative coordination logic
- Centralized event handling
Hybrid Hook Pattern
Combine script-based filtering with AI-based decision making:
Script component: Fast filtering and validation
- Check file paths match patterns
- Validate file format
- Extract relevant data
- Determine if action needed
Prompt component: Intelligent response
- Analyze file contents
- Decide which agent to spawn
- Generate agent context
- Handle complex scenarios
Hook Configuration
Basic Structure
Hooks are configured in hooks/hooks.json:
{
"PostToolUse": [{
"matcher": "Write",
"hooks": [
{
"type": "prompt",
"prompt": "Check if file change requires agent response"
}
]
}]
}
File Pattern Matching
Detect specific file writes:
{
"PostToolUse": [{
"matcher": "Write",
"hooks": [{
"type": "prompt",
"prompt": "File written: {{tool_use.parameters.file_path}}\n\nIf this is a turn-signal file (games/*/state/turn-signal.json), read the file to determine which player agent to spawn.\n\nIf this is a player-action file (games/*/state/player-actions/*.json), trigger the gamemaster agent to validate and process the action.\n\nOtherwise, take no action."
}]
}]
}
Hybrid Hook Pattern
Use script for fast filtering, prompt for decisions:
{
"PostToolUse": [{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": "bash $CLAUDE_PLUGIN_ROOT/hooks/scripts/check-game-file.sh {{tool_use.parameters.file_path}}",
"timeout": 5
},
{
"type": "prompt",
"prompt": "The previous command checked if this file change requires action. If it exited with code 0, the file is a game state file that needs processing. Read the file and spawn the appropriate agent."
}
]
}]
}
Agent Triggering Patterns
Turn-Based Triggering
When turn signal is written, spawn player agent:
Hook configuration:
{
"PostToolUse": [{
"matcher": "Write",
"hooks": [{
"type": "prompt",
"prompt": "A file was written: {{tool_use.parameters.file_path}}\n\nCheck if this matches the pattern: games/*/state/turn-signal.json\n\nIf yes:\n1. Read the turn-signal.json file\n2. Extract the currentPlayer and turnNumber\n3. Read the game rules from games/*/RULES.md\n4. Read the player's hand from game state\n5. Spawn a player agent using Task tool with:\n - model: haiku\n - prompt including rules, hand, and visible state\n - Instructions to write decision to player-actions/<player-id>.json\n\nIf no: Take no action."
}]
}]
}
Agent spawn on trigger:
// Hook detects turn-signal.json write
const turnSignal = JSON.parse(await Read("games/uno/state/turn-signal.json"));
// Spawn player agent
await Task({
subagent_type: "general-purpose",
model: "haiku",
description: `Player ${turnSignal.currentPlayer} turn`,
prompt: generatePlayerPrompt(turnSignal),
run_in_background: false
});
Action Processing Triggering
When player writes action, trigger gamemaster:
Hook configuration:
{
"PostToolUse": [{
"matcher": "Write",
"hooks": [{
"type": "prompt",
"prompt": "File written: {{tool_use.parameters.file_path}}\n\nCheck if this matches: games/*/state/player-actions/*.json\n\nIf yes:\n1. Read the action file\n2. Extract gameId, playerId, action details\n3. If you ARE the gamemaster agent:\n - Validate the action against game rules\n - Update game state if valid\n - Write next turn signal\n4. If you are NOT the gamemaster:\n - Use Task tool to spawn/resume gamemaster agent\n - Provide action file path for processing\n\nIf no: Take no action."
}]
}]
}
Hook Templates
Game State Monitor Hook
Monitor all game state file changes:
{
"PostToolUse": [{
"matcher": "Write",
"hooks": [{
"type": "prompt",
"prompt": "File change detected: {{tool_use.parameters.file_path}}\n\n## Game Coordination Hook\n\nCheck the file path:\n\n**Turn Signal** (games/*/state/turn-signal.json):\n- Read file to get currentPlayer\n- Load game rules and player hand\n- Spawn player agent for that player's turn\n\n**Player Action** (games/*/state/player-actions/<player-id>.json):\n- Read action file\n- Trigger gamemaster to validate and process\n- Update game state if valid\n\n**Game State** (games/*/state/game-state.json):\n- Log state change for debugging\n- Check if game has ended\n- If ended, generate final report\n\n**Other files**: No action needed\n\nProcess accordingly."
}]
}]
}
Validation Hook
Prevent invalid state changes:
{
"PreToolUse": [{
"matcher": "Write",
"hooks": [{
"type": "prompt",
"prompt": "About to write file: {{tool_use.parameters.file_path}}\n\nIf this is a game state file (games/*/state/*.json):\n1. Validate JSON syntax in tool_use.parameters.content\n2. Check file structure matches expected schema\n3. If invalid: BLOCK the write and explain why\n4. If valid: ALLOW the write\n\nOtherwise: ALLOW the write."
}]
}]
}
Script Integration
File Pattern Checker
Create hooks/scripts/check-game-file.sh:
#!/usr/bin/env bash
# Check if file is a game coordination file
file_path=$1
# Check for turn signal
if [[ "$file_path" =~ games/.*/state/turn-signal\.json ]]; then
echo "turn-signal"
exit 0
fi
# Check for player action
if [[ "$file_path" =~ games/.*/state/player-actions/.*\.json ]]; then
echo "player-action"
exit 0
fi
# Check for game state
if [[ "$file_path" =~ games/.*/state/game-state\.json ]]; then
echo "game-state"
exit 0
fi
# Not a game file
exit 1
File Validator
Create hooks/scripts/validate-game-file.sh:
#!/usr/bin/env bash
# Validate game file JSON structure
file_path=$1
# Check file exists
if [ ! -f "$file_path" ]; then
echo "ERROR: File not found"
exit 1
fi
# Validate JSON syntax
if ! jq empty "$file_path" 2>/dev/null; then
echo "ERROR: Invalid JSON"
exit 1
fi
# Check required fields based on file type
file_type=$(jq -r '.fileType // "unknown"' "$file_path")
case "$file_type" in
"turn-signal")
jq -e '.currentPlayer and .turnNumber' "$file_path" > /dev/null
;;
"player-action")
jq -e '.playerId and .action and .turnNumber' "$file_path" > /dev/null
;;
"game-state")
jq -e '.players and .turnNumber and .gameActive' "$file_path" > /dev/null
;;
*)
echo "ERROR: Unknown file type: $file_type"
exit 1
;;
esac
if [ $? -ne 0 ]; then
echo "ERROR: Missing required fields for $file_type"
exit 1
fi
echo "Valid $file_type file"
exit 0
Best Practices
Hook Design
✅ DO:
- Use prompt-based hooks for complex logic
- Filter with scripts before expensive AI operations
- Include file paths in prompts for context
- Handle multiple file patterns in one hook
- Provide clear decision criteria
❌ DON'T:
- Create separate hooks for every file pattern
- Use only command hooks for complex decisions
- Trigger on every file write without filtering
- Spawn agents without checking context
- Ignore error handling
Performance
✅ DO:
- Filter early with regex patterns
- Use fast scripts for simple checks
- Cache game rules and static data
- Batch multiple actions when possible
- Set reasonable timeouts
❌ DON'T:
- Parse large files in every hook
- Spawn agents unnecessarily
- Reload static data repeatedly
- Create infinite trigger loops
- Ignore timeout configurations
Debugging
✅ DO:
- Log hook executions
- Include file paths in messages
- Test hooks with sample files
- Validate JSON before processing
- Use clear error messages
❌ DON'T:
- Silently fail
- Omit context from logs
- Skip validation
- Create complex hook chains
- Ignore hook errors
Integration Patterns
Complete Turn Cycle
- Gamemaster writes turn signal → PostToolUse hook triggers
- Hook spawns player agent → Player analyzes state
- Player writes action → PostToolUse hook triggers
- Hook notifies gamemaster → Gamemaster validates
- Gamemaster updates state → Next turn begins
Error Recovery
If player agent fails:
- Hook detects timeout or error
- Spawns fallback handler
- Logs error for analysis
- Continues game with default action
If gamemaster fails:
- Hook detects missing state update
- Attempts recovery or game halt
- Notifies user of issue
Testing Hooks
Manual Testing
# Test turn signal trigger
echo '{"fileType":"turn-signal","currentPlayer":"player-1","turnNumber":1}' > games/uno/state/turn-signal.json
# Verify hook triggers
# Check if player agent spawns
# Test player action trigger
echo '{"fileType":"player-action","playerId":"player-1","action":"play","card":{"color":"Red","value":"7"}}' > games/uno/state/player-actions/player-1.json
# Verify hook triggers
# Check if gamemaster processes action
Hook Debugging
Run Claude Code with debug mode:
claude --debug
Check hook execution logs for:
- Hook trigger events
- File path matching
- Script output
- AI responses
- Error messages
Additional Resources
Example Files
Working examples in examples/:
hooks-config.json- Complete hooks.json configurationcheck-game-file.sh- File pattern matcher scriptvalidate-game-file.sh- File validator script
Integration
This skill works with:
- game-coordination: Agents triggered by these hooks
- file-protocol: Files monitored by these hooks
For complete multi-agent coordination, use all three skills together.