Przejdź do głównej zawartości

Duże bazy kodu i monorepo w Claude Code: zakres, plan, weryfikacja

Claude Code radzi sobie w dużej bazie kodu lub monorepo, gdy każda sesja widzi tylko fragment, którego dotyczy zadanie. Ten fragment wyznaczają katalog startowy, pliki CLAUDE.md per katalog, claudeMdExcludes, reguły Read w deny, wtyczka code intelligence i rzadkie (sparse) worktree. Zmiany między pakietami są bezpieczne, gdy powstają w jednej zaplanowanej sesji i przechodzą bramki na każdym dotkniętym pakiecie.

Ta strona jest dla programistów pracujących w repozytorium zbyt dużym, by ogarnąć je w głowie, oraz dla tech leadów odpowiedzialnych za wspólną konfigurację Claude Code. Sytuacja: prosisz Claude o zmianę przepływu uwierzytelniania w monorepo z 40 pakietami, a on edytuje przestarzały pakiet legacy-auth zamiast aktywnego. Dwa tygodnie później sesja kolegi wczytuje CLAUDE.md zespołu frontendowego i stosuje reguły Reacta do serwisu w Go. Żaden z tych błędów nie wynika z modelu. Oba wynikają ze złego zakresu.

Wszystko poniżej sprawdziliśmy 2026-09-26 na Claude Code v2.1.283 (kanał latest) i w przewodniku producenta po dużych bazach kodu.

  • Regułę, skąd uruchamiać claude, żeby wczytały się właściwe pliki CLAUDE.md i ustawienia.
  • Commitowany plik ustawień, który trzyma poza kontekstem instrukcje innych zespołów, artefakty builda i kod vendorowany.
  • Prompty do pełnej inwentaryzacji wywołań, planu zmiany między pakietami i wykonania z bramkami.
  • Konfigurację worktree, dzięki której równoległe sesje nie nadpisują sobie nawzajem pracy.
  • Skrypt weryfikacyjny, który dowodzi zakresu, kompletności i działania na każdym dotkniętym pakiecie, więc nikt nie musi czytać każdej linii.
  • Sposoby wyjścia z awarii, które pojawiają się dopiero w dużej skali.

Katalog, z którego uruchamiasz claude, decyduje o tym, co Claude może edytować bez pytania, które pliki CLAUDE.md wczytują się na starcie i który .claude/settings.json obowiązuje. Ustawienia projektu nie dziedziczą się z katalogów nadrzędnych tak jak pliki CLAUDE.md.

Start zDostęp do plikówCLAUDE.md wczytane na starcieKiedy
Katalog główny repozytoriumWszystkie plikiTylko główny; plik podkatalogu wczytuje się, gdy Claude czyta plik w tym podkataloguZadanie obejmuje kilka pakietów lub podsystemów
Pakiet lub podsystemTo poddrzewo, dopóki nie przyznasz więcejPlik tego katalogu i wszystkich katalogów nadrzędnychPraca dotyczy jednego pakietu

Domyślnie startuj z pakietu. Z katalogu głównego startuj tylko wtedy, gdy zmiana naprawdę przekracza granice pakietów, i wtedy najpierw ją zaplanuj (zobacz planowanie zmiany między pakietami).

Żeby sprawdzić, co się wczytało, uruchom w sesji /context i przejrzyj listę Memory files. Jeśli widać tam plik z pakietu innego zespołu, następna sekcja go usunie.

Każde z poniższych ustawień działa niezależnie, więc wdróż te, których potrzebuje twoje repozytorium. Tech lead commituje części wspólne, a każdy programista trzyma własne wykluczenia w .claude/settings.local.json.

  1. Podziel CLAUDE.md według katalogów. W pliku głównym zostaw tylko reguły obowiązujące wszędzie (format commitów, gdzie leży kod generowany, jak uruchamiać skrypty pakietów). Konwencje stosu danego pakietu umieść w jego własnym CLAUDE.md, utrzymywanym przez właścicieli pakietu. Pełną kolejność wczytywania, importy i .claude/rules/ z globami paths: opisuje strona o systemie pamięci Claude Code.

    packages/api/CLAUDE.md
    Copy `.env.example` to `.env` before running tests; they fail without it.
    Write queries with the Knex query builder. No raw SQL in route handlers.
    Never edit a merged migration. Add a new one.
    Gate: `pnpm --filter api run typecheck && pnpm --filter api test`.
  2. Wyklucz instrukcje dla kodu, którego nie dotykasz. Gdy startujesz z katalogu głównego, CLAUDE.md pakietu wczytuje się, gdy tylko Claude przeczyta w nim jakiś plik. claudeMdExcludes pomija pliki według globów dopasowywanych do ścieżek bezwzględnych, więc wzorce względne zaczynaj od **/. Osobiste wykluczenia trzymaj w .claude/settings.local.json, a jeśli tworzysz ten plik ręcznie, dopisz go do .gitignore. Plików CLAUDE.md z polityki zarządzanej (managed policy) nie da się wykluczyć.

    {
    "claudeMdExcludes": ["**/packages/legacy-*/**", "**/packages/web/CLAUDE.md"]
    }
  3. Zablokuj odczyt kodu generowanego i vendorowanego. Wyszukiwanie treści już respektuje .gitignore, więc node_modules/ i dist/ nie trafiają do wyników. Na commitowany kod generowany albo vendorowane SDK dodaj reguły Read w deny. Wzorzec zakończony /**/* blokuje pliki, ale nadal pozwala Claude wylistować katalog. Reguły deny obejmują narzędzia plikowe Claude i rozpoznawane przez Claude Code polecenia Bash (cat, grep, find ze ścieżką w argumencie). Rekurencyjny grep -r po katalogu nadrzędnym nadal zwraca trafienia z zablokowanych plików, a podprocesy, które same otwierają pliki, nie są objęte blokadą.

    {
    "permissions": {
    "deny": [
    "Read(./**/generated/**/*)",
    "Read(./**/*.generated.*)",
    "Read(./**/vendor/**/*)",
    "Read(./packages/legacy-auth/**/*)"
    ]
    }
    }

    Wzorce względne są liczone od katalogu, z którego uruchamiasz claude, więc ostatnia reguła chroni sesje startowane z katalogu głównego repozytorium. Jeśli startujesz sesje z pakietu, zapisuj reguły dla całego repozytorium jako ścieżki absolutne z //, na przykład Read(//abs/path/to/repo/packages/legacy-auth/**/*).

  4. Zastąp skanowanie plików serwerem języka. Wtyczka code intelligence pozwala Claude przechodzić do definicji i znajdować referencje zamiast czytać pliki w poszukiwaniu symbolu, a po edycji zgłasza błędy typów. Najpierw zainstaluj binarkę serwera języka, potem wtyczkę w sesji. Dla TypeScriptu:

    Okno terminala
    # terminal
    npm install -g typescript-language-server typescript
    /plugin install typescript-lsp@claude-plugins-official

    Oficjalny marketplace zawiera też pyright-lsp, gopls-lsp, rust-analyzer-lsp, jdtls-lsp i wtyczki dla innych języków (lista w anthropics/claude-plugins-official z 2026-09-26). Żeby włączyć wtyczkę całemu zespołowi, dodaj ją do enabledPlugins w commitowanym .claude/settings.json. Jeśli twoja organizacja ma już wyszukiwarkę kodu lub indeks RAG nad repozytorium, udostępnij go jako serwer MCP, żeby Claude odpytywał indeks zamiast czytać pliki; zobacz serwery MCP do analizy kodu.

  5. Przyznawaj dostęp do sąsiednich pakietów jawnie. Sesja uruchomiona w packages/api/ nie może edytować packages/shared/, dopóki na to nie pozwolisz. Zacommituj pakiety, których potrzebuje każdy programista API, albo jednorazowo przekaż --add-dir przy starcie (lub wpisz /add-dir w sesji):

    {
    "permissions": { "additionalDirectories": ["../shared"] }
    }
    Okno terminala
    # terminal, z katalogu packages/api
    CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 claude --add-dir ../shared

    Katalog dodany przez additionalDirectories nigdy nie wczytuje swojego CLAUDE.md, reguł ani skilli. Katalog dodany przez --add-dir wczytuje skille, a CLAUDE.md i reguły tylko przy ustawionej tej zmiennej środowiskowej.

Procedury specyficzne dla pakietu, zbyt długie na CLAUDE.md (na przykład jak pisać testy API), należą do skilla w packages/api/.claude/skills/. Skille wczytują się tylko wtedy, gdy Claude uzna je za istotne, więc narzędzia API nic nie kosztują podczas pracy nad frontendem.

Przeszukaj duży obszar bez zapychania głównego kontekstu

Dział zatytułowany „Przeszukaj duży obszar bez zapychania głównego kontekstu”

Zanim zmienisz coś, co przekracza granice pakietów, zrób inwentaryzację. Uruchom wyszukiwanie w subagencie, żeby setki odczytów plików nie trafiły do głównej rozmowy, i nazwij pośrednie mechanizmy, których używa twój kod. Wyszukiwanie tekstowe znajduje importy, ale nie handlery rejestrowane kluczem tekstowym czy przez wstrzykiwanie zależności.

Uruchom polecenie rg, które dostaniesz, i porównaj liczbę trafień z tabelą. Rozbieżność oznacza niepełną inwentaryzację: poproś Claude o wyjaśnienie każdego brakującego trafienia, zanim zaczniesz planować. Pełną mapę nieznanego repozytorium opisuje strona o poznawaniu nieznanej bazy kodu z Claude Code.

Wprowadź zmianę między pakietami w jednej zaplanowanej sesji

Dział zatytułowany „Wprowadź zmianę między pakietami w jednej zaplanowanej sesji”

Zmiana wspólnego typu i wszystkich miejsc jego użycia powinna odbyć się w jednej sesji, żeby każda edycja wynikała z tych samych decyzji. Najpierw ją zaplanuj: w trybie planowania Claude zapisuje plan do pliku, a Claude Code wstrzykuje ten plan ponownie po każdej kompakcji. Długa sesja zachowuje więc plan nawet wtedy, gdy starsza historia rozmowy zostaje streszczona.

Czytaj plan, nie kod. Sprawdź kolejność edycji, niepokryte testami miejsca wywołań i punkt „pliki spoza listy”. Przed akceptacją dopisz testy dla niepokrytych miejsc albo zaakceptuj tę lukę na piśmie.

Jeśli zmiana dzieli się na niezależne jednostki, z których każdą da się zmergować osobno (na przykład ta sama migracja w 30 pakietach), przekaż ją do /batch; zobacz operacje wsadowe na setkach plików.

Dwie sesje w tym samym checkoucie dzielą jedno drzewo robocze, więc druga może nadpisać pracę pierwszej. Daj każdej równoległej sesji osobne git worktree:

Okno terminala
# terminal, jedno na zadanie
cd packages/api && claude --worktree api-rate-limit
cd packages/web && claude --worktree web-settings-page

W dużym repozytorium pełne worktree powstaje wolno i zajmuje dużo miejsca. Zacommituj worktree.sparsePaths, żeby każde worktree pobierało tylko wymienione katalogi i pliki z katalogu głównego, oraz symlinkDirectories, żeby node_modules było linkowane, a nie kopiowane. Ścieżki są względne wobec katalogu głównego repozytorium. Dodaj .claude, żeby główne ustawienia i reguły istniały w worktree. Umieść sparsePaths i symlinkDirectories w .claude/settings.json katalogu, z którego startujesz (tu packages/api/) — są czytane przed utworzeniem worktree.

{
"worktree": {
"sparsePaths": [".claude", "packages/api", "packages/shared"],
"symlinkDirectories": ["node_modules"]
}
}

Dwie zasady utrzymują równoległą pracę w stanie nadającym się do merge’a. Po pierwsze: jeden właściciel na plik. Jeśli dwa zadania muszą zmienić packages/shared, wykonaj je po kolei, a nie obok siebie. Po drugie: w worktree sesja czyta .claude/settings.json z katalogu głównego worktree, a nie z pakietu, więc trzymaj kopię reguł Read z deny w ustawieniach katalogu głównego repozytorium. Nadzór nad wieloma sesjami naraz opisuje strona o uruchamianiu wielu agentów równolegle z worktree.

Jak zweryfikować zmianę w dużej bazie kodu bez czytania każdego diffa?

Dział zatytułowany „Jak zweryfikować zmianę w dużej bazie kodu bez czytania każdego diffa?”

Udowodnij mechanicznie trzy rzeczy, a ludzką uwagę poświęć tylko planowi i plikom wskazanym przez te sprawdzenia.

PytanieSprawdzenieZaliczone, gdy
Czy zmiana nie wyszła poza zakres?git diff --name-only porównane z listą plików z planuKażdy zmieniony plik jest w planie albo ma podany powód
Czy jest kompletna?Liczba trafień rg dla starego wzorcaLiczba wynosi 0
Czy każdy konsument nadal działa?Typecheck i testy na zmienionych pakietach i pakietach od nich zależnychZielono na wszystkich, nie tylko na edytowanym pakiecie
#!/usr/bin/env bash
# verify-change.sh: uruchom z katalogu głównego repozytorium po zakończeniu sesji
set -euo pipefail
base=origin/main
echo "== Files changed (compare with the plan)"
git diff --name-only "$base"...HEAD
echo "== Positional authenticate( calls left (must be 0)"
# rg kończy się kodem 1, gdy nic nie znajdzie (to przypadek poprawny), więc || true chroni przed przerwaniem przez set -e i pipefail
count=$( { rg -nP 'authenticate\((?!\s*\{)' packages/ --type ts --glob '!packages/legacy-auth/**' || true; } | wc -l)
echo "$count"
test "$count" -eq 0
echo "== Typecheck and test every changed package and its dependents"
pnpm --filter "...[$base]" run typecheck
pnpm --filter "...[$base]" test

Dopasuj wzorzec do stylu wywołań w swoim kodzie: wyklucz plik z definicją UserService (na przykład --glob '!packages/shared/src/user-service.ts') i niezwiązane API o nazwie authenticate(. Rozstrzyga lista referencji z serwera języka.

Filtr ...[origin/main] wybiera pakiety zmienione od origin/main oraz wszystkie pakiety od nich zależne, bo to tam psuje się zmiana sygnatury. Nx (nx affected -t typecheck test) i Turborepo (turbo run typecheck test --filter=...[origin/main]) działają według tej samej idei. Uruchamiaj ten sam skrypt w CI, żeby bramka nie zależała od czyjejś pamięci.

Potem uruchom /code-review na gałęzi jako drugie przejście nastawione na poprawność i przepuść pull request przez CODEOWNERS, żeby właściciel każdego dotkniętego pakietu zatwierdził swoją część. Właściciel przegląda plan i wynik bramek dla swojego pakietu, a nie każdą linię. Stronę review i CI opisuje automatyzacja code review w Claude Code.

Co psuje się w dużej bazie kodu i jak z tego wyjść?

Dział zatytułowany „Co psuje się w dużej bazie kodu i jak z tego wyjść?”

Przestarzały pakiet z tymi samymi nazwami co aktywny (legacy-auth obok auth) wygrywa w wyszukiwaniu. Wyjście: cofnij edycje przez /rewind, dodaj ścieżkę przestarzałego pakietu do reguł Read w deny i do claudeMdExcludes, a potem uruchom sesję od nowa z katalogu aktywnego pakietu. Dopisz do głównego CLAUDE.md jedną linię wskazującą aktywny pakiet.

Wyszukiwanie tekstowe znajduje importy, a nie trasy rejestrowane napisem czy serwisy rozwiązywane przez kontener. Zmiana się kompiluje, a pada w czasie działania. Wyjście: nazwij w prompcie każdy mechanizm pośredni, sprawdź wynik przez rg, korzystaj z referencji serwera języka tam, gdzie go masz, i dopisz test dla każdego miejsca wywołania oznaczonego w planie jako niepokryte.

Kontekst zapełnia się w połowie zmiany między pakietami

Dział zatytułowany „Kontekst zapełnia się w połowie zmiany między pakietami”

Claude zaczyna powtarzać pracę albo zapomina wcześniejszą decyzję. Wyjście: uruchom /compact ze wskazaniem, co zachować, na przykład /compact keep the plan, the caller table and the list of packages already done. Plik planu zostaje wstrzyknięty ponownie po kompakcji. Jeśli jakość nadal jest słaba, użyj /clear i zacznij nową sesję, która czyta plan i kontynuuje od pierwszego nieukończonego pakietu.

Po dodaniu ../shared Claude zignorował jego CLAUDE.md. Katalogi dodane przez --add-dir wczytują CLAUDE.md tylko przy ustawionym CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1, a additionalDirectories nie wczytuje go nigdy. Wyjście: uruchom sesję ponownie z tą zmienną albo, dla tego zadania, startuj z katalogu głównego.

Sesja w worktree czyta główny .claude/settings.json, więc reguły zacommitowane tylko w packages/api/.claude/settings.json tam nie obowiązują. Wyjście: skopiuj reguły deny do głównego pliku ustawień.

Długa sesja uruchomiona z katalogu głównego może zgromadzić setki skilli ze wszystkich katalogów, których dotknie. Przy tak dużej liczbie część skilli traci opisy w całości, więc Claude nie ma już słów kluczowych, po których wybiera właściwy. Wyjście: startuj z pakietu, pisz krótkie opisy zaczynające się od słów, które pojawiają się w prośbach („writing or modifying tests in packages/api/”), a skille wspólne przenieś do wtyczki.

CLAUDE.md nadal opisuje uwierzytelnianie sesyjne po przejściu na JWT. Wyjście: przeglądaj zmiany w CLAUDE.md w pull requestach jak kod, uruchamiaj powyższy prompt uzgadniający po dużych refaktoryzacjach i przeczytaj instrukcje ponownie po dużym wydaniu modelu, bo obejścia dla starszego modelu stają się zbędnym narzutem.

Jak z dużymi repozytoriami radzą sobie Codex i Cursor

Dział zatytułowany „Jak z dużymi repozytoriami radzą sobie Codex i Cursor”

Zasady zawężania są te same we wszystkich narzędziach, ale konfiguracja już nie: Codex czyta pliki AGENTS.md, a Cursor używa własnych reguł. Strategię wspólną dla wszystkich narzędzi opisują strony o strategiach dla baz kodu z milionami linii i pracy z monorepo z asystentami AI. Wersję tej strony dla Cursora znajdziesz w strategiach dla dużych baz kodu w Cursorze.