$npx -y skills add softspark/ai-toolkit --skill dart-rulesDart/Flutter coding rules: style, patterns, security, testing. Triggers: .dart, pubspec.yaml, Flutter, Riverpod, Bloc, widget, StatelessWidget, StatefulWidget.
| 1 | # Dart/Flutter Rules |
| 2 | |
| 3 | These rules come from `app/rules/dart/` in ai-toolkit. They cover |
| 4 | the project's standards for coding style, frameworks, patterns, |
| 5 | security, and testing in Dart/Flutter. Apply them when writing or |
| 6 | reviewing Dart/Flutter code. |
| 7 | |
| 8 | # Dart Coding Style |
| 9 | |
| 10 | ## Naming |
| 11 | - PascalCase: classes, enums, typedefs, extensions, mixins. |
| 12 | - camelCase: variables, functions, methods, parameters, named constants. |
| 13 | - snake_case: libraries, packages, directories, source files. |
| 14 | - UPPER_SNAKE: not used in Dart. Use camelCase for constants. |
| 15 | - Prefix private members with `_`: `_internalState`, `_helper()`. |
| 16 | |
| 17 | ## Null Safety |
| 18 | - Enable sound null safety (default since Dart 2.12). |
| 19 | - Use `?` types only when null is semantically meaningful. |
| 20 | - Use `!` operator sparingly. Prefer null checks or `??` fallback. |
| 21 | - Use `late` keyword only when initialization is guaranteed before access. |
| 22 | - Use `required` keyword for mandatory named parameters. |
| 23 | |
| 24 | ## Classes |
| 25 | - Use `const` constructors for immutable classes. |
| 26 | - Use factory constructors for caching, subtype selection, or validation. |
| 27 | - Use named constructors for clarity: `Point.fromJson(json)`. |
| 28 | - Use `final` fields for immutable properties. |
| 29 | - Use `@immutable` annotation on classes that should be immutable. |
| 30 | |
| 31 | ## Functions |
| 32 | - Use named parameters for functions with >2 parameters. |
| 33 | - Use `required` for mandatory named parameters. |
| 34 | - Use default values for optional parameters. |
| 35 | - Use fat arrow (`=>`) for single-expression functions. |
| 36 | - Always specify return types for public functions. |
| 37 | |
| 38 | ## Collections |
| 39 | - Use collection literals: `[]`, `{}`, `<String, int>{}`. |
| 40 | - Use `if` and `for` inside collection literals for conditional/iterative building. |
| 41 | - Use spread operator: `[...list1, ...list2]`. |
| 42 | - Use `whereType<T>()` for type-safe filtering. |
| 43 | - Prefer `const` collections when values are known at compile time. |
| 44 | |
| 45 | ## Async |
| 46 | - Use `async`/`await` for all asynchronous operations. |
| 47 | - Return `Future<T>` from async functions. Never return `void`. |
| 48 | - Use `Stream<T>` for continuous data (events, real-time updates). |
| 49 | - Use `Future.wait()` for concurrent independent operations. |
| 50 | - Use `Completer<T>` only when wrapping callback-based APIs. |
| 51 | |
| 52 | ## Imports |
| 53 | - Order: `dart:` SDK, `package:` external, relative project imports. |
| 54 | - Use `show`/`hide` to limit import scope when names conflict. |
| 55 | - Use `as` prefix for namespace conflicts: `import 'package:foo/foo.dart' as foo`. |
| 56 | - Prefer relative imports within the same package. |
| 57 | |
| 58 | ## Formatting |
| 59 | - Use `dart format` (line length 80) for consistent formatting. |
| 60 | - Use `dart analyze` for static analysis with default lint rules. |
| 61 | - Use `analysis_options.yaml` with recommended lints: `flutter_lints` or `lints`. |
| 62 | - Use trailing commas in multi-line argument lists for cleaner diffs. |
| 63 | |
| 64 | # Dart Frameworks |
| 65 | |
| 66 | ## Flutter |
| 67 | - Use `StatelessWidget` by default. Use `StatefulWidget` only for local state. |
| 68 | - Use `const` constructors and `const` widgets for build optimization. |
| 69 | - Use `Key` parameters for widgets in lists for correct diffing. |
| 70 | - Extract large `build()` methods into smaller widget classes (not methods). |
| 71 | - Use `Theme.of(context)` and `TextTheme` for consistent styling. |
| 72 | |
| 73 | ## Navigation |
| 74 | - Use `GoRouter` for declarative, type-safe routing. |
| 75 | - Define routes as constants: `static const String home = '/home'`. |
| 76 | - Use `ShellRoute` for persistent navigation bars across routes. |
| 77 | - Use `context.go()` for navigation, `context.push()` for stacking. |
| 78 | - Pass arguments via path parameters or `extra` for complex objects. |
| 79 | |
| 80 | ## Networking |
| 81 | - Use `dio` for HTTP with interceptors, retry, and cancellation. |
| 82 | - Use `retrofit` (code gen) for type-safe REST client definitions. |
| 83 | - Use interceptors for auth token injection and refresh logic. |
| 84 | - Set timeouts on every request: `connectTimeout`, `receiveTimeout`. |
| 85 | - Use `CancelToken` for cancelling in-flight requests on navigation. |
| 86 | |
| 87 | ## JSON Serialization |
| 88 | - Use `json_serializable` (+ `build_runner`) for generated `fromJson`/`toJson`. Default `fieldRename: FieldRename.none` uses Dart property names as-is — combined with Effective Dart `lowerCamelCase`, this produces `camelCase` JSON keys with zero configuration. |
| 89 | - Flutter docs recommend: *"best if both server and client follow the same naming strategy"* ([Flutter — JSON and serialization](https://docs.flutter.dev/data-and-backend/serialization/json)). When they do, no mapping is needed. |
| 90 | - When server uses a different convention, prefer `@JsonSerializable(fieldRename: FieldRename.snake)` at the class level (or globally in `build.yaml`) over sprinkling `@JsonKey(name:)` on every field. Community recommendation from the `json_serializable` docs and pub.dev guides. |
| 91 | - Use individual `@JsonKey(name: '...')` only for exceptional cases: external API with mixed conventions, reserved Dart keyword collision (`clas |