home / skills / louloulin / claude-agent-sdk / hooks-test-skill
/crates/claude-agent-sdk/examples/.claude/skills/hooks-test-skill
This skill demonstrates hooks functionality for automated tool events, enabling PreToolUse, PostToolUse, and Stop hooks to orchestrate actions.
npx playbooks add skill louloulin/claude-agent-sdk --skill hooks-test-skillReview the files below or copy the command above to add this skill to your agents.
---
name: hooks-test
description: Test skill demonstrating hooks functionality. Shows PreToolUse, PostToolUse, and Stop hooks in action.
version: "1.0.0"
author: "SDK Team <[email protected]>"
tags:
- testing
- hooks
- development
dependencies: []
allowed_tools:
- Read
- Write
- Bash
- Grep
hooks:
pre_tool_use:
- matcher: "Bash"
command: "echo 'š PreToolUse: About to execute Bash tool'"
type: command
once: false
- matcher: "Write"
command: "echo 'š PreToolUse: About to write file - $TOOL_NAME'"
type: command
once: false
- matcher: "*"
command: "echo 'ā” PreToolUse: Tool $TOOL_NAME is about to be used'"
type: command
once: true
post_tool_use:
- matcher: "Bash"
command: "echo 'ā
PostToolUse: Bash tool executed successfully'"
type: command
once: false
- matcher: "Write"
command: "echo 'š¾ PostToolUse: File written successfully'"
type: command
once: false
stop:
- matcher: "*"
command: "echo 'š Stop hook: Cleaning up resources...'"
type: command
once: false
---
# Hooks Test Skill
Demonstrates the complete hooks functionality in Claude Agent SDK. This skill showcases how PreToolUse, PostToolUse, and Stop hooks work together to provide event-driven automation.
## What are Hooks?
Hooks are event-driven commands that run at specific points during skill execution:
- **PreToolUse**: Runs BEFORE a tool is executed
- **PostToolUse**: Runs AFTER a tool completes successfully
- **Stop**: Runs when the skill execution stops or completes
## Hook Configuration
Each hook has:
- **matcher**: Pattern to match tool names (e.g., "Bash", "Write", "*")
- **command**: Shell command to execute
- **once**: If true, runs only once per session (default: false)
- **type**: Execution type - "command", "script", or "function"
## Testing the Hooks
### Test 1: Bash Tool Hooks
When you ask me to run a Bash command:
```
Please run: echo "Hello World"
```
**Expected Output**:
```
š PreToolUse: About to execute Bash tool
[Bash command executes]
ā
PostToolUse: Bash tool executed successfully
```
### Test 2: Write Tool Hooks
When you ask me to write a file:
```
Create a file named test.txt with content "Hello"
```
**Expected Output**:
```
š PreToolUse: About to write file - Write
[File is written]
š¾ PostToolUse: File written successfully
```
### Test 3: Wildcard Matcher
The `*` matcher with `once: true` will run only once for the first tool used:
```
Run any command
```
**Expected Output**:
```
ā” PreToolUse: Tool <tool_name> is about to be used
[This message appears only once per session]
```
### Test 4: Stop Hook
When this skill finishes execution:
**Expected Output**:
```
š Stop hook: Cleaning up resources...
```
## Hook Features Demonstrated
### 1. Tool-Specific Hooks
- PreToolUse and PostToolUse for specific tools (Bash, Write)
- Fine-grained control over tool execution
### 2. Wildcard Matching
- `*` matcher applies to all tools
- Useful for global hooks like logging
### 3. Once-Only Execution
- `once: true` ensures hook runs only once per session
- Perfect for initialization tasks
### 4. Multiple Hooks Per Event
- Can stack multiple hooks for the same event
- Run in sequence for chained operations
## Advanced Usage
### Pattern Matching
You can use patterns in the matcher field:
```yaml
hooks:
PreToolUse:
# Match specific tool
- matcher: "Bash"
hooks:
- type: command
command: "echo 'Bash tool detected'"
# Match multiple tools with wildcard
- matcher: "Bash*"
hooks:
- type: command
command: "echo 'Any Bash-related tool'"
# Match all tools
- matcher: "*"
hooks:
- type: command
command: "echo 'Any tool'"
```
### Environment Variables
Hooks can access environment variables:
```yaml
hooks:
PreToolUse:
- matcher: "*"
hooks:
- type: command
command: "echo 'Tool: $TOOL_NAME, Input: $TOOL_INPUT'"
```
### Script Hooks
Instead of inline commands, use scripts:
```yaml
hooks:
PreToolUse:
- matcher: "Write"
hooks:
- type: script
command: "scripts/validate_write.sh"
```
With `scripts/validate_write.sh`:
```bash
#!/bin/bash
echo "Validating write operation..."
echo "Tool: $TOOL_NAME"
echo "Input: $TOOL_INPUT"
# Add validation logic here
```
## Common Use Cases
### 1. Security Validation
```yaml
hooks:
PreToolUse:
- matcher: "Bash"
hooks:
- type: script
command: "scripts/security_check.sh"
```
### 2. Audit Logging
```yaml
hooks:
PostToolUse:
- matcher: "*"
hooks:
- type: command
command: "echo '$(date): Tool $TOOL_NAME used' >> audit.log"
```
### 3. Resource Cleanup
```yaml
hooks:
Stop:
- matcher: "*"
hooks:
- type: script
command: "scripts/cleanup.sh"
```
### 4. Performance Monitoring
```yaml
hooks:
PreToolUse:
- matcher: "*"
hooks:
- type: command
command: "echo $(date +%s%N) > /tmp/start_time"
PostToolUse:
- matcher: "*"
hooks:
- type: command
command: |
START=$(cat /tmp/start_time)
END=$(date +%s%N)
echo "Tool execution time: $((($END - $START) / 1000000))ms"
```
## Testing Checklist
Test each hook type:
- [ ] PreToolUse fires before Bash
- [ ] PreToolUse fires before Write
- [ ] PostToolUse fires after Bash
- [ ] PostToolUse fires after Write
- [ ] Wildcard matcher works for all tools
- [ ] `once: true` prevents repeat execution
- [ ] Stop hook fires on skill completion
- [ ] Multiple hooks execute in sequence
- [ ] Hook failures don't stop main execution
## Troubleshooting
### Hook Not Firing
**Problem**: Hook command doesn't execute
**Solutions**:
1. Check YAML syntax (use spaces, not tabs)
2. Verify matcher pattern matches tool name
3. Ensure command is executable
4. Check hook event type (PreToolUse vs PostToolUse)
### Once Flag Not Working
**Problem**: Hook with `once: true` keeps running
**Solution**: The `once` flag applies per session. Restart the session to test.
### Hook Failing Silently
**Problem**: Hook errors not visible
**Solution**: Add error handling:
```yaml
hooks:
PreToolUse:
- matcher: "*"
hooks:
- type: command
command: "python scripts/hook.py 2>&1 || echo 'Hook failed'"
```
## Best Practices
### DO ā
1. Use specific matchers when possible
2. Keep hook commands simple and fast
3. Add proper error handling
4. Use scripts for complex logic
5. Test hooks in isolation
6. Log hook execution for debugging
### DON'T ā
1. Don't put long-running commands in hooks
2. Don't use hooks for core logic (use skill execution)
3. Don't forget to make scripts executable
4. Don't assume environment variables exist
5. Don't create circular dependencies with hooks
## Summary
This skill demonstrates:
- ā
PreToolUse hooks for tool preparation
- ā
PostToolUse hooks for tool completion
- ā
Stop hooks for cleanup
- ā
Pattern matching with specific tools
- ā
Wildcard matching for all tools
- ā
Once-only execution
- ā
Multiple hooks per event
Try the tests above to see hooks in action!
---
**Version**: 1.0.0
**Last Updated**: 2026-01-10
**Maintainer**: SDK Team
This skill demonstrates hooks functionality in the Claude Agent SDK for Rust. It shows PreToolUse, PostToolUse, and Stop hooks in action and provides concrete patterns for matcher, command, type, and once semantics. Use it to verify event-driven automation, logging, validation, and cleanup behaviors around tool execution.
The skill runs configured hook entries at three lifecycle points: before a tool runs (PreToolUse), after it completes successfully (PostToolUse), and when the skill stops (Stop). Each hook entry uses a matcher pattern to select tools, a command or script to run, an execution type (command, script, function), and an optional once flag that limits execution to the first match per session. Hooks run in sequence and do not block normal tool execution if they fail.
What does once: true do?
once: true ensures the matched hook runs only the first time the matcher triggers in a session, useful for one-time initialization.
Will a failing hook stop the main tool?
No. Hooks are designed not to block the main execution; add error handling in hook commands if you need stricter behavior.
How do I match multiple tools?
Use pattern matchers like Bash*, or '*' to match all tools. Prefer narrower patterns for precise control.