mirror of
https://github.com/anthropics/claude-code.git
synced 2026-01-30 04:02:03 +00:00
proper hook file
This commit is contained in:
84
examples/hooks/bash_command_validator_example.py
Normal file
84
examples/hooks/bash_command_validator_example.py
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Claude Code Hook: Bash Command Validator
|
||||||
|
=========================================
|
||||||
|
This hook runs as a PreToolUse hook for the Bash tool.
|
||||||
|
It validates bash commands against a set of rules before execution.
|
||||||
|
In this case it changes grep calls to using rg.
|
||||||
|
|
||||||
|
Read more about hooks here: https://docs.anthropic.com/en/docs/claude-code/hooks
|
||||||
|
|
||||||
|
Make sure to change your path to your actual script.
|
||||||
|
|
||||||
|
{
|
||||||
|
"hooks": {
|
||||||
|
"PreToolUse": [
|
||||||
|
{
|
||||||
|
"matcher": "Bash",
|
||||||
|
"hooks": [
|
||||||
|
{
|
||||||
|
"type": "command",
|
||||||
|
"command": "python -m ./bash_command_validator_example"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Define validation rules as a list of (regex pattern, message) tuples
|
||||||
|
VALIDATION_RULES = [
|
||||||
|
(
|
||||||
|
r"\bgrep\b(?!.*\|)",
|
||||||
|
"Use 'rg' (ripgrep) instead of 'grep' for better performance and features",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
r"\bfind\s+\S+\s+-name\b",
|
||||||
|
"Use 'rg --files | rg pattern' or 'rg --files -g pattern' instead of 'find -name' for better performance",
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def validate_command(command: str) -> list[str]:
|
||||||
|
issues = []
|
||||||
|
for pattern, message in VALIDATION_RULES:
|
||||||
|
if re.search(pattern, command):
|
||||||
|
issues.append(message)
|
||||||
|
return issues
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
try:
|
||||||
|
input_data = json.load(sys.stdin)
|
||||||
|
except json.JSONDecodeError as e:
|
||||||
|
print(f"Error: Invalid JSON input: {e}", file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
tool_name = input_data.get("tool_name", "")
|
||||||
|
if tool_name != "Bash":
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
tool_input = input_data.get("tool_input", {})
|
||||||
|
command = tool_input.get("command", "")
|
||||||
|
|
||||||
|
if not command:
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
# Validate the command
|
||||||
|
issues = validate_command(command)
|
||||||
|
|
||||||
|
if issues:
|
||||||
|
for message in issues:
|
||||||
|
print(f"• {message}", file=sys.stderr)
|
||||||
|
# Exit code 2 blocks tool call and shows stderr to Claude
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user