Hooks i Event-Driven Automation w Claude Code - Kompletny Przewodnik
Automatyzuj workflow przez event hooks w Claude Code. Pre/Post tool hooks, validation, logging, notifications i integration z external tools.
Hooks w Claude Code to system event-driven automation, który pozwala automatycznie wykonywać akcje w odpowiedzi na zdarzenia - używanie narzędzi, wysyłanie promptów, rozpoczynanie sesji i więcej. W tym przewodniku nauczysz się wykorzystywać hooks do budowania zaawansowanych workflow automation.
Czym Są Hooks?
Hooks to skrypty lub komendy wywoływane automatycznie w odpowiedzi na zdarzenia w Claude Code.
Przykłady użycia:
- Auto-formatting kodu po edycji
- Logowanie wszystkich komend Bash do audit log
- Validation przed wykonaniem ryzykownych operacji
- Wysyłanie notyfikacji do Slacka
- Injection dodatkowego kontekstu do promptów
8 Typów Eventów Hook
Claude Code wspiera 8 głównych event hooks:
1. PreToolUse
Kiedy: Po utworzeniu parametrów tool przez Claude, przed wykonaniem
Use cases:
- Validation przed wykonaniem
- Approval workflows
- Logging planowanych działań
- Blocking ryzykownych operacji
2. PostToolUse
Kiedy: Natychmiast po udanym wykonaniu tool
Use cases:
- Auto-formatting po edycji plików
- Running tests po zmianach kodu
- Notyfikacje o zakończeniu
- Cleanup operations
3. UserPromptSubmit
Kiedy: Gdy użytkownik wysyła prompt, przed przetworzeniem przez Claude
Use cases:
- Context injection
- Enriching prompts z dodatkowymi danymi
- User input validation
- Analytics tracking
4. Notification
Kiedy: Claude wysyła notyfikację (permission requests, idle waiting)
Use cases:
- Auto-approval dla trusted operations
- Logging permission requests
- Custom notification routing
5. Stop
Kiedy: Main agent kończy odpowiedź
Use cases:
- Session summary
- Archiving conversation
- Metrics collection
6. SubagentStop
Kiedy: Subagent kończy zadanie
Use cases:
- Subagent result processing
- Performance tracking
- Cleanup po subagent tasks
7. SessionStart
Kiedy: Na początku sesji lub resume
Use cases:
- Environment setup
- Loading context
- Initializing integrations
8. SessionEnd
Kiedy: Zakończenie sesji
Use cases:
- Cleanup operations
- Saving state
- Final reporting
Konfiguracja Hooks
Hooks definiuje się w plikach settings:
~/.claude/settings.json- User-level (wszystkie projekty).claude/settings.json- Project-level (team shared).claude/settings.local.json- Local overrides (gitignored)
Podstawowa Struktura
{
"hooks": {
"EventName": [
{
"matcher": "ToolPattern",
"hooks": [
{
"type": "command",
"command": "bash-command",
"timeout": 60
}
]
}
]
}
}
Matcher Patterns
Matchers określają, które tools powinny wywołać hook.
Case-sensitive patterns:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write", // Dokładne dopasowanie - tylko Write tool
"hooks": [...]
},
{
"matcher": "Edit|Write", // Regex - Edit LUB Write
"hooks": [...]
},
{
"matcher": "Notebook.*", // Regex - wszystkie Notebook tools
"hooks": [...]
},
{
"matcher": "*", // Wildcard - wszystkie tools
"hooks": [...]
}
]
}
}
Popularne tool patterns:
Bash- Shell commandsRead,Write,Edit- File operationsGlob,Grep- File searchingWebFetch,WebSearch- Web operationsTask- Subagent tasksmcp__*- Wszystkie MCP toolsmcp__github__*- Tylko GitHub MCP tools
Hook Input Format
Hooks otrzymują JSON via stdin ze szczegółami eventu:
{
"session_id": "abc123",
"transcript_path": "/path/to/transcript.md",
"cwd": "/project/directory",
"hook_event_name": "PostToolUse",
"tool_name": "Write",
"tool_input": {
"file_path": "/path/to/file.js",
"content": "const x = 1;"
},
"tool_output": "File written successfully"
}
Dostęp do danych w hookach:
Przez environment variables:
$TOOL_NAME- Nazwa użytego tool$TOOL_INPUT_<param>- Parametry (np.$TOOL_INPUT_file_path)$CLAUDE_PROJECT_DIR- Root directory projektu$CLAUDE_CODE_REMOTE-"true"jeśli remote environment
Hook Output i Exit Codes
Exit Codes
# 0 - Success (stdout pokazany w transcript mode)
exit 0
# 2 - Blocking error (stderr przekazany do Claude)
exit 2
# Inne - Non-blocking error (stderr pokazany użytkownikowi)
exit 1
JSON Output (Advanced Control)
{
"continue": true,
"stopReason": "message",
"suppressOutput": true,
"hookSpecificOutput": {
"hookEventName": "EventType",
"permissionDecision": "allow",
"additionalContext": "Extra info for Claude"
}
}
Pola:
continue- Czy kontynuować executionstopReason- Powód zatrzymaniasuppressOutput- Ukryj output hookpermissionDecision-"allow"|"deny"|"ask"(dla Notification hooks)additionalContext- Context dodany do UserPromptSubmit
Praktyczne Przykłady Hooks
Przykład 1: Auto-formatting Po Edycji
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "npx prettier --write \"$TOOL_INPUT_file_path\"",
"timeout": 30
}
]
}
]
}
}
Co robi: Po każdym Write lub Edit, automatycznie formatuje plik przez Prettier.
Przykład 2: Bash Command Logging
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "echo \"[$(date)] Executing: $TOOL_INPUT_command\" >> .claude/bash-audit.log",
"timeout": 5
}
]
}
]
}
}
Co robi: Loguje wszystkie Bash commands przed wykonaniem do audit log.
Przykład 3: Dangerous Command Blocking
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash -c 'if echo \"$TOOL_INPUT_command\" | grep -qE \"rm -rf|sudo|curl.*sh\"; then echo \"Dangerous command blocked\" >&2 && exit 2; fi'",
"timeout": 5
}
]
}
]
}
}
Co robi: Blokuje potencjalnie niebezpieczne komendy (exit 2 = blocking error).
Przykład 4: Auto-testing Po Zmianach
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "if echo \"$TOOL_INPUT_file_path\" | grep -q '\\.test\\|spec'; then npm test -- \"$TOOL_INPUT_file_path\"; fi",
"timeout": 120
}
]
}
]
}
}
Co robi: Uruchamia testy automatycznie, gdy edytujesz pliki testowe.
Przykład 5: Context Injection
{
"hooks": {
"UserPromptSubmit": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "echo '{\"additionalContext\": \"Current branch: $(git branch --show-current)\\nLast commit: $(git log -1 --oneline)\"}'",
"timeout": 10
}
]
}
]
}
}
Co robi: Automatycznie dodaje Git context do każdego promptu (UserPromptSubmit + additionalContext).
Przykład 6: Slack Notifications
{
"hooks": {
"Stop": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "curl -X POST https://hooks.slack.com/services/YOUR/WEBHOOK/URL -H 'Content-Type: application/json' -d '{\"text\": \"Claude Code session completed\"}'",
"timeout": 10
}
]
}
]
}
}
Co robi: Wysyła notyfikację do Slacka po zakończeniu sesji.
Przykład 7: Environment Setup
{
"hooks": {
"SessionStart": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "echo 'export PROJECT_NAME=my-app' > \"$CLAUDE_ENV_FILE\" && echo 'export ENV=development' >> \"$CLAUDE_ENV_FILE\"",
"timeout": 10
}
]
}
]
}
}
Co robi: Setup environment variables na początku sesji (przez $CLAUDE_ENV_FILE).
Przykład 8: MCP Tool Monitoring
{
"hooks": {
"PreToolUse": [
{
"matcher": "mcp__github__*",
"hooks": [
{
"type": "command",
"command": "echo \"[$(date)] GitHub MCP call: $TOOL_NAME\" >> .claude/mcp-github.log",
"timeout": 5
}
]
}
]
}
}
Co robi: Loguje wszystkie wywołania GitHub MCP tools.
Zaawansowane Patterns
Multiple Hooks na Event
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "npx prettier --write \"$TOOL_INPUT_file_path\"",
"timeout": 30
},
{
"type": "command",
"command": "npx eslint --fix \"$TOOL_INPUT_file_path\"",
"timeout": 30
},
{
"type": "command",
"command": "git add \"$TOOL_INPUT_file_path\"",
"timeout": 10
}
]
}
]
}
}
Co robi: 3 hooks wykonywane równolegle po edycji: format, lint, git add.
Conditional Hooks
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "if [ \"$CLAUDE_CODE_REMOTE\" = \"true\" ]; then echo 'Remote execution detected' >> remote.log; fi",
"timeout": 5
}
]
}
]
}
}
Co robi: Hook wykonuje się tylko w remote environment.
File Type Specific Hooks
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "case \"$TOOL_INPUT_file_path\" in *.js|*.ts) npx eslint --fix \"$TOOL_INPUT_file_path\" ;; *.py) black \"$TOOL_INPUT_file_path\" ;; *.go) gofmt -w \"$TOOL_INPUT_file_path\" ;; esac",
"timeout": 60
}
]
}
]
}
}
Co robi: Różne formattery dla różnych języków.
Execution Details
Parallel Execution
Wszystkie matching hooks wykonują się równolegle:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write",
"hooks": [
{"type": "command", "command": "hook1.sh"}, // \
{"type": "command", "command": "hook2.sh"}, // |--> Równolegle
{"type": "command", "command": "hook3.sh"} // /
]
}
]
}
}
Deduplication
Identyczne komendy są deduplikowane:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write",
"hooks": [
{"type": "command", "command": "npm test"} // Wykonane
]
},
{
"matcher": "Edit",
"hooks": [
{"type": "command", "command": "npm test"} // Deduplikowane jeśli Write+Edit match
]
}
]
}
}
Timeouts
Domyślny timeout: 60 sekund
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": "long-running-task.sh",
"timeout": 300 // 5 minut
}
]
}
]
}
}
Security Best Practices
1. Validate Input
Zawsze waliduj dane z $TOOL_INPUT_*:
#!/bin/bash
# validate-hook.sh
FILE="$TOOL_INPUT_file_path"
# Check for path traversal
if echo "$FILE" | grep -q '\.\./'; then
echo "Path traversal attempt blocked" >&2
exit 2
fi
# Check for absolute path outside project
if [[ "$FILE" = /* ]] && [[ ! "$FILE" = "$CLAUDE_PROJECT_DIR"* ]]; then
echo "Access outside project blocked" >&2
exit 2
fi
# Proceed with safe operation
prettier --write "$FILE"
2. Quote Variables
Zawsze cytuj zmienne w bash:
# ❌ Niebezpieczne
prettier --write $TOOL_INPUT_file_path
# ✅ Bezpieczne
prettier --write "$TOOL_INPUT_file_path"
3. Avoid Sensitive Files
#!/bin/bash
FILE="$TOOL_INPUT_file_path"
# Blokuj sensitive files
if echo "$FILE" | grep -qE '\\.env$|\\.git/|id_rsa|credentials'; then
echo "Cannot modify sensitive file" >&2
exit 2
fi
4. Use Absolute Paths
#!/bin/bash
# ❌ Relative path - może być exploitation
cd "$TOOL_INPUT_directory" && rm file.txt
# ✅ Absolute path
rm "$CLAUDE_PROJECT_DIR/$TOOL_INPUT_directory/file.txt"
5. Limit Permissions
Hook ma permissions użytkownika - ogranicz dostęp:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "if echo \"$TOOL_INPUT_command\" | grep -q 'sudo'; then echo 'sudo blocked' >&2 && exit 2; fi",
"timeout": 5
}
]
}
]
}
}
Real-World Use Cases
Use Case 1: Code Review Workflow
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "npx eslint \"$TOOL_INPUT_file_path\" --format json > /tmp/lint.json && if [ $(jq '.[] | select(.errorCount > 0) | length' /tmp/lint.json) -gt 0 ]; then echo 'Linting errors detected' >&2 && exit 2; fi",
"timeout": 60
}
]
}
]
}
}
Workflow: Błędy lintingu blokują Claude przed dalszymi zmianami.
Use Case 2: Continuous Testing
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "npm test -- --findRelatedTests \"$TOOL_INPUT_file_path\" --passWithNoTests",
"timeout": 120
}
]
}
],
"Stop": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "npm test -- --coverage && echo 'Coverage report: file://$(pwd)/coverage/index.html'",
"timeout": 300
}
]
}
]
}
}
Workflow: Testy after każdej zmiany, full coverage na końcu sesji.
Use Case 3: Deployment Gate
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "if echo \"$TOOL_INPUT_command\" | grep -q 'deploy'; then echo 'Deployment requires manual approval' >&2 && exit 2; fi",
"timeout": 5
}
]
}
]
}
}
Workflow: Blokuj auto-deployment, wymagaj manual approval.
Use Case 4: Analytics & Metrics
{
"hooks": {
"UserPromptSubmit": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "curl -X POST https://analytics.company.com/track -d '{\"event\": \"claude_prompt\", \"user\": \"$USER\", \"timestamp\": \"$(date -Iseconds)\"}'",
"timeout": 10
}
]
}
],
"Stop": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "curl -X POST https://analytics.company.com/track -d '{\"event\": \"claude_session_complete\", \"session_id\": \"$SESSION_ID\", \"duration\": \"$(date +%s)\"}'",
"timeout": 10
}
]
}
]
}
}
Workflow: Track usage metrics dla team analytics.
Debugging Hooks
Check Hook Configuration
claude
> /hooks
Output pokazuje:
- Załadowane hooks
- Active matchers
- Configuration source (user/project/local)
View Hook Output
Hooks output jest widoczny w transcript mode.
Enable transcript:
claude --transcript
Test Hook Manually
# Symuluj hook input
echo '{"tool_name": "Write", "tool_input": {"file_path": "test.js"}}' | \
TOOL_NAME=Write \
TOOL_INPUT_file_path=test.js \
bash -c 'npx prettier --write "$TOOL_INPUT_file_path"'
Hook Errors
Check stderr output:
- Exit 2 → Claude otrzyma error
- Exit 0 → Success
- Exit 1 → User widzi error, Claude kontynuuje
Snapshot Behavior
Ważne: Hooks są snapshot at startup.
External zmiany w settings wymagają:
claude
> /hooks
Następnie wybierz “Reload hooks” aby zaaplikować nową konfigurację.
📚 Dokumentacja i Zasoby
Oficjalna Dokumentacja
Powiązane Artykuły
Podsumowanie
Hooks w Claude Code to potężny system automation:
✅ 8 typów eventów - PreToolUse, PostToolUse, UserPromptSubmit, SessionStart/End, Stop, SubagentStop, Notification ✅ Flexible matchers - Exact, regex, wildcard patterns ✅ Rich input data - JSON via stdin, environment variables ✅ Control flow - Exit codes, JSON output, blocking errors ✅ Parallel execution - Multiple hooks run concurrently ✅ Security - Input validation, path checking, permission limits
Best Practices Recap
- Validate input - Sprawdzaj
$TOOL_INPUT_*przed użyciem - Quote variables - Zawsze
"$VAR"w bash - Check paths - Blokuj
../i absolute paths poza projektem - Limit permissions - No sudo, no sensitive files
- Use timeouts - Prevent hanging hooks
- Test locally - Before deploying team-wide
- Document hooks - Comment complex logic
Następne Kroki
- Stwórz prosty PostToolUse hook (auto-format)
- Dodaj PreToolUse validation (dangerous commands)
- Implement UserPromptSubmit context injection
- Setup SessionStart environment initialization
- Build complete workflow automation pipeline
Hooks przekształcają Claude Code w w pełni automatyczny development environment! 🎣
Podobał Ci się ten tutorial?
Podziel się nim ze znajomymi i kolegami, którym może się przydać!
📚 Powiązane Artykuły
Power-user workflow: Extended Thinking Megathink, Sessions i approvals
Przewodnik dla zaawansowanych użytkowników Claude Code: jak łączyć najdłuższe tryby myślenia, zapisy stanu i mechanizm approvals w złożonych projektach.
AI w pipeline frontendu: Plan Mode + hook PostToolUse dla pełnej automatyzacji
Jak skonfigurować Claude Code, by po zmianach komponentów AI planował zadania, formatował kod, uruchamiał astro check oraz wskazywał brakujące testy.
Hooki Claude Code jako CI light: lint, astro check, testy i Lighthouse
Budujemy zestaw hooków PostToolUse i Stop, które po każdej zmianie formatują kod, uruchamiają testy, generują coverage oraz raport dostępności.