Claude Code hooks po polsku, 10 praktycznych przykładów 2026
Hooks w Claude Code, kompletny tutorial PL. PreToolUse, PostToolUse, UserPromptSubmit, SessionStart. 10 gotowych hooków do skopiowania, antywzorce, troubleshooting.
Spis treści
Aktualizacja: maj 2026. Hooks to najbardziej niedocenione feature Claude Code. Pozwalają zamienić CLI z "lepszego chatu z kodem" w prawdziwy agentic system z gwarancjami: brak destrukcyjnych komend, automatyczna formatowanie, custom validation, audit log. W tym tutorialu pokazuję 5 typów hooków, syntax w settings.json i 10 gotowych przykładów do skopiowania.
TL;DR, hooks w 5 punktach:
- Programowalne triggery w określonych momentach sesji Claude Code
- 5 typów: PreToolUse, PostToolUse, UserPromptSubmit, Stop, SessionStart
- Konfiguracja w
.claude/settings.json(per-projekt) lub~/.claude/settings.json(global) - Komenda to dowolny shell (bash, python, node), exit code != 0 blokuje akcję
- Standard use case: blokuj
rm -rf, auto-format po edytach, audit log
Czym są hooks w Claude Code
Hooks to konfigurowalne triggery uruchamiane w określonych momentach sesji Claude Code. Każdy hook to wpis w settings.json, który mówi: "kiedy stanie się X, wykonaj komendę Y". Jeśli Y zwróci błąd (exit code != 0), Claude Code zablokuje akcję X.
Analogicznie do git hooków (pre-commit, post-receive), tylko że tutaj triggerami są nie operacje git, tylko operacje agenta: użycie narzędzia (PreToolUse / PostToolUse), wysłanie prompta (UserPromptSubmit), zakończenie sesji (Stop), początek sesji (SessionStart).
Realnie hooks są tym, co zamienia Claude Code z "AI chat w terminalu" w prawdziwy system, który zatrzymuje agenta przed zrobieniem czegoś głupiego (jak rm -rf node_modules bez backup), albo automatyzuje workflow, którego inaczej trzeba pilnować ręcznie (jak format po każdej edycji).
5 typów hooków w Claude Code
| Typ hooka | Kiedy się uruchamia | Typowy use case |
|---|---|---|
PreToolUse | Przed wywołaniem narzędzia (Bash, Edit, Write) | Blokuj destrukcyjne komendy, validation |
PostToolUse | Po wywołaniu narzędzia | Auto-format, lint, generation derived files |
UserPromptSubmit | Gdy użytkownik wysyła prompt | Wzbogacenie kontekstu (branch name, autor) |
Stop | Na zakończenie sesji Claude | Uruchom testy, generuj summary, audit log |
SessionStart | Na początku sesji | Ładuj env vars, sprawdzaj prereq |
Konfiguracja w settings.json
Hooks definiujesz w .claude/settings.json w roocie projektu (per-projekt) lub ~/.claude/settings.json (globalnie). Per-projekt nadpisuje globalne. Format:
{
"hooks": {
"TypHooka": [
{
"matcher": "PatternMatcher",
"hooks": [
{
"type": "command",
"command": "shell command tutaj"
}
]
}
]
}
} matcher to filter, który decyduje, dla jakich narzędzi/promptów hook ma się uruchomić. Dla PreToolUse i PostToolUse matcher to nazwa narzędzia (Bash, Edit, Write, Glob, Grep, Read). Dla UserPromptSubmit i Stop matcher zazwyczaj jest pusty (uruchamia się zawsze).
Twój pierwszy hook, blokowanie rm -rf
Zacznijmy od najprostszego i najużyteczniejszego hooka, blokady niebezpiecznego rm -rf.
Plik .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "if echo \"$CLAUDE_TOOL_INPUT\" | grep -qE 'rm -rf|sudo rm'; then echo 'BLOCKED: destructive rm command' && exit 1; fi"
}
]
}
]
}
}
Od teraz każda próba Claude'a użycia rm -rf w Bash kończy się komunikatem "BLOCKED: destructive rm command" i Claude przejdzie do alternatywnej strategii (np. git rm, mv do trash). Bez restartu Claude Code, hook działa natychmiast po zapisaniu pliku.
10 praktycznych hooków do skopiowania
1. Blokuj rm -rf i destrukcyjne bash
{
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "if echo \"$CLAUDE_TOOL_INPUT\" | grep -qE 'rm -rf|sudo rm|chmod 000|dd if='; then echo 'BLOCKED destructive command' && exit 1; fi"
}]
}]
} 2. Auto-format po Edit (Prettier / Ruff)
{
"PostToolUse": [{
"matcher": "Edit",
"hooks": [{
"type": "command",
"command": "FILE=$(echo \"$CLAUDE_TOOL_OUTPUT\" | jq -r '.file_path'); if [[ \"$FILE\" == *.ts ]] || [[ \"$FILE\" == *.js ]]; then npx prettier --write \"$FILE\"; elif [[ \"$FILE\" == *.py ]]; then ruff format \"$FILE\"; fi"
}]
}]
} 3. Blokuj edit plików .env i secrets
{
"PreToolUse": [{
"matcher": "Edit|Write",
"hooks": [{
"type": "command",
"command": "FILE=$(echo \"$CLAUDE_TOOL_INPUT\" | jq -r '.file_path // empty'); if echo \"$FILE\" | grep -qE '\\.env|secrets|credentials|\\.pem$'; then echo 'BLOCKED: edit on secrets file' && exit 1; fi"
}]
}]
} 4. Auto-uruchom testy po zakończeniu sesji
{
"Stop": [{
"hooks": [{
"type": "command",
"command": "if [ -f package.json ]; then npm test --silent 2>&1 | tail -20; elif [ -f pyproject.toml ]; then pytest -q 2>&1 | tail -20; fi"
}]
}]
} 5. Dodaj branch i autor do każdego prompta (UserPromptSubmit)
{
"UserPromptSubmit": [{
"hooks": [{
"type": "command",
"command": "echo \"BRANCH=$(git branch --show-current)|USER=$(git config user.email)\" >&2"
}]
}]
} 6. Wymuszaj że każdy commit ma conventional commit prefix
{
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "if echo \"$CLAUDE_TOOL_INPUT\" | grep -qE 'git commit'; then if echo \"$CLAUDE_TOOL_INPUT\" | grep -qvE '(feat|fix|chore|docs|refactor|test|style|perf|build|ci)(\\(.*\\))?:'; then echo 'BLOCKED: commit message must start with conventional prefix' && exit 1; fi; fi"
}]
}]
} 7. Audit log wszystkich tool uses (PostToolUse)
{
"PostToolUse": [{
"hooks": [{
"type": "command",
"command": "echo \"$(date -Iseconds) $CLAUDE_TOOL_NAME $(echo $CLAUDE_TOOL_INPUT | jq -c .)\" >> .claude/audit.log"
}]
}]
} 8. SessionStart, sprawdź czy CLAUDE.md istnieje
{
"SessionStart": [{
"hooks": [{
"type": "command",
"command": "if [ ! -f CLAUDE.md ]; then echo 'WARNING: brak CLAUDE.md w repo' >&2; fi"
}]
}]
} 9. Blokuj wywołania zewnętrznego curla do unknown domains
{
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "if echo \"$CLAUDE_TOOL_INPUT\" | grep -qE '^curl '; then DOMAIN=$(echo \"$CLAUDE_TOOL_INPUT\" | grep -oE 'https?://[^/ ]+' | head -1); ALLOWED='api.github.com|api.linear.app|api.anthropic.com'; if ! echo \"$DOMAIN\" | grep -qE \"$ALLOWED\"; then echo \"BLOCKED curl to: $DOMAIN\" && exit 1; fi; fi"
}]
}]
} 10. PostToolUse, regeneracja plików derived (np. types z OpenAPI)
{
"PostToolUse": [{
"matcher": "Edit|Write",
"hooks": [{
"type": "command",
"command": "FILE=$(echo \"$CLAUDE_TOOL_OUTPUT\" | jq -r '.file_path'); if [[ \"$FILE\" == *openapi.yaml ]] || [[ \"$FILE\" == *schema.prisma ]]; then npm run generate --silent 2>&1 | tail -10; fi"
}]
}]
} Matchery i tool patterns
Matcher dla PreToolUse i PostToolUse to nazwa narzędzia. Możesz użyć pipe | żeby objąć kilka narzędzi: "matcher": "Edit|Write". Najczęstsze nazwy:
Bash, wywołania shellEdit, edycja istniejącego plikuWrite, utworzenie nowego plikuRead, odczyt plikuGlob, szukanie plików po wzorzeGrep, szukanie w treści plikówWebFetch, fetch URLWebSearch, search web
Dla MCP tools matcher to mcp__<server_name>__<tool_name>, np. mcp__github__create_issue.
Zmienne środowiskowe w hookach
Claude Code podaje do hookow zmienne ENV z kontekstem aktualnej operacji:
CLAUDE_TOOL_NAME, nazwa narzędzia (np. "Bash", "Edit")CLAUDE_TOOL_INPUT, JSON inputu do narzędziaCLAUDE_TOOL_OUTPUT, JSON outputu (tylko w PostToolUse)CLAUDE_SESSION_ID, unikalny ID sesjiCLAUDE_USER_PROMPT, ostatni prompt użytkownika (tylko w UserPromptSubmit)
W skrypcie hooka używasz ich jak normalne env vars: $CLAUDE_TOOL_INPUT. Parsuj JSON przez jq dla łatwego dostępu do pól.
Antywzorce, czego unikać
- Zbyt rygorystyczne blokady, jeśli zablokujesz
rmcałkowicie, Claude nie usunienode_modulesprzed reinstall. Bądź selektywny (rm -rf na critical paths). - Slow hooks, hook PreToolUse który trwa 5s blokuje każdą operację o 5s. Trzymaj hooki pod 1s. Wszystko cięższe (testy, lint full) → Stop hook.
- Niedeterministyczne hooks, hook który czasem fail, czasem pass = nieprzewidywalny Claude. Każdy hook powinien być reprodukowalny.
- Brak echo w blokadach, jeśli blokujesz coś, zawsze drukuj wyjaśnienie do stdout/stderr. Claude pokaże to userowi.
- Hardcoded paths, używaj zmiennych env i
$(pwd), hook ma działać niezależnie od lokalizacji.
Troubleshooting
Najczęstsze problemy z hookami i jak je naprawić:
- Hook nie odpala się, sprawdź syntax JSON (npx jsonlint
.claude/settings.json). Najczęstsza przyczyna 90% problemów. - Hook fail-y zawsze, dodaj
echo "hook fired with input: $CLAUDE_TOOL_INPUT"na początku i sprawdź czy zmienne są tym, czym myślisz. - Hook za wolny, profiluj
time <komenda>. Sprawdź czy używasz cache (npm install, prettier --check zamiast --write na dużej liście plików). - Permission denied, hook to dowolny shell, więc musi być wykonywalny. Skrypty Python/Node potrzebują shebang lub explicit interpreter.
- Logi nigdzie nie idą, sprawdź
~/.claude/logs/oraz uruchom Claude Code z flagą--debug.
Co dalej
Hooks to początek. Pełen workflow z Claude Code to hooks + slash commands + MCP servers + Agent SDK + Anthropic API. Każda warstwa ma swoją niszę:
- Claude Code tutorial po polsku, kompletny przewodnik
- Claude Code MCP Server po polsku (nadchodzące)
- Claude Agent SDK po polsku (nadchodzące)
- Claude Code vs Cursor
Hooks template pack w kursie
W Kursie Claude Code po polsku (349 zł brutto, 220 stron PDF, dożywotni dostęp) dostajesz pack 10 production-ready hooków + dokumentację każdego + repo GitHub template. Plus moduł 4 dedykowany hookom (25 stron) z deeper dive niż ten artykuł.
Najczęściej zadawane pytania
Co to są hooks w Claude Code?
Hooks to konfigurowalne triggery uruchamiane w określonych momentach sesji Claude Code, np. przed użyciem narzędzia (PreToolUse), po edycji pliku (PostToolUse), gdy użytkownik wysyła prompt (UserPromptSubmit), na zakończenie (Stop), na początku sesji (SessionStart). Pozwalają automatyzować workflow, blokować destrukcyjne komendy, dodawać validację i kontekst.
Gdzie zapisuje się konfigurację hooków?
W pliku .claude/settings.json w roocie projektu (per-projekt) lub ~/.claude/settings.json (globalnie). Per-projekt zawsze nadpisuje globalne. Hooks działają od momentu zapisania pliku, nie wymagają restartu sesji Claude Code.
Czy hooks blokują komendy?
Tak. Jeśli hook PreToolUse zwróci exit code różny od 0, Claude Code zablokuje wykonanie narzędzia. Hook wyświetli też swój stdout w logu, więc możesz przekazać użytkownikowi wyjaśnienie czemu został zablokowany.
Jakie są typowe use case dla hooków?
Pięć najczęstszych: 1) Blokuj rm -rf i inne destrukcyjne komendy. 2) Auto-formatuj kod po każdej edycji (Prettier, ruff). 3) Dodawaj kontekst do każdego prompta (np. nazwa branchu, autor). 4) Uruchamiaj testy automatycznie na zakończenie sesji. 5) Loguj wszystkie tool uses do audytu.
Czy hook może modyfikować input narzędzia?
Tak, dla niektórych typów hooków. PreToolUse może zmienić lub zatrzymać wywołanie. UserPromptSubmit może wzbogacić prompt o dodatkowy kontekst (np. dodać aktualną gałąź gita). PostToolUse jest informational, nie modyfikuje rezultatu.
Czy hooks działają w Claude Code w CI?
Tak, ale wymaga uwagi. W CI Claude Code jest uruchamiany headless (przez Claude Agent SDK), więc hooks muszą być deterministyczne i nie zależeć od interaktywnego inputu. Też pamiętaj o env vars i sciezkach absolutnych.
Jak debugować hook który nie działa?
1) Sprawdź ~/.claude/logs/. 2) Uruchom Claude Code z flagą --debug. 3) Dodaj echo "hook fired" na początku komendy hooka, pojawi się w outputcie. 4) Sprawdź syntax JSON w settings.json (najczęstsza przyczyna).
Czy mogę użyć hooków Python / Node zamiast bash?
Tak. Komenda w hooku to dowolne wywołanie shell, więc python ./hooks/validate.py lub node ./hooks/check.js działają normalnie. Pamiętaj że hook musi być szybki (typowo < 1s) i zwracać exit code.
Czy hooks działają z Claude Agent SDK?
Tak. Hooks definiujesz w settings.json i działają zarówno w Claude Code CLI jak i w skryptach używających Claude Agent SDK (oba czytają tę samą konfigurację).
Czy są gotowe hooki do pobrania?
Tak. W Kursie Claude Code po polsku dostajesz pack 10 gotowych hooków template (deny destructive, auto-format, pre-commit lint, custom validation, session start init). Inne hooki znajdziesz w Anthropic docs i community repo.
Jak wyłączyć tymczasowo hook?
Możesz zakomentować obiekt w settings.json (JSON nie wspiera komentarzy, ale możesz wynieść konfigurację do oddzielnego pliku i zmienić ścieżkę). Albo użyj flagi --disable-hooks przy starcie Claude Code.
Czy hook może być asynchroniczny?
Nie. Hooks są synchroniczne, Claude Code czeka na exit code przed kontynuacją. Jeśli potrzebujesz async work, zrób fire-and-forget (command &) z pełną świadomością, że jego rezultat nie wpłynie na sesję.
Powiązane artykuły
Claude Code cena 2026, ile kosztuje i czy jest darmowy
Claude Code cena w PLN i USD, plany Pro i Max, API pay-as-you-go, darmowe kredyty i alternatywy. Najtańsza legalna ścieżka. Stan maj 2026.
CzytajClaude Max plan po polsku, ceny i limity 2026
Plan Claude Max po polsku: ceny Max 5x i 20x, ile zapytań daje, Claude Pro vs Max, Max vs API. Limity sesji i tygodniowe. Stan maj 2026, dla kogo warto.
CzytajClaude Code Skills po polsku, tutorial Agent Skills 2026
Pierwszy polski tutorial Agent Skills w Claude Code. SKILL.md, frontmatter, progressive disclosure, jak tworzyć skille krok po kroku, vs subagents i MCP.
CzytajChcesz profesjonalnie nauczyć się tworzenia video AI?
6 modułów PDF + społeczność Discord. Dożywotni dostęp.