Shrnutí
Claude Code hooks jsou shell příkazy, které se spouštějí automaticky kolem volání nástrojů — před tím, než se příkaz spustí, po tom, co se zapíše soubor, když agent čeká na vstup. Žijí v settings.json, mohou volání nástroje rovnou zablokovat a jsou jediný mechanismus v celém stacku, který agent nedokáže obejít. Pokud provozujete Claude Code na čemkoli, co se dotýká produkce, a ještě nemáte hooks nakonfigurované, je to ten největší upgrade spolehlivosti, který máte k dispozici.
Tenhle průvodce projde tři typy hooks, schema v settings.json, kontrakt na exit kódy a tři vzory, které nasazuju do každého repa, kterého se dotknu.
Proč hooks existují
Prompty jsou doporučení. Hooks jsou smlouvy.
Do CLAUDE.md můžete napsat „vždycky spusť pnpm format po úpravě kódu" a agent to většinou dodrží. Většinou nestačí, když cenou za selhání je rozbitý main branch, uniklý secret nebo PR, který potichu obejde vaše lint pravidla. Hooks tu mezeru zavírají — posouvají chování z „model se snaží poslouchat" na „systém to vynucuje".
Viděl jsem týmy strávit týdny debatováním nad zněním CLAUDE.md, aby model dotlačily ke svým konvencím. Deset řádků hooku dělá to samé deterministicky.
Tři typy hooks
PreToolUse — běží před spuštěním nástroje
Dostane jméno nástroje a argumenty. Může volání schválit, zamítnout, nebo ho pustit s varováním. Nejdůležitější hook ve vašem setupu, protože tady se blokují akce, na kterých vám skutečně záleží.
Typické použití:
- Zablokovat
rm -rfmimo sandbox adresář - Zablokovat
git push --forcenamain/master - Odmítnout
Bashvolání, která obsahují zjevné secrets nebo credentials - Vynutit, aby
Writenikdy nesáhl namigrations/nebosrc/auth/bez explicitního approval flagu
PostToolUse — běží po spuštění nástroje
Dostane jméno nástroje, argumenty a výsledek. Nedokáže volání vrátit zpět, ale umí formátovat, validovat, logovat. Tady reálně bydlí „agent nemůže zapomenout naformátovat".
Typické použití:
- Automaticky spustit
prettier --write(neboblack,gofmt,rustfmt) po každémWrite - Přidat záznam do changelogu po editu package.json
- Vypustit strukturovaný log záznam pro audit
- Spustit rychlý lint a ohlásit chyby zpět agentovi
Notification — běží, když agent potřebuje vstup
Dostane prompt, na který agent čeká. Ideální pro „desktop notifikaci, když Claude stojí" a podobnou low-stakes automatizaci.
Typické použití:
- Pingnout macOS notification center, abyste se vrátili k agentovi, co čeká už dvě minuty
- Poslat zprávu do Slack kanálu, když agent chce lidský review
- Pípnout — ano, obyčejný terminálový zvonek je pořád nejrychlejší způsob, jak vás upozornit
Schema v settings.json
Hooks se konfigurují v .claude/settings.json (per projekt) nebo ~/.claude/settings.json (per uživatel). Projektové nastavení vyhrává.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/block-dangerous-bash.sh"
}
]
}
],
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/format.sh"
}
]
}
]
}
}
Dvě věci, které stojí za to vědět:
matcherje regex na jméno nástroje."Bash"matchne jen Bash."Write|Edit"matchne oba.".*"matchne všechno — užitečné, občas nebezpečné.commanddostane vstup nástroje jako JSON na stdin. Váš skript ho parsne, rozhodne co dělat, skončí.
Kontrakt na exit kódy
Tohle je část, na které lidi nejčastěji padají.
- Exit 0 — schvaluji (pro PreToolUse) nebo no-op (pro PostToolUse). Volání nástroje pokračuje.
- Exit 2 — blokuji. Volání nástroje je zamítnuto. Stderr vašeho skriptu se ukáže agentovi jako důvod blokace. Takhle se z „prosím ne" stane „systém to nedovolí".
- Jakýkoli jiný non-zero — chyba. Volání selže, ale jako error, ne jako záměrná blokace. Rezervujte si to pro skutečné selhání hooku.
Pište jasné stderr zprávy u exit 2. Agent je čte a přizpůsobí se. „Blokováno: force-push na main není povolený, otevřete PR" agentovi říká, co má dělat dál. „Error" ho nenaučí nic.
Tři vzory, které nasazuju do každého repa
Vzor 1: blokuj destruktivní Bash
#!/usr/bin/env bash
# .claude/hooks/block-dangerous-bash.sh
set -euo pipefail
input=$(cat)
command=$(echo "$input" | jq -r '.tool_input.command // ""')
if echo "$command" | grep -qE '(rm -rf /|git push.*--force.*main|git push.*-f.*main)'; then
echo "Blokováno: detekován destruktivní příkaz" >&2
exit 2
fi
exit 0
Pokrývá 90 % případů „agent rozmlátil repo" deseti řádky. Regex časem rozšiřujte, jak budou přibývat nové footguny.
Vzor 2: automatický formát po zápisu
#!/usr/bin/env bash
# .claude/hooks/format.sh
set -euo pipefail
input=$(cat)
file_path=$(echo "$input" | jq -r '.tool_input.file_path // ""')
case "$file_path" in
*.ts|*.tsx|*.js|*.jsx|*.json|*.md|*.mdx)
pnpm prettier --write "$file_path" >/dev/null 2>&1 || true
;;
*.py)
ruff format "$file_path" >/dev/null 2>&1 || true
;;
*.go)
gofmt -w "$file_path" >/dev/null 2>&1 || true
;;
esac
exit 0
Všimněte si || true — selhání formátteru by nemělo agenta zablokovat, prostě se přeskočí. Další lint reálné problémy stejně vytáhne.
Vzor 3: vyžaduj explicitní approval pro citlivé cesty
#!/usr/bin/env bash
# .claude/hooks/guard-sensitive-paths.sh
set -euo pipefail
input=$(cat)
file_path=$(echo "$input" | jq -r '.tool_input.file_path // ""')
case "$file_path" in
*migrations/*|*src/auth/*|*.env*)
if [ ! -f ".claude/allow-sensitive.flag" ]; then
echo "Blokováno: $file_path je citlivý. Pokud to opravdu chcete editovat, vytvořte pro tuhle session .claude/allow-sensitive.flag." >&2
exit 2
fi
;;
esac
exit 0
Vzor s flag souborem vám dává explicitní bránu „vím, co dělám". Agent si flag sám vytvořit nemůže — to děláte vy. Po session ho smažete. Paranoidní, levné, funguje.
Debugging hooks
Tři věci na zkontrolování, když hook „nefunguje":
- Je
settings.jsonvalidní JSON? Claude Code tiše ignoruje rozbitou konfiguraci. Pro jistotu spusťtejq . .claude/settings.json. - Je skript spustitelný?
chmod +x .claude/hooks/*.sh. Tohle jsem přehlédl víckrát, než bych chtěl přiznat. - Čte se stdin? Pokud váš skript visí, nejspíš čeká na stdin. Vždycky
input=$(cat)na začátku.
Logujte během vývoje verbose:
echo "hook invoked: $(date) $0" >> .claude/hooks.log
echo "$input" >> .claude/hooks.log
Po odladění logování smažte.
Kam hooks zapadají v širším obrazu
Hooks jsou jeden ze šesti stavebních bloků, které popisuju v delším postu o nasazení AI. CLAUDE.md dává agentovi kontext, skilly mu dávají opakovaně použitelné recepty, hooks vynucují invarianty. Dohromady je v tom rozdíl mezi agentem, který vás občas překvapí, a agentem, který se chová jako spolehlivý kolega.
Pokud váš tým zavádí Claude Code a tahle část vám přijde mlhavá, napište mi — vedu on-site školení, která přesně tohle procházejí. me@jakubkontra.com