W poście o konfiguracji wspomniałem o 11 hookach. Od tamtej pory liczba wzrosła. Teraz mam 23 skrypty shell podpięte pod różne zdarzenia Claude Code: blokują wdrożenia produkcyjne, automatycznie formatują TypeScript, wysyłają wiadomości Telegram, gdy Claude potrzebuje mojej uwagi.
Hooki to prawdopodobnie najbardziej niedoceniana część systemu konfiguracji Claude Code. Komendy przyciągają uwagę, bo się je wpisuje. Hooki są niewidoczne, dopóki nie są potrzebne.
Czym jest hook
Hook to skrypt shell uruchamiany w odpowiedzi na zdarzenie Claude Code. Rejestrujesz go w settings.json pod kluczem hooks. Gdy zdarzenie wystąpi, Claude Code uruchamia skrypt i decyduje co dalej na podstawie kodu wyjścia.
Konfiguracja wygląda tak:
| |
matcher filtruje, które wywołania narzędzi wyzwalają hook. "Bash" łapie wszystkie wywołania Bash. "Write" łapie zapisy do plików. "mcp__" łapie wszystko związane z MCP. Pusty string łapie wszystko.
Kody wyjścia sterują zachowaniem:
0: zezwól na wywołanie narzędzia2: zablokuj je, a stderr hooka pojawi się w Claude jako powód
Dla hooków PostToolUse blokowanie nie jest możliwe, ale można wstrzyknąć tekst do kontekstu Claude przez stdout.
Skrypty otrzymują pełny input narzędzia jako JSON na stdin. Możesz więc sprawdzić rzeczywiste polecenie, ścieżkę pliku lub zawartość pliku przed podjęciem decyzji.
PreToolUse: strażnicy
Tu dzieje się większość pracy związanej z bezpieczeństwem. Mam hooki na zdarzenia Bash, Write i Edit.
Blokowanie niebezpiecznych poleceń
block-prod.sh wypatruje wzorców wdrożeń produkcyjnych:
| |
Nie zablokuje wszystkiego. Nie o to chodzi. To sprawdzenie bezpieczeństwa na wypadek, gdybym powiedział “wdróż usługę auth” i zapomniał podać środowisko. Claude powinien zapytać, nie zakładać.
docker-guard.sh chroni konkretne kontenery infrastrukturalne przed przypadkowym zatrzymaniem. Nazwy są wystarczająco specyficzne, żeby regex był prosty:
| |
Efemeryczne kontenery runner są zatrzymywane cały czas. Kontenery infrastrukturalne nie. Wyjątek dla runner- przepuszcza normalną operację.
branch-guard.sh blokuje force push:
| |
Prosto i bez kompromisów.
Ochrona plików i sekretów
protect-configs.sh blokuje zapisy do /etc/, .ssh/ i plików .env:
| |
Dla niektórych plików tylko ostrzega i kontynuuje. Modyfikacje .mcp.json wypisują ostrzeżenie, ale go nie blokują. Celowo. Ostrzeżenie trafia do kontekstu Claude, więc kontynuuje ze świadomością.
secret-scanner.sh sprawdza zawartość pliku przed zapisem. Skanuje wzorce wyglądające jak prawdziwe klucze API:
| |
Pomija znane bezpieczne pliki jak .mcp.json i settings.json, które legalnie zawierają klucze lub odniesienia do nich.
strategy-validator.sh działa przed wywołaniami narzędzia Skill. Jeśli ktoś poda --strategy z nieprawidłową nazwą, blokuje i wypisuje listę poprawnych opcji. To ważne, bo mam dużo skilli z domyślnymi strategiami wbudowanymi w kod, a literówka mogłaby się cicho ześlizgnąć do złego zachowania.
PostToolUse: po fakcie
Działają po zakończeniu wywołania narzędzia. Brak możliwości blokowania, ale można logować, formatować i wstrzykiwać kontekst.
audit-log.sh dopisuje każde polecenie Bash z timestampem do pliku logu. Prosto:
| |
Kilka tygodni takiego logu jest zaskakująco przydatne, gdy próbujesz sobie przypomnieć, co naprawdę uruchomiłeś we wtorek.
auto-format.sh uruchamia Prettier na każdym pliku TypeScript po edycji. Uratował mnie przed zacommitowaniem nieformatowanego kodu więcej niż raz. Działa cicho i dotyczy tylko plików .ts i .tsx.
mcp-audit.sh loguje wywołania narzędzi MCP osobno. Chcę wiedzieć, jakich zewnętrznych usług używa Claude, szczególnie w sesjach, gdzie pracuję nad automatyzacją.
Hooki sesji: wstrzykiwanie kontekstu
Hooki cyklu życia sesji są najbardziej interesujące. Pozwalają wstrzykiwać informacje do kontekstu Claude w konkretnych momentach.
SessionStart
session-context.sh uruchamia się na początku każdej sesji i wstrzykuje krótki status systemu:
| |
Gałąź git, miejsce na dysku, pamięć, uruchomione kontenery, aktywne workery. Wszystko, czego Claude może potrzebować, żeby dawać mi dokładne odpowiedzi bez podawania tego samego kontekstu na nowo. Nie muszę mówić “jestem na gałęzi feature z 3 zmodyfikowanymi plikami.” Już wie.
UserPromptSubmit
Uruchamia się przed każdą moją wiadomością. Mam tu dwa hooki.
prompt-enhance.sh wypatruje promptów związanych z git i wstrzykuje aktualny stan gałęzi. Jeśli wpiszę “zacommituj to,” już wie, na której gałęzi jestem i ile plików jest staged.
telos-context.sh wypatruje słów kluczowych związanych z karierą lub celami i wstrzykuje przypomnienie, żeby zajrzeć do pliku z celami. To bardziej osobista rzecz. Jeśli wspomnę coś jak “czy powinienem skupić się na tej certyfikacji,” hook odpala i mówi Claude, żeby przeczytał odpowiedni plik pamięci przed odpowiedzią. To sposób na spójność rady z długoterminowym kierunkiem, nie tylko bieżącym pytaniem.
Notification: Telegram kiedy trzeba
Zdarzenie Notification odpala się, gdy Claude potrzebuje ludzkiej decyzji. Domyślnie to dzwonek w terminalu. Mam to ustawione nieco szerzej:
| |
Lookup tokena bota z Vault jest trochę ciężki, ale dzięki temu credentials nie leżą w samym pliku hooka. Instrukcja case pomija Telegram dla rutynowych ukończeń podzadań, bo inaczej odpala się co kilka minut podczas długich sesji agentów.
Dostanę ping na Telegram, gdy Claude trafi na prompt uprawnień, potrzebuje decyzji albo skończył zadanie wymagające mojego inputu. Rutynowe ukończenia zostają ciche.
Co w praktyce zostało zablokowane
Większość blokad w pierwszym miesiącu dotyczyła przypadków brzegowych, o których nie pomyślałem. Secret scanner odpalił dwa razy w pierwszym tygodniu, gdy pracowałem na przykładach integracyjnych z ciągami wyglądającymi jak placeholdery. block-prod.sh złapał jedno prawdziwe prawie-nieporozumienie, gdy prosiłem Claude o pomoc z upgradeem Helm bez podania środowiska.
Hooki ochrony plików są głównie prewencyjne. Nigdy nie zablokowały czegoś, czego chciałem. Taki jest cel: niski wskaźnik fałszywych pozytywów, okazjonalne prawdziwe ratowanie.
Hooki powiadomień są naprawdę przydatne. Pracując w terminalu, łatwo przegapić moment, gdy długa sesja agenta potrzebuje uwagi. Ping na Telegram pozwala odejść od komputera i wrócić, gdy jest to istotne.
Struktura hooka
Jeśli piszesz własny, podstawowy szkielet wygląda tak:
| |
Struktura JSON inputu różni się zależnie od typu hooka. Dla hooków Bash .tool_input.command to string z poleceniem. Dla hooków Write/Edit masz .tool_input.file_path i .tool_input.content lub .tool_input.new_string. Pełna struktura jest w dokumentacji Claude Code.
Warto wiedzieć: hooki działają w kolejności z settings.json. Jeśli masz trzy hooki PreToolUse na Bash, wszystkie trzy się uruchamiają. Pierwsze exit 2 wygrywa.
Czy warto?
Tak, ale zwrot jest nierówny. Hooki bezpieczeństwa opłacają się sporadycznie i działają jak ubezpieczenie. Hooki wstrzykiwania kontekstu opłacają się w każdej sesji, bo startowanie z dokładnym stanem systemu jest po prostu lepsze niż proszenie o niego.
Hooki powiadomień opłacają się proporcjonalnie do tego, jak często uruchamiasz długie sesje. Jeśli używasz Claude Code tylko do szybkich edycji, nie potrzebujesz Telegrama. Jeśli uruchamiasz zadania wielu agentów trwające 10 minut, ping jest przydatny.
Zacznij od protect-configs.sh i secret-scanner.sh. Są tanie w konfiguracji, a koszt braku ich jest credential w historii git. Potem dodaj wstrzykiwanie kontekstu, jeśli odkryjesz, że podajesz ten sam kontekst w każdej sesji. Reszta to optymalizacja.
Powiązane: Moja konfiguracja Claude Code | Własne komendy | Komendy DevOps
