Kurs vibe coding z AI · Moduł 15: Claude Code CLI
Praktyczne workflow z Claude Code
W tej lekcji8
Funkcja skończona, testy zielone, diff czysty - a Ty i tak siedzisz godzinę nad własnym kodem, zanim odważysz się otworzyć Pull Requesta. Potem piszesz dokumentację ręcznie. Potem testy. Potem opis commita. I właśnie w tym miejscu wiatr się zmienia: większość pracy programisty to nie pisanie nowego kodu, tylko czytanie, dokumentowanie, testowanie i przenoszenie kodu, który już istnieje. To obowiązki nocnej wachty - powtarzalne, niezbędne i idealne do zautomatyzowania. W tej lekcji przekazuję Ci siedem manewrów, których naprawdę używam na pokładzie, od najprostszego do najcięższego, a każdy z nich mieści się w jednej komendzie albo w krótkim skrypcie. Dwie uwagi, zanim odbijemy od brzegu. Po pierwsze, wszystkie polecenia poniżej działają z dzisiejszym Claude Code, a nie z tym z zakurzonych poradników sprzed dwóch lat. Po drugie, treść poleceń zostawiam w przykładach po angielsku, bo w takiej postaci spotkasz je w większości skryptów krążących po sieci - Claude rozumie polski dokładnie tak samo dobrze, więc pisz w tym języku, w którym jest Ci wygodniej. Wszystko, co zobaczysz poniżej, wpisujesz w terminalu, będąc w katalogu swojego projektu, bo właśnie z tego katalogu Claude Code czyta pliki. Samo narzędzie instalujesz raz (instalatorem natywnym albo przez npm, jak w poprzedniej lekcji) i od tej pory masz w systemie polecenie claude.
Manewr 1: recenzja kodu
Zacznijmy od najczęstszego obowiązku: oddania pliku do przeczytania. Dwa klocki, zanim cokolwiek wpiszesz. Pierwszy to flaga -p, od angielskiego print: uruchamia Claude Code, zadaje mu jedno pytanie, wypisuje odpowiedź w terminalu i oddaje Ci znak zachęty. Żadnej sesji, żadnej rozmowy - jedna komenda, jedna odpowiedź. Drugi klocek to znak @: wewnątrz treści polecenia zapis @katalog/plik.ts mówi Claude, żeby sam otworzył ten plik i sam go przeczytał. Nigdy nie wklejasz zawartości ręcznie, podajesz wyłącznie adres, jak punkt zaznaczony na mapie morskiej. I nic nie stoi na przeszkodzie, żeby wymienić kilka plików w jednym zdaniu.
1# Recenzja jednego pliku
2claude -p "Review @src/auth.ts for bugs and security issues"
3
4# Dwa pliki obok siebie
5claude -p "Compare @src/old-api.ts and @src/new-api.ts and suggest improvements"Co się właśnie stało: Claude otworzył wskazane pliki, przeczytał je w całości i wypisał analizę zwykłym tekstem w terminalu. Co się nie zmieniło - i to jest tu najważniejsze - Twoje pliki. Tryb -p czyta i odpowiada, ale domyślnie sam niczego nie zapisze: w tym trybie nikt nie zatwierdzi zmiany pliku, więc Claude Code odrzuca zapisy, dopóki nie pozwolisz na nie flagą - pokażę ją przy dokumentacji. Możesz więc puszczać te komendy na dowolnym repozytorium bez najmniejszego ryzyka, nawet w środku niezacommitowanej pracy. Zapamiętaj też, że wyjście jest zwykłym tekstem: da się je zapisać do pliku przekierowaniem > albo przekazać dalej, do kolejnej komendy. Jedna rada z mostka co do samego pytania: im węższe, tym lepsza odpowiedź. Prośba w stylu "sprawdź ten plik" da Ci ogólniki, a pytanie o konkretne błędy i o bezpieczeństwo, jak w przykładzie wyżej, daje listę, z którą naprawdę da się coś zrobić.
Potok: podaj Claude to, co widzi Git
Cały plik to zwykle za dużo. Przed commitem nie chcesz czytać całego auth.ts, tylko te dwanaście linii, których przed chwilą dotknąłeś. Git potrafi je już wyciągnąć, a terminal potrafi przelać informację z jednej komendy do drugiej: to potok, czyli pionowa kreska |. Bierze to, co komenda po lewej wypisuje, i wlewa prosto na wejście komendy po prawej. Claude Code przyjmuje taki strumień: wszystko, co przypłynie potokiem, dokleja się do treści Twojego polecenia. Z drugiej strony git diff pokazuje zmiany, których jeszcze nie zapisałeś w commicie. Razem dają najbardziej przydatną recenzję w całym dniu pracy.
1# Zmiany przed commitem
2git diff | claude -p "Review these changes before commit"
3
4# Ten sam diff, prostsze polecenie
5git diff | claude -p "Summarize these changes"Kolejność trzech elementów nie jest ozdobą: najpierw źródło, potem potok, na końcu Claude. Zapisany odwrotnie ciąg przestaje mieć sens, bo Claude nie miałby czego czytać w chwili startu. Zwróć uwagę na to, czego tu nie ma: żadnej flagi --diff, żadnej magicznej opcji po stronie Claude. Potok jest mechanizmem terminala, a nie funkcją Claude Code, i właśnie to czyni go tak mocnym: działa z każdą komendą, która potrafi wypisać tekst. Moja kapitańska rekomendacja: wszystko, co wychodzi z Gita, podawaj potokiem, a @ zostaw dla plików, które wskazujesz sam. Jedna pułapka, na którą wpada każdy: samo git diff pokazuje wyłącznie zmiany jeszcze nieprzygotowane do commita. Jeśli zdążyłeś już zrobić git add, diff zrobi się pusty i Claude dostanie polecenie bez żadnej treści. Wtedy sięgasz po git diff --staged, które pokazuje dokładnie to, co czeka w poczekalni.
Ten sam potok podłączysz do innych wyjść Gita i dopiero wtedy staje się on prawdziwym narzędziem wachtowym. git show HEAD pokazuje ostatni zapisany commit razem z opisem i zmianami - idealne do sekcji zwłok commita, który właśnie położył kompilację. git diff main...HEAD porównuje całą Twoją gałąź z main, czyli wszystko, co zaproponuje Twój Pull Request, a nie tylko ostatni krok. Trzy kropki mają znaczenie: każą Gitowi zacząć od momentu, w którym Twoja gałąź odbiła od main, żebyś nie utonął w commitach, które trafiły na main, gdy żeglowałeś gdzie indziej.
1# Analiza ostatniego commita
2git show HEAD | claude -p "Analyze this commit and find bugs"
3
4# Zakres Pull Requesta
5git diff main...HEAD | claude -p "Find potential bugs in this diff"W obu przypadkach budowa jest identyczna - źródło z Gita, potok, claude -p z pytaniem - i zmienia się wyłącznie źródło. To ten sam ruch zastosowany do innego zasięgu: raz jeden commit, raz cała gałąź. Nic nie ląduje na dysku, nic nie idzie na serwer, nic nie zostaje zacommitowane: dostajesz opinię, a nie akcję. A skoro wyjście dalej jest tekstem, możesz je zachować na później przekierowaniem, choćby > recenzja.md, i przeczytać spokojnie, gdy kompilacja się kręci. To mój poranny rytuał na projekcie, którego jeszcze nie znam: diff gałęzi, jedno pytanie, plik z notatkami. Gdy gałąź jest naprawdę gruba, zawęź kurs i dopisz na końcu ścieżkę, na przykład git diff main...HEAD -- src/api. Recenzja jednego obszaru naraz jest o wiele konkretniejsza niż jedna wielka opinia o wszystkim, co ruszyłeś przez ostatni tydzień.
Recenzja całego Pull Requesta
Diff daje Ci linie, ale Pull Request to również tytuł, opis, komentarze i historia. Żeby wziąć go w całości, trzeba przejść do sesji interaktywnej: wpisujesz samo claude, bez niczego więcej, i dostajesz rozmowę, która zostaje otwarta. W tej sesji polecenia zaczynające się od ukośnika nie są wiadomościami kierowanymi do Claude, tylko bezpośrednimi rozkazami dla samego narzędzia. To, które nas tutaj interesuje, nazywa się /code-review (krócej /review - to ten sam rozkaz). Bez argumentu recenzuje commity Twojej gałęzi i niezacommitowane zmiany, a z numerem Pull Requesta sam pobiera jego zawartość, zamiast czekać, aż wkleisz ją do rozmowy:
1/code-review 42Jedna linia, a mimo to używam jej najczęściej ze wszystkiego, zanim zatwierdzę pracę kogoś z załogi. Zapamiętaj dobrze tę różnicę, bo bardzo łatwo ją pomylić: claude -p wpisujesz w terminalu, a /code-review wpisujesz wewnątrz już otwartej sesji. To dwa różne światy i komenda sesyjna nigdy nie zadziała wprost w powłoce. Tu również nic nie zostaje zmienione: /code-review produkuje uwagi (chyba że dopiszesz --fix - wtedy od razu sam poprawia kod), a to Ty decydujesz potem, czy zatwierdzić zmiany, poprosić o poprawki, czy zamknąć Pull Requesta bez scalania. /code-review nie jest zresztą jedyną komendą sesyjną, którą spotkasz w tej lekcji - dalej pojawią się jeszcze /model, /clear i /compact. Wszystkie zaczynają się od ukośnika i wszystkie działają wyłącznie w otwartej sesji, więc jeśli kiedykolwiek zobaczysz w terminalu komunikat o braku takiego pliku albo takiego polecenia, znaczy to prawie zawsze, że wpisałeś komendę sesyjną poziom za nisko.
Manewr 2: dokumentacja
Nikt nie lubi pisać README i właśnie dlatego większość z nich kłamie po trzech miesiącach. Manewr drugi: pozwolić Claude przeczytać kod i napisać dokumentację na podstawie tego, co naprawdę istnieje. Tutaj jedna właściwość zmienia wszystko względem poprzednich przykładów. Claude Code potrafi nie tylko czytać Twoje pliki, ale też je zapisywać. Nie potrzebujesz więc ani specjalnej opcji wyjścia, ani przekierowania: wystarczy, że w zdaniu napiszesz, gdzie ma wylądować wynik. Zauważ przy okazji, że odpuściłem -p: bez tej flagi sesja zostaje otwarta i możesz od razu dorzucać poprawki na gorąco.
1# README na bazie kodu projektu
2claude "Read the code in src/ and write a professional README.md
3 with a project description, install steps and usage examples"
4
5# Dokumentacja API z jednego pliku
6claude "Generate API documentation in Markdown from @src/api.ts
7 and save it to docs/API.md"Różnica między tymi dwiema komendami jest pouczająca. Pierwsza nie wskazuje żadnego pliku: Claude sam przechodzi katalog src/, sam decyduje, które pliki się liczą, i wyciąga z nich opis. Druga celuje w @src/api.ts i narzuca miejsce zapisu. W obu wypadkach widzisz każdą zmianę w rozmowie: w trybie ręcznym (Manual) Claude Code pyta o zgodę, zanim utworzy albo zmieni plik, a w trybie auto, w którym nowe wersje zaczynają sesję w terminalu, pliki w katalogu projektu zapisuje bez pytania (klasyfikator ocenia tylko ryzykowniejsze akcje). Co się natomiast nie ruszyło: Twój kod źródłowy. Generowanie dokumentacji nie przepisuje dokumentowanych funkcji i dokładnie o to chodzi - mapa się aktualizuje, a brzeg zostaje tam, gdzie był. Przeczytaj jednak wynik, zanim go zacommitujesz. Dokumentacja napisana na podstawie kodu jest dokładna w tym, co kod robi, ale nie wie, czego celowo nie robi ani dlaczego zespół podjął kiedyś taką, a nie inną decyzję. To Ty dokładasz kontekst, którego w plikach po prostu nie ma.
Dopóki dokumentujesz jeden plik, wystarczy zwykła komenda. W dniu, w którym zechcesz odświeżyć całą dokumentację projektu przed wydaniem, nie będziesz wpisywał z pamięci trzech poleceń: zamkniesz je w skrypcie. Skrypt bash to zwykły plik tekstowy z komendami wykonywanymi od góry do dołu. Jego pierwsza linia, #!/bin/bash, mówi systemowi, jakiego interpretera użyć; linie zaczynające się od kratki są komentarzami, pomijanymi przy uruchomieniu; a echo wypisuje komunikat, żebyś wiedział, w którym miejscu jest w danej chwili statek. Nazwijmy nasz skrypt generate-docs.sh. Na Windowsie uruchamiaj takie skrypty w Git Bash albo w WSL, bo zwykły PowerShell nie zna składni basha.
1#!/bin/bash
2# generate-docs.sh
3
4echo "Start dokumentacji..."
5
6# Dokumentacja API
7claude -p "Read src/api/ and generate complete API documentation:
8 endpoints, request and response types, usage examples, error codes.
9 Save the result to docs/API.md" --permission-mode acceptEdits
10
11# Dokumentacja dla src/components
12claude -p "Read src/components/ and document every component:
13 purpose, props interface, code example.
14 Save the result to docs/COMPONENTS.md" --permission-mode acceptEdits
15
16# README projektu
17claude -p "Read the whole src/ folder and write README.md:
18 description, install steps, quick start, project structure.
19 Keep it readable for beginners" --permission-mode acceptEdits
20
21echo "Gotowe."Trzy polecenia, trzy pliki dokumentacji, jedno uruchomienie przez bash generate-docs.sh. Zwróć uwagę, że wróciła flaga -p: w skrypcie nie ma nikogo, kto odpowiedziałby na pytania, więc chcemy trybu nieinteraktywnego, który obsługuje prośbę i oddaje znak zachęty. Nowa jest flaga --permission-mode acceptEdits: w trybie -p nikt nie kliknie zgody na zapis, więc bez niej Claude domyślnie przeczytałby kod, ale żadnego pliku by nie utworzył. Tryb acceptEdits pozwala mu tworzyć i edytować pliki bez pytania, dlatego uruchamiaj taki skrypt tylko w repozytorium, w którym wszystkie zmiany masz już zacommitowane. Drugi sposób to poprosić o samą treść i przekierować ją do pliku: claude -p "..." > docs/API.md. Względem wersji ręcznej nie zmieniło się jedno: sposób formułowania samych poleceń. Skrypt to nie jest nowa składnia do nauczenia, tylko pamięć Twoich dobrych komend. A jeśli plik nie chce wystartować, prawie zawsze znaczy to, że nie jest wykonywalny, i chmod +x generate-docs.sh załatwia sprawę raz na zawsze.
Manewr 3: testy
Kod bez testów to statek bez grodzi wodoszczelnych: wszystko gra do pierwszego przecieku. Manewr trzeci: zlecić pisanie testów. Jest to najpopularniejszy uruchamiacz testów w świecie JavaScriptu. React Testing Library to biblioteka, która pozwala testować komponent React tak, jak robiłby to użytkownik, czyli szukając tekstu na ekranie zamiast grzebać we wnętrzu komponentu. W swoim poleceniu mów zawsze trzy rzeczy: który plik testować, co ma zostać pokryte - w szczególności przypadki brzegowe i obsługę błędów - oraz gdzie zapisać wynik.
1# Testy dla pliku z funkcjami pomocniczymi
2claude "Write Jest tests for @src/utils.ts, cover edge cases
3 and error handling, and save them to src/utils.test.ts"
4
5# Testy dla komponentu React
6claude "Write React Testing Library tests for @src/components/Button.tsx
7 and save them to src/components/Button.test.tsx"Dostajesz kompletny plik testów napisany w konwencji projektu: te same importy, te same nazwy bloków, ten sam styl. Jedno kapitańskie ostrzeżenie mimo wszystko. Wygenerowany test niczego nie dowodzi, dopóki go nie uruchomisz. Odpal go, sprawdź, że przechodzi, a potem celowo zepsuj testowaną funkcję i zobacz, czy test się wywali. Test, który świeci na zielono bez względu na wszystko, jest gorszy niż brak testu, bo daje pewność, nie dając żadnej gwarancji. Co się tutaj nie zmieniło: src/utils.ts pozostaje nietknięty, na świat przychodzi wyłącznie plik z testami. Cała ta próba to jedno polecenie w terminalu, na przykład npx jest src/utils.test.ts, i minuta Twojego czasu - a odróżnia testy, które chronią statek, od testów, które są tylko dekoracją na burcie.
Jeden plik naraz jest dobry na start; na projekcie, który jest w morzu od dwóch lat, potrzebujesz sieci dryfującej. Oto cztery narzędzia użyte w kolejnym skrypcie. find src -name "*.ts" przechodzi katalog i wyławia wszystkie pliki TypeScript, a ! -name "*.test.ts" odrzuca te, które już są testami. Pętla for ... do ... done powtarza to samo działanie dla każdego znalezionego pliku, wkładając go w każdym obrocie do zmiennej FILE. Wyrażenie ${FILE%.ts} obcina końcówkę nazwy, czyli przyrostek .ts, żebym mógł w to miejsce dokleić .test.ts. Wreszcie [ -f "$TEST_FILE" ] pyta, czy taki plik już istnieje, a continue przeskakuje do następnego obrotu, nie robiąc niczego.
1#!/bin/bash
2# generate-tests.sh
3
4# Wszystkie pliki TypeScript poza testami
5for FILE in $(find src -name "*.ts" ! -name "*.test.ts"); do
6
7 # Nazwa oczekiwanego pliku z testami
8 TEST_FILE="${FILE%.ts}.test.ts"
9
10 # Plik ma test - idziemy dalej
11 if [ -f "$TEST_FILE" ]; then
12 continue
13 fi
14
15 echo "Brak testu dla: $FILE"
16
17 claude -p "Write complete Jest tests for @$FILE.
18 Cover every exported function, edge cases and error handling.
19 Follow the Arrange-Act-Assert pattern.
20 Return only the test code, without Markdown fences." > "$TEST_FILE"
21donePrzebieg skryptu: dla każdego pliku z src/ wylicza nazwę odpowiadającego mu testu, sprawdza, czy taki plik istnieje, i woła Claude wyłącznie wtedy, gdy go nie ma. Odpowiedź Claude trafia do pliku przekierowaniem > "$TEST_FILE", bo w trybie -p Claude domyślnie sam pliku nie zapisze. Drugi szczegół wart zapamiętania to @$FILE wsunięte w treść polecenia: terminal podmienia zmienną na prawdziwą ścieżkę, zanim Claude w ogóle zobaczy zdanie, dzięki czemu odwołanie @ wskazuje właściwy plik w każdym obrocie pętli. Co się nie zmienia: testy, które napisałeś ręcznie. Skrypt je wykrywa i mija bokiem, więc możesz go uruchamiać do woli, nie kasując swojej pracy - cecha bezcenna, gdy skrypt rozmawia ze sztuczną inteligencją.
Manewr 4: migracje i refactoring
Manewr czwarty, ten, który oszczędza całe tygodnie: migracja. Przełożenie pliku JavaScript na TypeScript, unowocześnienie starego komponentu React, wymiana porzuconej biblioteki - to przemiany mechaniczne, ale nieskończenie długie, dokładnie ten rodzaj pracy, przy którym ludzka uwaga wysiada na dziesiątym pliku. Przepis ma dwa składniki: plik wskazany przez @ oraz polecenie, które mówi, co ma się zmienić, a przede wszystkim co ma zostać takie samo. Ta druga część jest ważniejsza, bo bez niej konwersja bardzo szybko upraszcza po drodze jakieś zachowanie.
1# JavaScript na TypeScript
2claude "Convert @src/legacy.js to TypeScript: add types and interfaces,
3 keep the behaviour exactly the same"
4
5# Stary komponent na nowoczesny React
6claude "Refactor @src/old-component.jsx into a modern React function
7 component with hooks"Dla pojedynczego pliku ta komenda w zupełności wystarcza i wynik widzisz od razu. Przy migracji, która dotyka trzydziestu plików, zmień taktykę i poproś najpierw o plan. Claude Code ma tryb planowania: analizuje teren, proponuje kolejność działań i czeka na Twoje przyzwolenie, zanim cokolwiek zmieni - poznasz go dokładnie w następnym ćwiczeniu. Moja kapitańska rekomendacja: powyżej trzech plików zawsze przechodź przez plan. Przeczytanie dziesięciu linii strategii kosztuje minutę, a przeczytanie trzydziestu przepisanych naraz plików kosztuje Cię cały wieczór.
Jest jeszcze jeden ruch, który warto wykonać zaraz po migracji, i łączy on manewr czwarty z pierwszym. Skoro Claude właśnie przepisał pliki, wszystkie te zmiany leżą teraz w Twoim katalogu jako niezacommitowany diff. Podaj więc ten diff z powrotem potokiem: git diff | claude -p "Review these changes before commit" i poproś wprost o wskazanie miejsc, w których zachowanie mogło się po drodze zmienić. Czytanie własnej migracji świeżym okiem jest trudne, bo pamiętasz, jak miało być, a nie widzisz, jak jest. Recenzja z zewnątrz nie ma tego obciążenia i wyłapuje właśnie to, co Ty przeoczysz - zgubioną obsługę błędu albo domyślną wartość, która cicho zniknęła podczas konwersji.
Manewr 5: Claude wewnątrz Twoich skryptów
Manewr piąty, mój ulubiony: opisy commitów. Znasz efekt pośpiesznego wieczoru - fix, fix2, final-fix, final-fix2. Skoro claude -p zwraca czysty tekst, ten tekst można złapać do zmiennej i wykorzystać w dalszej części skryptu. Cztery elementy basha do poznania, zanim przeczytasz kolejny blok. Konstrukcja $(komenda) wykonuje komendę i podstawia w to miejsce jej wyjście, dzięki czemu wynik ląduje w zmiennej. git diff --cached pokazuje wyłącznie to, co dodałeś do poczekalni, czyli do staging area, poleceniem git add. Test [ -z "$DIFF" ] pyta, czy zmienna jest pusta, a exit 1 przerywa skrypt z kodem błędu. Wreszcie read -p zadaje pytanie i chowa odpowiedź w zmiennej REPLY, którą porównujemy potem przez [[ $REPLY =~ ^[Yy]$ ]], czyli: czy odpowiedź zaczyna się od y albo od Y.
1#!/bin/bash
2# smart-commit.sh
3
4# To, co czeka w staging area
5DIFF=$(git diff --cached)
6
7if [ -z "$DIFF" ]; then
8 echo "Pusty staging. Najpierw: git add <pliki>"
9 exit 1
10fi
11
12# Diff idzie w potok, tekst wraca
13MESSAGE=$(echo "$DIFF" | claude -p "Write a commit message in
14 Conventional Commits format (type: description).
15 Return ONLY the message, nothing else.")
16
17echo "Propozycja dla tego commita:"
18echo "$MESSAGE"
19echo
20
21read -p "Commit z tym opisem? (y/n) " -n 1 -r
22echo
23
24if [[ $REPLY =~ ^[Yy]$ ]]; then
25 git commit -m "$MESSAGE"
26 echo "Zrobione."
27else
28 echo "Anulowane."
29fiPrześledź ten wątek, czyta się jak manewr w czterech taktach. Diff ze staging area wchodzi do zmiennej DIFF; jeśli jest ona pusta, skrypt zatrzymuje się porządnie, z przydatnym komunikatem, zamiast wołać Claude bez powodu; w przeciwnym razie diff przepływa potokiem do claude -p, a odpowiedź zostaje złapana w MESSAGE; na koniec skrypt pokazuje Ci propozycję, czeka na zgodę i commituje wyłącznie wtedy, gdy odpowiesz y. Co się nie zmieniło i nigdy zmienić nie powinno: nic nie zostaje zacommitowane za Twoimi plecami. Ludzkie potwierdzenie zostaje w środku łańcucha i radzę Ci trzymać tę zasadę we wszystkich swoich skryptach - automat proponuje, marynarz decyduje.
Temperatura, wysiłek i model: co ustawiasz, a czego nie
Słowo o ustawieniach, o których na pewno słyszałeś, bo mnóstwo starych poradników opowiada o nich bzdury. Temperatura to parametr próbkowania modeli językowych: niższa daje odpowiedzi bardziej powtarzalne, wyższa bardziej różnorodne. W Claude Code jej nie ustawisz - nie istnieje ani flaga --temperature, ani flaga --max-tokens - a najnowsze modele Claude nie przyjmują jej nawet przez API (akceptują tylko domyślną wartość 1.0). Jeśli poradnik każe Ci wpisać claude --temperature 0.2, pochodzi z zupełnie innej epoki. Prawdziwym pokrętłem obok modelu jest poziom wysiłku (effort): decyduje, jak długo model myśli nad każdym krokiem. Ustawisz go flagą --effort przy starcie albo komendą /effort w sesji, z wartościami low, medium, high, xhigh i max. Niski wysiłek jest szybszy i tańszy przy prostych zadaniach, wysoki daje głębsze rozumowanie przy trudnych:
1# Proste pytanie: niski wysiłek
2claude --effort low -p "Explain what git rebase does"
3
4# Trudny problem: wysoki wysiłek
5claude --effort high "Find the cause of the memory leak in @src/server.ts"Wybór modelu też leży w Twoich rękach i naprawdę zmienia postać rzeczy. Na pokładzie są cztery rodziny, od najlżejszej do najpotężniejszej. Haiku to szalupa: najszybszy i najtańszy, skrojony pod krótkie pytania, takie jak rozszyfrowanie komunikatu o błędzie albo wyjaśnienie jednej komendy. Sonnet to okręt liniowy, równowaga między prędkością a głębią, dobry do codziennej pracy i do recenzji kodu. Opus to okręt flagowy, mocny w długim rozumowaniu i domyślny model na większości planów. Fable to galeon na najdłuższe wyprawy: najmocniejszy, ale wolniejszy i droższy, do wielogodzinnych migracji i przebudów całego projektu. Wybierzesz model flagą --model w linii poleceń albo komendą /model wewnątrz otwartej sesji.
1# Szybkie pytanie: Haiku
2claude --model haiku -p "What does this TypeScript error mean?"
3
4# Recenzja kodu: Sonnet
5git diff | claude --model sonnet -p "Review these changes"
6
7# Trudny refactoring: Opus
8claude --model opus "Refactor @src/legacy-cart.js and modernise it"Prosty odruch, żeby się w tym połapać: im więcej rozumowania wymaga zadanie, tym wyżej wchodzisz; im jest ono krótsze i bardziej powtarzalne, tym niżej schodzisz. Moja rekomendacja: do prostych i powtarzalnych zadań przełączaj się na Sonneta albo Haiku, a po Opusa i Fable sięgaj wtedy, gdy zadanie naprawdę wymaga rozumowania, bo przepuszczanie całej pracy przez największy model kosztuje więcej i trwa dłużej, nie dając nic przy prostych pytaniach. Na koniec uważaj na zamrożone identyfikatory modeli, które ciągną się w starych skryptach, w rodzaju claude-3-sonnet-20240229: takie wersje się starzeją i w końcu znikają, podczas gdy krótkie nazwy haiku, sonnet, opus i fable zawsze dadzą Ci bieżący model z danej rodziny.
Manewr 6: automatyczna recenzja w CI/CD
Manewr szósty: powierzyć pierwsze czytanie maszynie, żeby ludzka załoga otwierała Pull Requesta dopiero wtedy, gdy oczywistości zostały już zgłoszone. GitHub Actions to system automatyzacji GitHuba: wrzucasz plik YAML do katalogu .github/workflows/, a GitHub wykonuje jego zawartość przy każdym zdarzeniu, które zadeklarujesz. Linia on: pull_request znaczy więc: przy każdym otwartym albo zaktualizowanym Pull Requeście. Job to ciąg kroków wykonywanych na świeżej maszynie, a każdy krok robi jedną rzecz: albo używa gotowej akcji przez uses, albo uruchamia komendy przez run. Klucza API nigdy nie wpisuje się do pliku: śpi on w sekretach repozytorium i zostaje wstrzyknięty dopiero w potrzebnym momencie przez env. Ostatni składnik, ten naprawdę ważny dla automatyzacji: flaga --output-format json każe Claude Code odpowiedzieć w ustrukturyzowanym formacie, nadającym się do przetworzenia przez program, zamiast tekstem przeznaczonym dla ludzkiego czytelnika.
1# .github/workflows/claude-review.yml
2name: Claude Code Review
3
4on:
5 pull_request:
6 branches: [ main ]
7
8jobs:
9 review:
10 runs-on: ubuntu-latest
11 permissions:
12 contents: read
13 pull-requests: write
14 steps:
15 - uses: actions/checkout@v4
16 with:
17 fetch-depth: 0
18
19 - name: Setup Node.js
20 uses: actions/setup-node@v4
21 with:
22 node-version: '22'
23
24 - name: Install Claude Code
25 run: npm install -g @anthropic-ai/claude-code
26
27 - name: Review changed files
28 env:
29 ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
30 run: |
31 git diff origin/main...HEAD | \
32 claude -p "Review these changes for bugs and security. Be brief." \
33 --output-format json > review.json
34
35 - name: Post review as a PR comment
36 uses: actions/github-script@v7
37 with:
38 script: |
39 const fs = require('fs');
40 const data = JSON.parse(fs.readFileSync('review.json', 'utf8'));
41 github.rest.issues.createComment({
42 issue_number: context.issue.number,
43 owner: context.repo.owner,
44 repo: context.repo.repo,
45 body: data.result
46 });Przeczytaj kolejność kroków jeszcze raz, bo opowiada historię, w której żaden rozdział nie może zmienić miejsca: pobieramy kod, instalujemy Claude Code, recenzujemy zmienione pliki i dopiero na końcu publikujemy wynik jako komentarz do Pull Requesta. Nie recenzuje się kodu, którego się nie pobrało, i nie komentuje się recenzji, która jeszcze nie istnieje. Dwa szczegóły warte uwagi. Linia fetch-depth: 0 żąda pełnej historii repozytorium, bez niej porównanie z main nie miałoby czego chwycić. A review.json to nie tekst dla Ciebie: to ustrukturyzowany plik, który następny krok otwiera, żeby wyciągnąć z niego pole result i dopiero je opublikować. Co się nie zmieniło: robot komentuje, niczego nie scala i nikogo nie blokuje.
Dwie sprawy do ustawienia, zanim to popłynie na produkcję. Klucz API musisz najpierw dodać w ustawieniach repozytorium, w sekcji sekretów, dokładnie pod tą nazwą, której używasz w env - inaczej krok wystartuje z pustą zmienną i skończy się błędem uwierzytelnienia. I trzymaj polecenie krótkie, tak jak w przykładzie, z wyraźnym "Be brief": ten workflow uruchomi się przy każdej aktualizacji każdego Pull Requesta, więc rozwlekła recenzja zamieni się w ścianę tekstu, której załoga przestanie czytać już w drugim tygodniu.
Manewr 7: sesja w duecie
Manewr siódmy i ostatni, najtrudniejszy do pokazania na piśmie, bo jest zwyczajnie rozmową. Uruchom claude bez żadnego polecenia: otwierasz sesję interaktywną, a Claude pamięta wszystko, co sobie w niej powiedzieliście. Opisujesz zamiar, on pisze prosto do plików; prosisz o ulepszenie, poprawia to, co przed chwilą napisał; prosisz o testy, tworzy plik z testami. Rytm jest taki jak w programowaniu w parze: małe kroki, sprawdzenie po każdym z nich i nigdy dziesięć próśb naraz. W kolejnym bloku linie zaczynające się od strzałki to jest to, co wpisujesz Ty, a te w nawiasach kwadratowych to, co Claude robi w odpowiedzi.
1# Start sesji interaktywnej
2claude
3
4# A dalej, w sesji:
5# > I am building a login system. Start with the login function
6# > in @src/auth/login.ts
7# > [Claude writes the code straight into the file]
8# > Now add password hashing
9# > [Claude updates the same file]
10# > Add rate limiting to block brute force attempts
11# > [Claude adds the protection]
12# > Write tests for all of this
13# > [Claude creates the test file]Cztery prośby, cztery zmiany i ani razu nie otworzyłeś edytora sam. Co nie zmienia się między wiadomościami, to kontekst: Claude pamięta plik logowania, sposób, w jaki go napisał, i decyzje podjęte wcześniej, dzięki czemu nie musisz tłumaczyć wszystkiego od nowa w każdej turze. Ta wygoda ma jednak drugą stronę. Po długiej sesji kontekst zapełnia się starociami, które nie mają już nic wspólnego z bieżącym zadaniem, a rozmowa traci precyzję. Dwie komendy stawiają ją z powrotem do pionu: /clear zaczyna od czystej karty, idealne, gdy zmieniasz temat całkowicie, a /compact zachowuje streszczenie rozmowy i prowadzi dalej na tej podstawie, czego chcesz wtedy, gdy zadanie trwa, ale historia zrobiła się długa. Wybór między nimi sprowadza się do jednego pytania: czy to, co powiedzieliście sobie do tej pory, przyda się jeszcze w następnym kroku. Jeśli tak, wybierasz /compact; jeśli zaczynasz zupełnie nowy temat, /clear zdejmie Ci z pokładu cały zbędny balast.
Podsumowanie
Recenzja kodu - claude -p "Review @plik" albo git diff | claude -p "...", a /code-review <numer PR> dla całego Pull Requesta
Dokumentacja - poproś Claude, żeby przeczytał kod i sam zapisał plik
Testy - claude "Write Jest tests for @plik and save them to ..."
Migracje - plik wskazany przez @, a tryb planowania, gdy budowa rośnie
Skrypty - claude -p w trybie nieinteraktywnym, potok | na wejściu, zmienna na wyjściu
CI/CD - claude -p --output-format json w GitHub Actions
Duet - sesja interaktywna, /clear i /compact do pilnowania kontekstu
Modele i wysiłek - haiku, gdy ma być szybko, sonnet na co dzień, opus i fable na wielkie budowy; --effort reguluje, jak długo model myśli
W następnym ćwiczeniu bierzemy kurs na tryb planowania i subagentów, a przekonasz się, że na razie opłynęliśmy dopiero brzeg. Do zobaczenia na pokładzie!
Zapamiętaj przede wszystkim to: Claude Code nie zastępuje marynarza przy sterze, tylko trzyma liny, gdy Ty pilnujesz kursu - a załoga, która automatyzuje obowiązki wachty, wchodzi do portu zawsze przed innymi.
Kod do tej lekcji: code-review.sh
1#!/bin/bash
2# Recenzja kodu z Claude Code
3# Użycie: ./code-review.sh
4
5echo "Recenzja zmian ze staging area..."
6
7# Pobierz zmiany ze staging area i przekaż je do Claude przez pipe.
8# Tryb -p (--print) wypisuje odpowiedź i kończy działanie.
9git diff --cached | claude -p "Zrecenzuj te zmiany pod kątem:
10 - błędów logicznych
11 - luk bezpieczeństwa
12 - problemów z wydajnością
13 - naruszeń dobrych praktyk
14
15 Bądź zwięzły. Raportuj tylko realne problemy."
16
17echo ""
18echo "Recenzja zakończona. Popraw błędy przed commitem."
19
20# Możesz też wskazać konkretny plik przez @ zamiast pipe:
21# claude -p "Zrecenzuj @src/auth.ts pod kątem bezpieczeństwa"
22
23# Albo zrecenzować w sesji Pull Requesta o numerze 42
24# (samo /code-review sprawdzi zmiany na gałęzi):
25# /code-review 42Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Który model Claude do jakiego zadania?
2. Którą komendą w sesji zrecenzujesz Pull Requesta?
To 2 z 5 pytań do tej lekcji. Pozostałe rozwiążesz w grze.
Zadania praktyczne w grze
- Układanie w poziomie
Ułóż polecenie, które przekazuje diff Git do Claude w celu podsumowania:
- Edytor kodu
Napisz w commands.sh skrypt generate-docs.sh, który przez claude -p tworzy trzy pliki: docs/API.md, docs/COMPONENTS.md i README.md. Odpowiedź każdego wywołania zapisz do pliku przekierowaniem >.
- Układanie w poziomie
Ułóż polecenie recenzujące całą gałąź względem main przez pipe:
- Układanie w pionie
Uporządkuj kroki workflow GitHub Actions z recenzją kodu przez Claude:
- Edytor kodu
Napisz w commands.sh skrypt generate-tests.sh: znajdź pliki .ts w src (find), pomiń te, które mają już plik .test.ts ([ -f ... ]), a dla pozostałych wywołaj claude -p z prośbą o testy Jest.
- Układanie w pionie
Uporządkuj kroki działania skryptu smart-commit.sh generującego wiadomość commita:
- Układanie w poziomie
Ułóż polecenie przekazujące konkretny commit (HEAD) do analizy przez Claude:
- Układanie w pionie
Uporządkuj typowy przebieg sesji pair programming z Claude: