Przejdź do głównej zawartości

Terminal dla Claude Code: tmux, powiadomienia i potoki

Terminal dla Claude Code to jedna sesja tmux na repozytorium: Claude Code w głównym panelu, a obok testy w trybie watch, narzędzie sprawdzające typy (np. tsc) i serwer deweloperski w panelach, które Claude odczytuje przez tmux capture-pane. Hook Notification wysyła alert tylko wtedy, gdy Claude Code czeka na programistę. Polecenia sprawdzono na Claude Code 2.1.283 i tmux 3.4.

Ta strona jest dla programistów, którzy już codziennie pracują z Claude Code w terminalu. Zlecasz poprawkę, przełączasz się do przeglądarki i po 20 minutach odkrywasz, że sesja od drugiej minuty stoi na prośbie o uprawnienia. Albo Claude melduje „wszystkie testy przechodzą”, a narzędzie do uruchamiania testów w innej karcie od trzech edycji świeci na czerwono. Rozwiązaniem jest układ, w którym dowody są zawsze na ekranie, a agent czyta te same dowody co ty.

  • Przetestowany skrypt tmux, który otwiera Claude Code obok paneli z testami, sprawdzaniem typów i serwerem, i przekazuje Claude’owi identyfikatory tych paneli.
  • Prompt, który każe Claude’owi czytać te panele i kończyć każde zadanie ich wyjściem jako dowodem.
  • Alerty tylko o prośbach o uprawnienia i bezczynnych sesjach, działające w tmux, na macOS i Linuksie.
  • Pasek stanu z modelem, katalogiem i gałęzią pod każdym promptem, żebyś nie wpisał polecenia w zły panel.
  • Zadania poboczne we własnym worktree i własnej sesji tmux jednym poleceniem: claude -w NAZWA --tmux.
  • Funkcję powłoki why, która przekazuje wyjście nieudanego polecenia do Claude’a działającego w trybie tylko do odczytu.

Flagi i polecenia slash, na których to stoi, mają osobną stronę: wiersz poleceń Claude Code. Ta strona dotyczy terminala wokół nich.

Jakich ustawień terminala Claude Code potrzebuje na start?

Dział zatytułowany „Jakich ustawień terminala Claude Code potrzebuje na start?”

Trzy ustawienia decydują, czy reszta zadziała. Zrób je raz na maszynę, w tej kolejności.

  1. Włącz prompty wielowierszowe. Uruchom /terminal-setup w Claude Code w zewnętrznym terminalu (nie w tmux). W Apple Terminal włącza to Option+Enter jako nową linię; w terminalach, które natywnie obsługują Shift+Enter, potwierdza konfigurację. Wszędzie działa wpisanie \, a potem Enter.

  2. Wybierz kanał powiadomień. Otwórz /config i ustaw kanał powiadomień (zapisywany jako preferredNotifChannel w ~/.claude.json). W wersji 2.1.283 dostępne wartości to auto, iterm2, terminal_bell, iterm2_with_bell, kitty, ghostty i notifications_disabled. auto rozpoznaje wyłącznie iTerm2, kitty, Ghostty i Apple Terminal, więc w tmux auto nie znajduje żadnej metody i milczy. Jeśli pracujesz w tmux, ustaw terminal_bell i pozwól tmux oznaczyć okno (następny krok).

  3. Skonfiguruj tmux pod agenta. Dodaj to do ~/.tmux.conf i przeładuj poleceniem tmux source-file ~/.tmux.conf:

    Okno terminala
    # ~/.tmux.conf — ustawienia, które mają znaczenie, gdy Claude Code działa w panelu
    set -g history-limit 50000 # długie sesje przewijają się daleko; zachowaj wyjście
    set -g mouse on # przewijanie i zaznaczanie wyjścia Claude'a myszą
    set -g monitor-bell on # dzwonek w dowolnym oknie oznacza je znakiem !
    set -g bell-action any # ...także w oknach, na które nie patrzysz
    set -g set-titles on # nazwa sesji Claude Code trafia do tytułu terminala
    set -g extended-keys on # przepuszcza Shift+Enter do Claude Code (tmux 3.2+)
    set -sg escape-time 10 # Esc (przerwanie, Esc Esc do cofnięcia) reaguje od razu

Daj Claude Code najszerszy panel, a po prawej umieść kontrole, które dowodzą jego pracy: testy w trybie watch, sprawdzanie typów w trybie watch i serwer deweloperski. Nie chodzi o to, żeby patrzeć, jak Claude pisze. Chodzi o to, żeby werdykt dla każdej edycji był na ekranie bez proszenia o niego.

+--------------------------------+-----------------------+
| | testy (tryb watch) |
| +-----------------------+
| claude -n cc-shop-api | tsc --watch |
| +-----------------------+
| | serwer dev |
+--------------------------------+-----------------------+

Poniższy skrypt buduje ten układ. Zapisuje identyfikator każdego panelu w chwili jego utworzenia, zamiast zgadywać numery, więc działa też wtedy, gdy ~/.tmux.conf ustawia pane-base-index 1. Drugie uruchomienie podłącza się do istniejącej sesji zamiast uruchamiać kolejną instancję Claude Code.

Podmień trzy polecenia send-keys na swój stos technologiczny: pytest-watch albo mix test --stale dla testów, mypy albo cargo check w pętli dla typów. Zostaw je w trybie watch. Panel, który pokazuje wynik tylko wtedy, gdy ktoś pamięta, żeby coś uruchomić, nie jest dowodem.

Między panelami przełączasz się prefiksem tmux i strzałką. Możesz też dodać do ~/.tmux.conf bind -n M-Left select-pane -L (i trzy pozostałe kierunki), żeby używać Alt+strzałki bez prefiksu.

Jak Claude czyta panele z testami i sprawdzaniem typów?

Dział zatytułowany „Jak Claude czyta panele z testami i sprawdzaniem typów?”

Claude Code nie widzi twojego ekranu, ale jego narzędzie Bash może uruchomić tmux capture-pane -p -t PANE_ID, które wypisuje zawartość panelu. Skrypt wyeksportował identyfikatory paneli, więc sesja od startu ma wszystko, czego potrzebuje. Wklej to jako pierwszą wiadomość w sesji.

Zezwól na tmux capture-pane raz (to polecenie tylko do odczytu), żeby nie zatwierdzać go co kilka tur: dodaj "Bash(tmux capture-pane:*)" do permissions.allow w .claude/settings.local.json albo przy pierwszej prośbie wybierz opcję „don’t ask again”. Tryb auto jest trybem startowym sesji interaktywnych od v2.1.283 na kanale wydań latest, z wyjątkiem uruchomień claude -p, sesji, w których plik ustawień ustawia disableAutoMode, oraz sesji na modelu nieobsługiwanym przez tryb auto — te startują w trybie Manual; szczegóły w trybach uprawnień na stronie o wierszu poleceń.

Skąd wiesz, że praca w terminalu jest poprawna, bez czytania każdej linii?

Dział zatytułowany „Skąd wiesz, że praca w terminalu jest poprawna, bez czytania każdej linii?”

Dzięki temu układowi weryfikacja to rzut oka, a nie lektura. Zanim przyjmiesz zadanie, sprawdź cztery rzeczy w tej kolejności:

  1. Oba panele kontrolne są zielone. Uruchomiły się ponownie po ostatniej edycji Claude’a, więc zielony panel jest aktualny. Jeśli panel wciąż pokazuje poprzedni przebieg, zapisz dowolny plik, żeby go wyzwolić.
  2. Blok dowodów zgadza się z panelami. Porównaj linie wklejone przez Claude’a z tym, co widzisz. Rozbieżność oznacza, że Claude podsumował przebieg, który nie jest najnowszy.
  3. Zakres jest taki, o jaki prosiłeś. git diff --stat wymienia każdy zmieniony plik. Zmiana w pliku blokady (package-lock.json), migracji albo konfiguracji CI, o którą nie prosiłeś, to fragment, który otwierasz i czytasz.
  4. Ryzykowne klasy zmian czyta człowiek. Uwierzytelnianie, płatności, zmiany schematu i migracje nadal czytasz linia po linii. Resztę oceniasz po dowodach; zobacz czytanie dowodów zamiast diffów.

Żeby punkt 1 był mechanizmem, a nie nawykiem, dodaj hook Stop, który nie pozwala Claude’owi zakończyć pracy, dopóki testy nie przechodzą. Skrypt i test z danymi testowymi są na stronie o hookach Claude Code. Akceptację nadal podpisujesz ty: panele i hook mówią, czy scalać, a diff mówi tylko, gdzie patrzeć.

Powiadomienia tylko wtedy, gdy Claude Code cię potrzebuje

Dział zatytułowany „Powiadomienia tylko wtedy, gdy Claude Code cię potrzebuje”

Większość przepisów na powiadomienia używa hooka Stop. Stop odpala się, gdy Claude kończy odpowiedź (zob. dokumentację hooków), czyli po każdej turze, także po jednozdaniowych odpowiedziach, które właśnie czytasz. Użyj zamiast tego hooka Notification i dopasuj typ powiadomienia. W 2.1.283 typy obejmują permission_prompt (Claude czeka na zgodę), idle_prompt (sesja czeka na twoje polecenie) oraz, dla agentów w tle w agent view, agent_needs_input i agent_completed.

  1. Zapisz skrypt powiadomień. Czyta JSON hooka ze stdin i działa na macOS (osascript) i Linuksie (notify-send):

    #!/usr/bin/env bash
    # ~/.claude/hooks/notify.sh — alert na pulpicie dla hooków Notification w Claude Code
    input=$(cat)
    msg=$(jq -r '.message // "Claude Code needs you"' <<<"$input")
    dir=$(jq -r '.cwd // ""' <<<"$input")
    title="Claude Code · ${dir##*/}"
    if command -v osascript >/dev/null; then
    osascript -e 'on run argv' -e 'display notification (item 2 of argv) with title (item 1 of argv)' -e 'end run' "$title" "$msg"
    elif command -v notify-send >/dev/null; then
    notify-send "$title" "$msg"
    fi
    exit 0

    Tekst trafia do AppleScriptu jako argv, a nie jest wklejany w łańcuch, więc wiadomość z cudzysłowem nie zepsuje polecenia.

  2. Nadaj mu prawo wykonania: chmod +x ~/.claude/hooks/notify.sh. Wymaga jq.

  3. Zarejestruj go w ustawieniach użytkownika, ~/.claude/settings.json, bo alerty to osobista preferencja, a nie reguła projektu:

    {
    "hooks": {
    "Notification": [
    {
    "matcher": "permission_prompt|idle_prompt|agent_needs_input",
    "hooks": [{ "type": "command", "command": "~/.claude/hooks/notify.sh" }]
    }
    ]
    }
    }
  4. Przetestuj go bez czekania na Claude’a: echo '{"message":"test","cwd":"/tmp/demo"}' | ~/.claude/hooks/notify.sh. Powiadomienie z tytułem „Claude Code · demo” dowodzi, że skrypt działa. Potem uruchom /hooks w sesji i sprawdź, czy Claude Code wczytał wpis.

Wbudowany kanał z kroków konfiguracji i ten hook działają niezależnie. Zostaw dzwonek terminala, żeby tmux oznaczał okno znakiem !, a hooka używaj do alertów, które mają cię dogonić w innej aplikacji.

Przy trzech sesjach w trzech panelach najdroższy błąd to wpisanie promptu w zły panel. Pasek stanu pod promptem usuwa zgadywanie. Uruchom /statusline i opisz, czego chcesz, albo napisz skrypt sam. Claude Code przekazuje dane sesji jako JSON na stdin; model.display_name i workspace.current_dir to dwa z jego pól.

#!/usr/bin/env bash
# ~/.claude/statusline.sh — model, katalog i gałąź pod promptem
input=$(cat)
model=$(jq -r '.model.display_name' <<<"$input")
dir=$(jq -r '.workspace.current_dir' <<<"$input")
branch=$(git -C "$dir" branch --show-current 2>/dev/null)
printf '%s · %s%s\n' "$model" "${dir##*/}" "${branch:+ · $branch}"

Zarejestruj go w ~/.claude/settings.json wpisem "statusLine": { "type": "command", "command": "~/.claude/statusline.sh" }. Przetestuj tak samo jak skrypt powiadomień:

Okno terminala
echo '{"model":{"display_name":"test"},"workspace":{"current_dir":"/tmp"}}' | ~/.claude/statusline.sh

Uruchom zadanie poboczne we własnym worktree i sesji tmux

Dział zatytułowany „Uruchom zadanie poboczne we własnym worktree i sesji tmux”

Gdy w trakcie sesji pojawia się drugie zadanie, nie otwieraj drugiego Claude Code w tym samym checkoucie: dwóch agentów edytujących jedno drzewo robocze nadpisuje sobie nawzajem zmiany. Uruchom je w izolacji:

Okno terminala
# Terminal: nowy git worktree i osobna sesja tmux jednym poleceniem
claude -w fix-flaky-discount -n fix-flaky-discount --tmux

-w (--worktree) tworzy dla sesji git worktree, -n (--name) nadaje sesji nazwę, po której znajdziesz ją później, a --tmux otwiera dla niej sesję tmux. W iTerm2 używa natywnych paneli, jeśli są dostępne; --tmux=classic wymusza zwykły tmux. Główny panel i jego narzędzie do uruchamiania testów dalej pracują na pierwotnym checkoucie.

Dowodem jest wynik z 20 przebiegów. Jeden zielony przebieg niestabilnego testu niczego nie dowodzi.

Żeby wrócić później do nazwanej sesji, claude -r fix-flaky-discount otwiera okno wznawiania przefiltrowane tym wyszukiwaniem, a claude -c kontynuuje najnowszą sesję w bieżącym katalogu. Gdy równolegle prowadzisz więcej niż dwa, trzy zadania poboczne, przestań zarządzać panelami ręcznie: agent view pokazuje sesje w tle i ich stan, a tmux dla floty agentów opisuje skryptowe rozdzielanie pracy.

Przekaż nieudane polecenie do Claude’a w trybie tylko do odczytu

Dział zatytułowany „Przekaż nieudane polecenie do Claude’a w trybie tylko do odczytu”

Niektóre pytania w ogóle nie potrzebują sesji: dlaczego build padł, co znaczy ten stack trace. Przekaż wyjście do claude -p z wyłączonymi wbudowanymi narzędziami i serwerami MCP, żeby uruchomienie mogło tylko przeczytać to, co przekazałeś potokiem, i odpowiedzieć.

Cztery decyzje w tej funkcji są celowe:

  • --tools "" wyłącza wszystkie wbudowane narzędzia, a --strict-mcp-config pomija serwery MCP, więc uruchomienie może przeczytać tylko to, co przekazałeś potokiem (sprawdzone na 2.1.283). Nie może edytować plików ani wykonać „najmniejszej poprawki”, którą proponuje. Poprawkę nakładasz ty, a polecenie kontrolne mówi, czy zadziałała.
  • return "$rc" zwraca kod wyjścia nieudanego polecenia, a nie Claude’a, więc why może stać w łańcuchu && bez ukrywania porażki.
  • tail -n 200 zachowuje koniec logu, gdzie zwykle jest błąd, i ogranicza koszt każdego wywołania.
  • Prompt prosi o polecenie kontrolne. Odpowiedź jest przydatna tylko wtedy, gdy mówi, jak ją sprawdzić.

Jeśli potok zasila skrypt i potrzebuje wyjścia JSON, kodów wyjścia oraz zawężonych uprawnień, użyj wzorców ze skryptowania Claude Code.

W tmux nie przychodzi żadne powiadomienie. Wbudowany kanał auto w 2.1.283 nie rozpoznaje tmux jako metody powiadomień. Ustaw kanał na terminal_bell w /config, sprawdź monitor-bell on w tmux i dodaj hook Notification dla alertów na pulpicie. Jeśli hook milczy, uruchom go ręcznie z testowym JSON-em z kroku 4 i przeczytaj błąd.

Alert przychodzi po każdej odpowiedzi. Skrypt jest podpięty pod Stop. Przenieś go do Notification z matcherem permission_prompt|idle_prompt.

Shift+Enter wysyła prompt zamiast dodać linię. W tmux klawisz dociera do Claude Code tylko przy extended-keys on i terminalu, który wysyła rozszerzone kody klawiszy. Awaryjnie wpisz \, a potem Enter, albo w Apple Terminal użyj Option+Enter po /terminal-setup.

Claude twierdzi, że testy przechodzą, a panel jest czerwony. Claude podsumował starszy przebieg albo uruchomił węższe polecenie niż twój proces obserwujący pliki. Odpowiedz wyjściem z panelu i przypomnij regułę dowodów z promptu powyżej. Jeśli zdarzy się to drugi raz, dodaj hook Stop ze strony o hookach, żeby kontrola przestała zależeć od promptu.

capture-pane zwraca pusty albo niewłaściwy panel. Identyfikatory paneli należą do sesji, która je wyeksportowała. Jeśli uruchomiłeś Claude Code ponownie poza skryptem, zmiennych już nie ma: uruchom tmux list-panes -F '#{pane_id} #{pane_current_command}' i podaj Claude’owi identyfikatory jeszcze raz.

Skrypt uruchamia drugą instancję Claude Code. Nazwa sesji pochodzi od nazwy katalogu, więc dwa klony o tej samej nazwie katalogu kolidują. Zmień nazwę jednego katalogu albo zmień name= w skrypcie tak, by zawierało katalog nadrzędny.

Wywołania przez potok robią się drogie. Każde claude -p to osobne zapytanie. Zostaw limit tail, nigdy nie wywołuj Claude’a z pętli watch dla każdej nieudanej linii i sprawdzaj wydatki przez /usage. Przy rozliczeniu przez API --max-budget-usd ogranicza koszt pojedynczego uruchomienia -p.

claude -p działa w repozytorium, któremu jeszcze nie zaufałeś. Tryb nieinteraktywny pomija okno zaufania do katalogu roboczego (według claude --help, 2.1.283). Hooki z ustawień projektu nadal się uruchamiają. Przekazuj dane do Claude Code tylko w repozytoriach, którym ufasz; uruchomienia z --tools "" --strict-mcp-config ograniczają szkody, ale nie zastępują tej zasady. --bare pomija też hooki, ale uwierzytelnia się wyłącznie przez ANTHROPIC_API_KEY albo apiKeyHelper, nigdy przez logowanie z subskrypcji.