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, @name: 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, komendą
npm install -g @anthropic-ai/claude-code, i od tej pory masz w systemie polecenie claude.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, nie modyfikuje niczego, dopóki wyraźnie o to nie poprosisz. 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ć.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ń.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ę /review: uruchamia recenzję Pull Requesta, samo pobierając jego zawartość, zamiast czekać, aż wkleisz ją do rozmowy.1/reviewJedna 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 /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: /review produkuje uwagi, a to Ty decydujesz potem, czy zatwierdzić zmiany, poprosić o poprawki, czy zamknąć Pull Requesta bez scalania. /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.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 zapis na dysku nie jest cichy: Claude Code prosi o potwierdzenie, zanim utworzy albo zmieni plik, i widzisz każdą zmianę, która przez to przechodzi. 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.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"
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"
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"
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. 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.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 Save the result to $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. 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 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 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.Słowo o dwóch 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. Niska, między 0.1 a 0.3, sprawia, że odpowiedzi są bardziej deterministyczne i powtarzalne, co pasuje do generowania kodu i do wszystkich zadań, w których chcesz za każdym razem tego samego wyniku. Wysoka, między 0.7 a 0.9, zostawia więcej miejsca na wariację, a więc na treści kreatywne: tekst, pomysły na nazwy, hasło reklamowe. To pojęcie jest jak najbardziej realne i spotkasz je od razu, gdy zaczniesz wołać API Claude z własnego programu. Natomiast - i tu czai się pułapka - narzędzie Claude Code w terminalu jej nie wystawia: nie istnieje ani flaga
--temperature, ani flaga --max-tokens. Nie znaczy to, że temperatura nie ma znaczenia, bo ma ogromne; znaczy tylko tyle, że zostaje dobrana za Ciebie, zależnie od zadania. Jeśli poradnik każe Ci wpisać claude --temperature 0.2, pochodzi z zupełnie innej epoki. Warto rozumieć samą zasadę, bo wróci do Ciebie przy każdym własnym skrypcie wołającym API: tam, gdzie wynik ma być powtarzalny, schodzisz z temperaturą nisko, a tam, gdzie chcesz świeżych pomysłów, podnosisz ją wysoko.Wybór modelu jest natomiast jak najbardziej w Twoich rękach i naprawdę zmienia postać rzeczy. Współistnieją trzy 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ą: to dobry wybór domyślny, a w szczególności do recenzji kodu. Opus to okręt flagowy, najmocniejszy w długim rozumowaniu, ten, który wyciągasz do skomplikowanego refactoringu albo trudnej migracji. Wybierzesz go 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: zostań domyślnie na Sonnecie i zmieniaj model tylko wtedy, gdy masz konkretny powód, bo przepuszczanie całej pracy przez Opusa 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 i opus zawsze dadzą Ci bieżący model z danej rodziny.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: '20'
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 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.Recenzja kodu -
claude -p "Review @plik" albo git diff | claude -p "...", a /review 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 - haiku, gdy ma być szybko, sonnet domyślnie, opus na wielkie budowyW 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, @name: 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.