mcpField
B
building-flutter-apps

building-flutter-apps

github.com/sgaabdu4Development25176 installsUpdated 3d ago
Repository

About building-flutter-apps

A skill that guides coding agents through Flutter and Dart development with project-specific rules and a trigger map for selecting the relevant references. It emphasizes generated Riverpod providers, architecture, testing, accessibility, and pre-flight checks.

Key features

  1. 01Scenario-based reference selection
  2. 02Flutter and Riverpod coding rules
  3. 03Architecture and state-management guidance
  4. 04Testing, accessibility, and localization rules
  5. 05Pre-flight checks after file changes

Use cases

  1. 01Starting or modifying a Flutter app
  2. 02Implementing Riverpod state and async mutations
  3. 03Reviewing UI, accessibility, or navigation changes

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/sgaabdu4/building-flutter-apps --skill building-flutter-apps

After installing, type/building-flutter-appsin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

agents/
openai.yaml
assets/
defender-installer-scan.ps1
inno-bundle-pubspec.yaml
inno-uninstall-settlement-sentinel.ps1
windows-installer-workflow.yml
references/
analysis_options.yaml
analysis-options.md
architecture.md
atomic-design.md
build-reproducibility.md
common-patterns.md
core-stack.md
dart-decimate.md
dart-mcp-e2e-testing.md
dart-patterns-records.md
deep-linking.md
error-reporting.md
flutter-optimizations.md
freezed-sealed.md
hive-persistence.md
references/atomic-design/
accessibility.md
references/common-patterns/
debounce-gate-batch.md
delta-sync.md
lists-forms-workflows.md
modals-navigation.md
navigation-flow.md
routing-app-shell.md
references/extensions/
collections-helpers.md
context-ui.md
primitive-formatting.md

Details

From the project README

Read first

  • This skill overrides generic Flutter/Dart advice; Critical Rules override examples, public docs, and older project code.
  • Each ref's Read first section is canonical.
  • After each .dart/pubspec.yaml/build.yaml/analysis_options.yaml write batch, run Pre-Flight; its cited rule/reference owns the applicable check.

Progressive Disclosure Gate

Before code, read only the narrowest matching Trigger Map row(s); scenario/subsystem rows own incidental stack/file words. Read a parent ref such as common-patterns.md only when no scenario row fits; never bulk-read references/. Cite exact refs in Pre-Flight.

Critical Rules

IDRuleDetail refs
R1Flutter/Riverpod package = first wire flutter_skill_lints + riverpod_lint, then run package-root dart analyze + its project-owned Dart Decimate check; pure-Dart CLI = native Dart analysis profile with neither plugin.analysis-options.md, dart-decimate.md, setup.md
R2Every provider uses @riverpod / @Riverpod codegen; no manual provider classes or legacy provider families.riverpod-codegen.md
R3Guard async gaps with ref.mounted / context.mounted; finally uses if (ref.mounted) { ... }.async-mutations.md
R4Widgets are public classes; no _buildXxx(), widget top-level helpers, or private widget classes except State.atomic-design.md, performance.md
R5Nullability is semantic; no empty/null/bool sentinel fallbacks, value!, nullable collections, or raw required domain strings.value-objects.md, freezed-sealed.md; Lints: domain_raw_required_string
R6All user-facing strings, tooltips, semantics, and visible accessibility copy use AppLocalizations.localization.md, accessibility.md
R7Immutable state/entities use sealed Freezed, one declaration per file, native switch, and VO map/when disabled.freezed-sealed.md, value-objects.md
R8presentation/widgets/ renders immutable inputs + emits typed callbacks; screens/routes/notifiers own navigation, workflow, domain state, and infrastructure.presentation-widgets.md
R9Duplicate behavior in 2+ classes becomes a small stateless *Mixin with an on clause.mixins.md
R10Storage SDK calls live in local datasources behind repositories; production Hive imports use hive_ce_flutter.hive-persistence.md, architecture.md
R11Primitive/context/collection operations live in core/extensions/; domain never imports those extensions.context-ui.md, primitive-formatting.md, collections-helpers.md
R12Domain primitives with meaning become validated Freezed Value Objects; Hive models keep primitives and mappers bridge.value-objects.md, hive-persistence.md; Lints: domain_unit_primitive
R13Typed GoRouter routes are navigation SSOT; redirects are pure resolver logic with nullable by-id fallback UI.deep-linking.md, routing-app-shell.md
R14Dialogs/sheets render immutable snapshots, pop results, and leave mutations/teardown to notifiers.modals-navigation.md, state-management-lifecycle.md
R15Debounce, gate, and batch high-frequency UI, sync, persistence, remote-function, reset, and lookup boundaries.debounce-gate-batch.md
R16App shell stays declarative; bootstrap listeners live in a sibling root ConsumerWidget.routing-app-shell.md
R17Keep control flow flat after exits; remove unnecessary else after return / throw / break / continue.Lint: avoid_unnecessary_else_after_control_flow
R18Use onReorderItem post-removal indexes directly; never add legacy onReorder adapter math.Lint: use_on_reorder_item_index_semantics
R19Android exact alarms use flutter_local_notifications permission APIs, not manual settings intents.Lint: use_local_notifications_exact_alarm_permission_api
R20Resolve nullable platform-specific plugin implementations before calling platform members.Lint: resolve_platform_specific_implementation_before_use
R21Widget previews are preview-only with deterministic fakes; no real HTTP/Firebase/Hive/native plugins.widget-previews.md
R22Runtime E2E proves behavior with stable selectors, failure-sensitive scenarios/logs, subject-matched evidence, source-of-truth verification, cleanup, and multi-actor proof when needed.dart-mcp-e2e-testing.md
R23Accessibility is UI correctness: localized tooltips/semantic labels, 48x48 targets, contrast, text scale, Text.rich.accessibility.md, flutter-optimizations.md
R24If remote error reporting is accepted or already present, use one app-owned Crash boundary and one reporting owner per operation; otherwise add no provider/facade. Scrub sensitive data + reconcile ambiguous remote outcomes before telemetry.error-reporting.md, networking.md
R25Windows installer delivery = one semantic engine + typed app config/capabilities + minimal-step exact-SHA diagnostic → one publisher; keep cheap guards before one build, isolate synthetic preservation proof, and activate only verified immutable bytes.windows-installer-pipeline.md, workflow scaffold, inno_bundle pubspec scaffold, Inno settlement sentinel, Defender scanner
R26Pause-sensitive Riverpod state starts only after its durable owner/listener exists; projections watch base state directly; switching auth/form modes clears transient errors.notifier-structure.md, state-management-lifecycle.md, testing.md
R27Native/custom links use one URI contract across producer, platform registration, Flutter delivery, and typed router; prove cold/warm + signed-state delivery on the target device.deep-linking.md, dart-mcp-e2e-testing.md

Trigger Map

TouchingRead
New app/project scaffolding with incidental stack/package mentions, main.dart, ProviderScope, MaterialApp.router, app startup shellsetup.md + architecture.md + routing-app-shell.md
Notifier/AsyncNotifier shape, sync Notifier.build() init, paused route/listener startup, provider projection, auth/form mode error reset, loading/progress, AsyncValue, cleanupnotifier-structure.md + state-management-lifecycle.md + testing.md
Mutation method, ref.read / ref.watch / ref.listen, _ensureRepository, async cancellation, ref.mounted, optimistic update, duplicate fetchasync-mutations.md + state-management-lifecycle.md
Freezed entity, sealed union, fromJson / toJson, copyWith, model vs entity, build.yaml for explicit_to_jsonfreezed-sealed.md
Provider declaration, @riverpod, family, keepAlive, codegen, Mutation<T> (experimental)riverpod-codegen.md
Repository, datasource, domain entity, layered architecture, IHttpService, mapping models to entitiesarchitecture.md
Value Object, primitive obsession, Distance/Money/Email/Slug, unit conversion in domain, cross-entity primitive, double distanceMeters/int amountCents/String email smell, arch_domain_import errorvalue-objects.md
GoRouter, typed route, redirect, auth-protected route, router provider, context.go, deep link, custom URI scheme, native extension/activity link, cold-start, navigation gaterouting-app-shell.md + deep-linking.md
HTTP, network, REST, source-of-truth fetch after mutation, long-running remote function, async-start + reconcile, transport id vs domain idnetworking.md + debounce-gate-batch.md
Atom, molecule, organism, design tokens, atomic widgets, core/widgets/ promotionatomic-design.md
Reusable presentation/widgets/, widget-owned navigation/page stack/selected entity/workflow state, direct repository/service/provider accesspresentation-widgets.md
Accessibility, semantics, tooltip, semanticLabel, image alt text, tap target, contrast, text scalingaccessibility.md + flutter-optimizations.md
Widget test, ProviderContainer.test(), UncontrolledProviderScope, fakes, mocks, AppWidgetKeys, event-contract teststesting.md
flutter_driver, Dart MCP, Marionette MCP, E2E, integration_test, semantic selectors, scenario validation, screenshot/media proof, log capture, native integration builds but fails on device, runtime permissions, plugin hangs, release-only runtime failuredart-mcp-e2e-testing.md
Hive, TypeAdapter, TypeId, box, persistence migration, retired field accountinghive-persistence.md
Crashlytics, FirebaseCrashlytics, Sentry, sentry_flutter, DSN, error reporting, Crash.init, Crash.error, Crash.log, symbol uploaderror-reporting.md
Mixin, capability vs interface, retry helper, RNG, bulk operationmixins.md
Service, singleton, fire-and-forget, abstract final class, unawaited(), Future<void> signatureservices-and-singletons.md
@Preview, widget_previews.dart, preview fakes, deterministic preview datawidget-previews.md
AppLocalizations, ARB file, gen-l10n, locale fallback, placeholders, plural / selectlocalization.md
Performance, build cost, .select(), const constructors, ListView.builder, large list computeperformance.md + flutter-optimizations.md
LayoutBuilder, RenderFlex overflow, Expanded / Flexible outside Row / Column, Positioned outside Stack, text-scale clamplayout-diagnostics.md
Pagination, infinite scroll, cursor loading, search debounce, registration/form validation and submission, batch processing, pull-to-refreshlists-forms-workflows.md + async-mutations.md
BuildContext helpers, ModalRoute current-route checks, dialogs, SnackBarUtils, snackbar dispatch from notifiercontext-ui.md
DateTime format/diff/timeAgo/startOfDay, String capitalize/truncate/titleCase/initials/format, int / double / num clamp/pluralized/asCurrency/percent/toFixed, Duration format, NumberFormat, DateFormat, intlprimitive-formatting.md
Iterable lookup/indexing, widget list helpers, Debouncer, validators, Result, extension types, core/extensions/ barrel exportcollections-helpers.md
Records (x, y), extension type IDs, pattern matching, primary/concise constructors, new(), factory(), dot shorthand such as .center, @RecordUsedart-patterns-records.md
Flutter/Riverpod analysis_options.yaml, dart analyze, plugin wiring, riverpod_lint version pin, analyzer crashanalysis-options.md + analysis_options.yaml
Skill setup, Git pre-push, hook/scanner registrationsetup.md
build_runner, missing generated parts, clean checkout, Xcode selection, Flutter SwiftPM generated package, Apple device build, local-vs-CI mismatchbuild-reproducibility.md + core-stack.md
Package constraints, dependency upgrade, generator/analyzer compatibilitycore-stack.md
Flutter Windows desktop packaging, GitHub Actions Windows installer, Inno Setup, inno_bundle, updater/auto-update, CRT DLLs, PowerShell/native installer process, installer/version/AppId failurewindows-installer-pipeline.md + build-reproducibility.md + core-stack.md
Dart Decimate, dead code, circular dependency, duplicate code, complexity, dependency hygiene, full zero-finding scandart-decimate.md
Navigation / form / list / debounce / route-param-fallback pattern that no narrower row coverscommon-patterns.md
Incremental remote pull, delta token, per-table sync date, merge/delete reconciliationdelta-sync.md
Route-param safety, wizard sequencing, guarded next-step navigationnavigation-flow.md
Dialog / sheet / modal, snapshot value object, post-await teardown, dismiss-then-route, pop fallback, nested navigator dismissalmodals-navigation.md + state-management-lifecycle.md
Debounce / throttle / coalesce — TextField.onChanged, Slider.onChanged, scroll listener, sync saveAll, full-collection rewrite after subset mutation, persistence helper, reset/clear sentinel preservation, _userTapped gate, WebView / VideoPlayer in build, _storage.read in service, ref.listenManual ban, keepAlive collection watch, datasource batch loader, zero-value save guard, primitive→VO at notifier boundary, routeSettings on modal helperdebounce-gate-batch.md

Pre-Flight

Internal check after each .dart / pubspec.yaml / build.yaml / analysis_options.yaml write batch: T0 always; + T1 for state/notifier/mutation changes; + T2 for network/E2E/stream/route changes. Edit loop = analyze only the edited files per analysis-options.md; the full package-root run is once before handoff.

  • Failed item → report it promptly with its rule ID or ref.
  • Handoff → report the completed verification: refs read + checks run + results.
T0 — Core
  • Flutter/Riverpod package: edited files analyze clean in the edit loop; once before handoff, package-root dart analyze --fatal-infos exits 0 with flutter_skill_lints + riverpod_lint; setup changes prove one diagnostic from each plugin. Pure-Dart CLI: native Dart analysis profile applies; both plugins are N/A.
  • A current same-scope project-owned Dart Decimate result is green per dart-decimate.md; cite scan scope.
  • Async gaps are guarded: ref.mounted / context.mounted, no bare mounted, and finally uses if (ref.mounted) { ... }.
  • Providers, state, and widgets follow Rules 2-8 and 14: reusable widgets own UI lifecycle only; screens/routes/notifiers own navigation, workflow branching, selected domain records, provider state, and infrastructure.
  • Domain/data/platform follow Rules 7, 10-13, 17-24, 26-27: sealed Freezed, VOs, datasource/repo storage, core extensions, typed routes, debounce/batch, platform APIs, previews, E2E, pause-safe state, native links, and a11y; if error reporting is accepted/present, it uses one scrubbed once-only boundary, otherwise N/A.
  • Rule 25 = N/A unless Windows packaging/updater delivery is touched; when applicable, its diagnostic/publisher proof is green.
  • Any row touched in Trigger Map was read; exact lint names are cited when a scanner should enforce the rule.
T1 — State / Notifier / Mutation
  • Mutation deps resolve lazily via stateless helper/mixin; no notifier-local repo/service cache except disposable lifecycle owners.
  • Sync Notifier.build() avoids pre-return state reads; async primary state uses AsyncNotifier.build; durable sync startup does not depend on microtask timing before its owner/listener exists.
  • ref.onDispose() cancels subscriptions/controllers/timers; durable status/snackbar/teardown belongs to notifier state.
  • Long-running sync/auth/import guards stale writes; no ref.watch inside notifier methods.
  • Pause-sensitive projections watch base state directly; route pause/resume keeps the first update; auth/form mode changes clear transient errors.
T2 — Network / E2E / Stream / Route
  • Source-of-truth fetch/reconcile after generated, normalized, reordered, destructive, or remote-function mutations.
  • Shared/realtime state has writer + observer E2E proof without manual refresh.
  • Selectors use stable text/semantics/tooltips or central AppWidgetKeys; no inline string keys or coordinate primary taps.
  • E2E scenario state is deterministic and isolated from production behaviour; Marionette runs use the debug-gated binding in lib/main.dart, Flutter Driver runs a separate driver-extension entrypoint; unknown scenarios fail; critical logs fail the run; evidence shows the asserted screen before app exit; cleanup is verified.
  • GoRouter redirects use pure matrix-tested resolver, nullable by-id providers/fallback UI, and generated typed route helpers.
  • Native/custom URI producer, Android/iOS registration, Flutter delivery, and typed router share one tested scheme/host/path contract; cold/warm + signed-state device paths pass.
  • Cross-runtime constants, schemas, and function contracts have drift tests; no app-root text-scale clamp.

Comments

Markdown supported