Przejdź do głównej zawartości

Programowanie we Flutterze z Claude Code, Codeksem lub Cursorem daje weryfikowalny kod, gdy agent startuje z trzech przypiętych faktów: wersji pakietów (Riverpod 3 z generowaniem kodu, go_router, Dio, freezed), reguł architektury i jednej komendy sprawdzającej. Plugin zespołu Fluttera i serwer MCP Darta weryfikują wtedy każdą zmianę analizą, generowaniem kodu i testami.

Ta strona jest dla programistów i tech leadów, którzy wydają aplikację we Flutterze z pomocą agenta. Prosisz o provider i dostajesz StateNotifierProvider, który Riverpod 3 przeniósł do importu legacy.dart. Prosisz o interceptor Dio z ponawianiem, a jeden niedziałający ekran wysyła teraz dziesiątki żądań, bo Riverpod 3 sam ponawia providery, które zwróciły błąd. Żadnego z tych błędów nie zauważysz, przeglądając diff pobieżnie.

  • Plugin agenta od zespołu Fluttera (skille plus serwer MCP Darta), zainstalowany w każdym narzędziu
  • Blok AGENTS.md, który przypina stos i komendę sprawdzającą, więc każda sesja je dziedziczy
  • Prompty do skopiowania: provider Riverpod z generowaniem kodu, przekierowanie autoryzacji w go_router bez pętli, serwis Dio z typowanymi błędami i testy widgetów
  • Mechaniczne kontrole do każdego przepisu (strażniki rg, build_runner --only-check, testy tabelaryczne), które zastępują czytanie wygenerowanego kodu
  • Mapę awarii: dryf build_runner, podwójne ponawianie, minimalna wersja SDK dla go_router, błędy Gradle i CocoaPods oraz niestabilne testy golden

Dane treningowe agenta obejmują kilka głównych wersji każdego pakietu z tabeli, a każda z nich zmieniła API, którego agent chętnie używa. Podaj wersje w prompcie i w AGENTS.md. Tabela pokazuje, co serwował pub.dev 2026-09-26.

PakietWersjaNa czym agent się myli
flutter_riverpod3.4.3 (wymaga Darta ^3.12)StateNotifierProvider, StateProvider i ChangeNotifierProvider są w package:flutter_riverpod/legacy.dart. Providery z błędem są ponawiane automatycznie.
riverpod_annotation / riverpod_generator4.0.7 / 4.0.9Główna wersja generatora (4) różni się od wersji runtime’u (3). Trzymaj adnotacje i generator na tej samej głównej wersji. Providery przyjmują zwykły Ref; generowane podklasy w stylu UserProfileRef zniknęły.
riverpod_lint3.1.9 (wymaga Darta 3.13)Oparty na analysis_server_plugin, nie na custom_lint. Konfiguruj go według jego README, nie według przepisu z custom_lint ze starszego artykułu.
go_router18.0.118.0.0 wymaga Fluttera 3.44 / Darta 3.12. Na starszym Flutterze przypnij ^17.5.0. Od 15.0.0 adresy URL rozróżniają wielkość liter.
dio5.11.1Stabilne API 5.x: InterceptorsWrapper, DioException.
freezed4.0.2 (wymaga Darta 3.13)4.0.0 nie akceptuje już final w parametrach konstruktora. Klasy muszą być sealed albo abstract (od 3.0).
build_runner2.16.1Domyślnie poprawia nieaktualne wygenerowane pliki. --delete-conflicting-outputs to usunięta flaga, ignorowana z ostrzeżeniem. --only-check przerywa build, gdy pliki na dysku różnią się od tego, co zapisałby generator.

Niech agent dodaje pakiety przez flutter pub add <pakiet>, które dobiera wersję zgodną z twoim SDK, zamiast wpisywać numery wersji do pubspec.yaml.

Zainstaluj plugin agenta od zespołu Fluttera i serwer MCP Darta

Dział zatytułowany „Zainstaluj plugin agenta od zespołu Fluttera i serwer MCP Darta”

Zespół Fluttera publikuje flutter/agent-plugins, repozytorium przemianowane z flutter/skills. Jego plugin dart-flutter (1.0.6 na 2026-09-26) zawiera 25 skilli, 10 dla Fluttera i 15 dla Darta, na przykład flutter-add-widget-test, flutter-fix-layout-issues i dart-resolve-package-conflicts. Rejestruje też serwer MCP Darta (dart mcp-server, dostarczany z Dart SDK). Zespół Darta publikuje swoje skille także w dart-lang/skills.

Okno terminala
# Marketplace and plugin are both named dart-flutter
claude plugin marketplace add flutter/agent-plugins
claude plugin install dart-flutter@dart-flutter

Aby dodać tylko serwer MCP, uruchom claude mcp add dart -- dart mcp-server. Otwórz /mcp w sesji, aby sprawdzić, czy serwer się połączył.

To serwer MCP zmienia pętlę pracy. Bez niego agent pisze widget i liczy na szczęście. Z nim może wywołać analyze_files, odczytać get_runtime_errors z działającej aplikacji, uruchomić hot_reload i przejść drzewo widgetów przez widget_inspector (nazwy narzędzi z README dart-lang/ai, odczytane 2026-09-26). Serwer wymaga Darta 3.9 lub nowszego. Do działającej aplikacji dociera przez Dart Tooling Daemon, który flutter run uruchamia w trybie debug i profile.

Porównanie skilli i serwerów MCP znajdziesz w artykułach jak instalować skille i nimi zarządzać oraz oficjalne skille dostawców.

Prompt przypina stos na jedną sesję. Plik z instrukcjami projektu przypina go dla każdej sesji. Codex czyta AGENTS.md, a Claude Code czyta go, gdy repozytorium nie ma CLAUDE.md (od v2.1.277, oba kanały wydań, stan na 2026-10-12). Jeśli masz CLAUDE.md, wstaw tam ten sam blok. W Cursorze umieść ten sam blok w regule projektu (Cursor Rules). Skopiuj go i dostosuj wersje.

## Flutter stack (do not substitute)
- Flutter 3.47+, Dart 3.13+. Add packages with `flutter pub add`, never by typing versions.
- State: Riverpod 3 with code generation (`@riverpod`, `part '*.g.dart';`).
Never import `package:flutter_riverpod/legacy.dart`. No StateNotifier, no get_it.
- Navigation: go_router 18 with one `GoRouter` provided through Riverpod.
- Networking: Dio behind `ApiService`. Map every `DioException` to the sealed `ApiFailure`.
- Models: freezed 4 (`sealed` or `abstract` classes). No hand-written fromJson.
- Layout: lib/features/<feature>/{data,domain,presentation}. domain/ imports no Flutter and no Dio.
## Check command (run before you say a task is done)
dart run build_runner build && dart format --output=none --set-exit-if-changed . \
&& flutter analyze && flutter test

Ostatnia linia to umowa. Agent, który zgłasza „gotowe” bez zielonej komendy sprawdzającej, nie skończył, i możesz go z tego rozliczyć bez otwierania choćby jednego pliku.

Uruchom prompt w narzędziu, którego używasz. W Claude Code podaj go jako pierwszy argument (claude "…"). W Codeksie tak samo (codex "…"); sesja pyta o zgodę przed komendami, które jej wymagają. W Cursorze wklej go do czatu agenta. Każde narzędzie stosuje blok tylko z pliku, który czyta. Gdy zmieniasz stos, zaktualizuj każdą kopię bloku w tym samym commicie.

Zaletą @riverpod jest to, że ładowanie, cache i parametry stają się deklaratywne. Ryzykiem jest to, że agent domiesza klasy providerów w starym stylu ze swoich danych treningowych.

Sprawdź wynik mechanicznie zamiast go czytać:

Okno terminala
# Must print nothing: legacy providers or pre-3.0 generated refs
rg -n "flutter_riverpod/legacy.dart|StateNotifier|ProviderRef\b|FutureProviderRef" lib
# Generated files must match what the generator writes
dart run build_runner build --only-check

Linia z --only-check ma znaczenie tylko wtedy, gdy commitujesz pliki .g.dart i .freezed.dart. Jeśli je commitujesz, wyłapuje agenta, który ręcznie zmienił wygenerowany plik albo zapomniał ponownie uruchomić generator.

Zbuduj przekierowanie autoryzacji w go_router, które nie może się zapętlić

Dział zatytułowany „Zbuduj przekierowanie autoryzacji w go_router, które nie może się zapętlić”

Klasyczny błąd w go_router to nieskończone przekierowanie: strażnik odsyła niezalogowanych do /login, ale zapomina przepuścić samo /login. Naprawa to jedna klauzula, i to ją agent pomija najczęściej. Nie polegaj na tym, że wypatrzysz ją w kodzie. Zrób z przekierowania czystą funkcję i ją przetestuj.

Test tabelaryczny jest kryterium akceptacji. Jeśli obejmuje każdą parę statusu i trasy i przechodzi, przekierowanie nie może się zapętlić, niezależnie od tego, jak wygląda implementacja. Wiersz z /LOGIN jest ważny, bo od wersji 15.0.0 adresy w go_router rozróżniają wielkość liter.

Zbuduj serwis API na Dio z typowanymi błędami i jedną warstwą ponawiania

Dział zatytułowany „Zbuduj serwis API na Dio z typowanymi błędami i jedną warstwą ponawiania”

Podstawowa ścieżka serwisu Dio jest prosta. O gotowości produkcyjnej decydują trzy rzeczy: odświeżenie tokenu po 401 z ponowieniem żądania, typowany błąd i miejsce, w którym zachodzi ponawianie.

Riverpod 3 domyślnie ponawia provider, który zwrócił błąd. W riverpod 3.4.3 ProviderContainer.defaultRetry pozwala na maksymalnie 10 ponowień, od 200 ms z podwajaniem do limitu 6,4 s, dla każdego błędu, który nie jest Error ani ProviderException. ApiFailure nie jest żadnym z nich. Dodaj interceptor Dio, który ponawia trzy razy, a jeden niedziałający ekran może wysłać dziesiątki żądań. Wybierz jedną warstwę do ponawiania.

Trzy testy dowodzą zachowania, które ma znaczenie. Dołóż do nich jeden mechaniczny strażnik: rg -n "rethrow|throw e\b" lib/core/network nie powinno nic wypisać, gdy każdy DioException jest już zmapowany. Kontrakt API po stronie serwera opisują wzorce tworzenia API.

Pilnuj warstw czystej architektury kontrolą, nie lekturą

Dział zatytułowany „Pilnuj warstw czystej architektury kontrolą, nie lekturą”

W większej aplikacji proś o konkretną funkcję, nie o „ustawienie czystej architektury”. Liczy się jedno ograniczenie: domain nie importuje ani Fluttera, ani Dio. Przeciekający package:flutter/material.dart w przypadku użycia oznacza, że warstwy są tylko dekoracją, a grep znajdzie go szybciej niż recenzent.

Dodaj regułę warstw do CI, aby przetrwała kolejne sto edycji agenta. Krok przechodzi tylko wtedy, gdy rg nic nie znajdzie (kod wyjścia 1); trafienie (kod 0) albo błąd rg, na przykład brak katalogu (kod 2), go przerywa, a forma || rc=$? działa także w powłoce bash -e, której używają runnery CI:

Okno terminala
rc=0
rg -n 'package:(flutter|dio)/' lib/features --glob '**/domain/**' || rc=$?
test "$rc" -eq 1

Weryfikuj każdą zmianę we Flutterze bez czytania każdej linii

Dział zatytułowany „Weryfikuj każdą zmianę we Flutterze bez czytania każdej linii”

Komenda sprawdzająca z AGENTS.md to pętla wewnętrzna. Pull request potrzebuje bramki, która uruchamia te same kontrole oraz te zbyt wolne na każdą edycję. Kolejność poniżej zaczyna od najtańszych, więc błąd kosztuje jak najmniej czasu CI.

  1. Wygenerowany kod jest aktualny. dart run build_runner build --only-check (jeśli commitujesz wygenerowane pliki), w przeciwnym razie dart run build_runner build.
  2. Formatowanie i analiza statyczna. dart format --output=none --set-exit-if-changed . oraz flutter analyze. Traktuj uwagi riverpod_lint jak błędy.
  3. Kontrole strażnicze. Strażniki rg dla importów Riverpod legacy i importów w warstwie domain z poprzednich sekcji.
  4. Testy jednostkowe i widgetów. flutter test, łącznie z tabelą przekierowań i testami Dio.
  5. Testy golden na jednym systemie. Testy golden uruchamiasz przez flutter test na linuksowym obrazie CI i porównujesz z zacommitowanymi obrazami. Generuj je ponownie przez flutter test --update-goldens tylko na tym obrazie, w osobnym commicie.
  6. Testy integracyjne na urządzeniu. flutter test integration_test na emulatorze dla przepływów, które dotykają pluginów, takich jak logowanie i płatność. Farmy urządzeń i triage niestabilnych testów opisuje strona wzorce testowania aplikacji mobilnych.

Kto zatwierdza: recenzent pull requesta sprawdza, że bramka jest zielona, a testy odpowiadają kryteriom akceptacji z zadania, takim jak tabela przekierowań i trzy przypadki Dio. Ludzka lektura trafia do tych testów i do warstwy domain, nie do wygenerowanego kodu ani do szablonowych widgetów. Sam proces opisuje artykuł code review PR-a agenta bez czytania każdej linii.

Jeśli agent ma sam napisać zadanie CI, najpierw podłącz serwer MCP GitHuba, aby czytał twoje prawdziwe workflowy i nazwy sekretów, zamiast je wymyślać. Konfigurację dla każdego narzędzia opisuje przewodnik po serwerze MCP GitHuba, a strukturę zadania wzorce potoków CI/CD. Przy awariach na produkcji serwer MCP do obserwowalności, na przykład serwer Sentry, pozwala agentowi odczytać prawdziwy stack trace dla wydania, zanim zaproponuje poprawkę.

  • Dryf build_runner. Objawy: provider, który „nie istnieje”, nieaktualny .g.dart albo błąd typu w wygenerowanym kodzie. Wyjście: uruchom dart run build_runner clean, a potem dart run build_runner build. Flaga --delete-conflicting-outputs w build_runner 2.16.1 nic już nie robi, więc agent, który ciągle ją dodaje, nie znalazł przyczyny. Wklej agentowi pierwszy błąd i zapytaj, która z trzech przyczyn zachodzi: brak dyrektywy part, mieszanie składni legacy z codegenem, czy riverpod_annotation i riverpod_generator w różnych głównych wersjach.
  • Wraca Riverpod legacy. Objaw: strażnik rg znajduje legacy.dart albo StateNotifier. Wyjście: odrzuć zmianę i wklej do promptu jeden z istniejących providerów jako wzorzec stylu. Dopisz regułę do AGENTS.md, jeśli jej brakuje.
  • Niedziałający ekran zalewa API żądaniami. Objaw: logi pokazują ten sam GET wiele razy przy jednym otwarciu ekranu. Przyczyna: automatyczne ponawianie Riverpoda nałożone na interceptor Dio. Wyjście: przekaż do ProviderScope funkcję retry, która zwraca null dla ApiFailure, jak w prompcie o Dio.
  • Testy oczekują surowego błędu. Objaw: test, który oczekuje ApiFailure z ref.read lub ref.watch, przestaje przechodzić po aktualizacji do Riverpoda 3. Przyczyna: Riverpod 3 opakowuje ponownie rzucony błąd providera w ProviderException. Wyjście: sprawdzaj stan AsyncValue providera albo rozpakuj wyjątek i powiedz agentowi, której konwencji używa twój zestaw testów.
  • freezed 4 rozwiązuje się jako 3.2.x. Objaw: flutter pub add freezed wybiera freezed 3.2.5 i riverpod_lint 3.1.8, a kod agenta pisany pod freezed 4 się nie buduje. Przyczyna: freezed od 4.0.0 i riverpod_lint 3.1.9 wymagają Darta 3.13, który jest dostarczany z Flutterem 3.47. Wyjście: zaktualizuj Fluttera do 3.47+ w osobnej zmianie albo, na Darcie 3.12, wpisz w AGENTS.md „freezed 3”, aby agent celował w wersję, którą faktycznie dostaje.
  • go_router 18 się nie rozwiązuje. Objaw: flutter pub get pada na ograniczeniu SDK. Przyczyna: 18.0.0 wymaga Fluttera 3.44 i Darta 3.12. Wyjście: przypnij go_router: ^17.5.0 do czasu aktualizacji Fluttera. Nie pozwól agentowi aktualizować Flutter SDK przy okazji zadania funkcjonalnego.
  • Błędy Gradle i CocoaPods. Awarie Androida po podbiciu zależności to zwykle niezgodność wersji Android Gradle Plugin, Gradle lub Kotlina. Awarie iOS to zwykle pod, który wymaga pod repo update albo wyższego deployment target. Wyjście: wklej pełny log builda, poproś agenta o przypięcie konkretnych wersji pluginów i zabroń mu zmieniać wersję Flutter SDK, aby naprawić poda.
  • Goldeny przechodzą lokalnie i padają w CI. Przyczyna: macOS i Linux renderują fonty inaczej. Wyjście: generuj goldeny tylko na obrazie CI i ładuj dołączony font w flutter_test_config.dart.
  • Agent nie widzi działającej aplikacji. Objaw: narzędzia MCP Darta, takie jak get_runtime_errors, nic nie zwracają. Przyczyna: aplikacja działa w trybie release albo z --no-dds, więc żaden Dart Tooling Daemon nie jest zarejestrowany. Wyjście: uruchom flutter run w trybie debug i poproś agenta, aby połączył się z nią przez narzędzie dtd.

Czy ten artykuł Ci pomógł?

Jedno kliknięcie, bez logowania.

wcale bardzo