Spis treści
- Który hook do jakiej sytuacji
- Czego potrzebujesz
- Krok 1 — Utwórz dwa kanały
- Krok 2 — Dodaj hooki
- Krok 3 — Przetestuj bez czekania na prawdziwą prośbę
- Krok 4 — Spraw, by kanał blokady dzwonił
- Jak uniknąć przeładowania powiadomieniami
- Claude Code zdalnie lub w CI
- Rozwiązywanie problemów
- Najczęstsze pytania
- Jak dostać powiadomienie, gdy Claude Code potrzebuje zgody?
- Skąd wiem, że Claude Code skończył zadanie?
- Czy powiadomienie może przebić tryb Nie przeszkadzać?
- Czy to działa w Claude Code w przeglądarce albo w sesjach zdalnych?
- Czy adres URL webhooka można bezpiecznie trzymać w settings.json?
- Podsumowanie
- Powiązane artykuły
Claude Code zatrzymuje się w dwóch istotnych sytuacjach: utknął w oczekiwaniu na Ciebie (prośba o zgodę, pytanie) albo skończył pracę. Jeśli nie patrzysz w terminal, obie wyglądają tak samo — nic się nie dzieje, a sesja stoi bezczynnie, aż wrócisz. Rozwiązaniem jest hook: kilka linijek w settings.json, które w chwili wystąpienia jednej z tych sytuacji wysyłają webhook na Twój telefon.
Ten przewodnik daje konfigurację do skopiowania, wyjaśnia, którego zdarzenia hooka użyć w której sytuacji, i omawia szczegóły, dzięki którym całość działa niezawodnie: odczyt danych wejściowych hooka, cudzysłowy w powłoce i unikanie zalewu powiadomień.
Który hook do jakiej sytuacji
Claude Code uruchamia hooki przy zdarzeniach cyklu życia. Ten problem pokrywają dwa z nich (dokumentacja hooków):
| Chcesz wiedzieć, kiedy… | Zdarzenie hooka | Matcher / filtr |
|---|---|---|
| Claude czeka na decyzję o zgodzie | Notification | permission_prompt |
| Claude jest bezczynny i czeka na Twoje dane | Notification | idle_prompt |
| Claude skończył odpowiadać | Stop | niepotrzebny |
Pole matcher hooka Notification filtruje po typie powiadomienia, więc możesz dokładnie wybrać, które z nich trafią na telefon. Dane wejściowe przychodzą jako JSON na stdin i zawierają notification_type, message, cwd oraz session_id. Hooki Notification nie mogą niczego zablokować ani zmienić — są tylko obserwatorami, a tutaj właśnie tego chcesz.
Dane wejściowe Stop zawierają last_assistant_message, czyli ostatni tekst wygenerowany przez Claude'a. To gotowa linijka podsumowania do powiadomienia.
Czego potrzebujesz
- Echobella na telefonie (App Store / Google Play)
curlijqna maszynie, na której działa Claude Code- Dwóch minut
Krok 1 — Utwórz dwa kanały
Nie wysyłaj wszystkiego do jednego kanału. W Echobellu utwórz:
- Claude zablokowany, typ Time Sensitive lub Calling — dla próśb o zgodę, gdy agent stoi, a każda minuta to zmarnowana moc obliczeniowa i czas
- Claude skończył, typ Normal — zwykły push, do przeczytania, kiedy wygodnie
Skopiuj adres URL webhooka każdego kanału. Wygląda tak: https://hook.echobell.one/t/<channel-token>. Traktuj go jak hasło: każdy, kto go ma, może zadzwonić na Twój telefon.
Zapisz oba jako zmienne środowiskowe, żeby nigdy nie trafiły do commitowanego pliku konfiguracyjnego:
export ECHOBELL_CLAUDE_BLOCKED_URL="https://hook.echobell.one/t/<blocked-token>"
export ECHOBELL_CLAUDE_DONE_URL="https://hook.echobell.one/t/<done-token>"
Dodaj je do profilu powłoki, żeby Claude Code je odziedziczył.
Krok 2 — Dodaj hooki
Dodaj poniższe do ~/.claude/settings.json, by działało w każdym projekcie, albo do .claude/settings.local.json dla jednego repozytorium:
{
"hooks": {
"Notification": [
{
"matcher": "permission_prompt",
"hooks": [
{
"type": "command",
"command": "jq -c '{title: \"Claude potrzebuje zgody\", body: .message, project: (.cwd | split(\"/\") | last)}' | curl -sS -m 10 -X POST -H 'Content-Type: application/json' -d @- \"$ECHOBELL_CLAUDE_BLOCKED_URL\""
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "jq -c '{title: \"Claude skończył\", body: (.last_assistant_message // \"Gotowe\" | .[0:200]), project: (.cwd | split(\"/\") | last)}' | curl -sS -m 10 -X POST -H 'Content-Type: application/json' -d @- \"$ECHOBELL_CLAUDE_DONE_URL\""
}
]
}
]
}
}
Co robi każdy element:
jq -c '{...}'czyta JSON hooka ze stdin i buduje mały payload, dzięki czemu Echobell dostaje dokładnie te pola, które chcesz, a nie cały dokument hooka..cwd | split("/") | lastzamienia/home/me/code/apinaapi, więc powiadomienie mówi, który projekt o Ciebie prosi..[0:200]skraca ostatnią wiadomość. Treść powiadomienia jest ograniczona przez workera Echobella do 1500 bajtów, a ekran blokady i tak pokazuje znacznie mniej.-m 10dajecurlowi10-sekundowy limit czasu, żeby problem z siecią nie zostawił Claude Code czekającego na Twój hook.
Echobell renderuje wysłane klucze przez szablony kanału, a nowy kanał nie ma szablonu, który by je odczytywał — ustaw je w ustawieniach kanału: szablon tytułu {{title}}, szablon treści {{body}}. Dodaj {{project}} do któregoś z nich, jeśli chcesz widzieć nazwę projektu, na przykład {{title}} ({{project}}).
Krok 3 — Przetestuj bez czekania na prawdziwą prośbę
Uruchom ten sam potok ręcznie z fałszywym payloadem hooka:
echo '{"message":"Claude potrzebuje Twojej zgody na użycie Bash","cwd":"/home/me/code/api","notification_type":"permission_prompt"}' \
| jq -c '{title: "Claude potrzebuje zgody", body: .message, project: (.cwd | split("/") | last)}' \
| curl -sS -m 10 -X POST -H 'Content-Type: application/json' -d @- "$ECHOBELL_CLAUDE_BLOCKED_URL"
Jeśli telefon się zaświeci, strona Echobella działa, a ewentualny problem leży w sposobie, w jaki Claude Code czyta konfigurację. W Claude Code uruchom /hooks, by potwierdzić załadowanie hooków; zmiany ustawień wprowadzone w trakcie sesji mogą wymagać wejścia do menu hooków albo restartu.
Krok 4 — Spraw, by kanał blokady dzwonił
Zwykły push przegrywa z trybem Nie przeszkadzać. Kanał Calling zachowuje się jak połączenie przychodzące i przebija tryb Skupienia w iOS, co ma największe znaczenie, gdy zaczynasz długie zadanie i wychodzisz na cały wieczór. Jeśli chcesz, by przerywano Ci tylko przy niektórych prośbach, zamiast edytować hook użyj warunku kanału w Echobellu na wysyłanych zmiennych, na przykład project == "api". Pełną listę zmiennych znajdziesz w dokumentacji warunków.
Jak uniknąć przeładowania powiadomieniami
Intensywna sesja potrafi wywołać wiele zdarzeń Stop — każda odpowiedź kończy się jednym. Trzy sposoby, by zachować sygnał:
- Nie wysyłaj
Stopna dzwoniący kanał. Ukończenie nie jest pilne; zostaw je na Normal. - Użyj
idle_promptzamiastStop, jeśli chcesz wiedzieć tylko o tym, że Claude się zatrzymał i czeka na Ciebie, a nie po każdej odpowiedzi. - Zawęź po projekcie warunkiem, żeby repozytorium do eksperymentów w ogóle nie powiadamiało.
Claude Code zdalnie lub w CI
To samo podejście działa w środowiskach chmurowych i zdalnych, bo hook to zwykłe wychodzące żądanie HTTPS. Nic nie musi być dostępne z internetu. Ustaw dwie zmienne środowiskowe w sekretach środowiska zamiast w profilu powłoki, a powiadomienie dotrze na telefon niezależnie od tego, gdzie działa sesja.
Rozwiązywanie problemów
Nic nie przychodzi, a test ręczny też zawodzi. Sprawdź, czy zmienna z adresem URL jest ustawiona w powłoce, która uruchamia Claude Code: echo "$ECHOBELL_CLAUDE_BLOCKED_URL". Pusta zmienna sprawia, że curl zawodzi po cichu.
Test ręczny działa, ale hook się nie uruchamia. Sprawdź matcher: permission_prompt i idle_prompt to różne wartości, a matcher, który nie pasuje, po prostu nigdy się nie uruchomi. Wykonaj /hooks i sprawdź, czy JSON jest poprawny — zbędny przecinek na końcu wyłącza wszystkie hooki z całego pliku ustawień.
Treść powiadomienia jest pusta. Filtr jq odwołał się do pola, które nie istnieje dla tego zdarzenia. message występuje w danych Notification, a last_assistant_message w danych Stop. Użyj //, by podać wartość domyślną, jak w konfiguracji powyżej.
Uruchamia się zbyt często. Zobacz sekcję wyżej — przejdź ze Stop na idle_prompt albo dodaj warunek.
Najczęstsze pytania
Jak dostać powiadomienie, gdy Claude Code potrzebuje zgody?
Dodaj hook Notification z matcherem permission_prompt, który wysyła webhook na kanał. Echobell zamienia to żądanie na push albo alert w formie połączenia na Twoim telefonie.
Skąd wiem, że Claude Code skończył zadanie?
Dodaj hook Stop. Uruchamia się, gdy Claude kończy odpowiadać, a jego dane wejściowe zawierają last_assistant_message, którego możesz użyć jako treści powiadomienia.
Czy powiadomienie może przebić tryb Nie przeszkadzać?
Tak, jeśli kanał odbierający jest kanałem Calling. Zachowuje się jak połączenie przychodzące, które tryb Skupienia w iOS przepuszcza. Zwykły push z dowolnej aplikacji tego nie potrafi.
Czy to działa w Claude Code w przeglądarce albo w sesjach zdalnych?
Tak. Hook wykonuje tylko wychodzące żądanie HTTPS, więc działa wszędzie tam, gdzie sesja ma dostęp do internetu. Adresy URL kanałów przekaż przez sekrety środowiska.
Czy adres URL webhooka można bezpiecznie trzymać w settings.json?
Lepiej użyć zmiennej środowiskowej, jak wyżej, żeby token nie trafił do repozytorium. Jeśli wycieknie, utwórz nowy kanał i wycofaj stary.
Podsumowanie
Dwa kanały, dwa hooki i potok jq | curl: kanał Calling lub Time Sensitive dla permission_prompt, kanał Normal dla Stop. Potem możesz zacząć długie zadanie agenta, wyjść z pokoju i wracać tylko wtedy, gdy agent naprawdę Cię potrzebuje.
Pobierz Echobella na iPhone'a albo weź go z Google Play, a potem uruchom powyższy test ręczny, zanim powierzysz tej ścieżce długie zadanie.