reis-mobile 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/.claude-plugin/marketplace.json +24 -0
  2. package/.claude-plugin/plugin.json +12 -0
  3. package/CHANGELOG.md +103 -0
  4. package/LICENSE +21 -0
  5. package/README.md +631 -0
  6. package/THIRD_PARTY_NOTICES.md +105 -0
  7. package/agents/flutter-architect.md +92 -0
  8. package/agents/flutter-performance-engineer.md +103 -0
  9. package/agents/flutter-test-engineer.md +100 -0
  10. package/agents/lead-mobile.md +107 -0
  11. package/agents/mobile-code-reviewer.md +66 -0
  12. package/agents/mobile-staff-engineer.md +85 -0
  13. package/agents/plugin-native-expert.md +97 -0
  14. package/bin/reis-mobile.mjs +256 -0
  15. package/commands/debate.md +135 -0
  16. package/commands/doctor.md +23 -0
  17. package/commands/reis-mobile.md +50 -0
  18. package/commands/review.md +53 -0
  19. package/core/config/language.mjs +83 -0
  20. package/core/context/context-engine.mjs +113 -0
  21. package/core/detection/project-probe.mjs +104 -0
  22. package/core/detection/stack-detector.mjs +204 -0
  23. package/core/diagnostics/doctor.mjs +181 -0
  24. package/core/install/claude-plugin.mjs +76 -0
  25. package/core/paths.mjs +4 -0
  26. package/core/registry/frontmatter.mjs +81 -0
  27. package/core/registry/registry.mjs +140 -0
  28. package/core/router/intent-detector.mjs +75 -0
  29. package/core/router/intents.mjs +91 -0
  30. package/core/router/router.mjs +83 -0
  31. package/core/security/redact.mjs +24 -0
  32. package/package.json +35 -0
  33. package/skills/architecture-feature-first/SKILL.md +116 -0
  34. package/skills/bloc/SKILL.md +354 -0
  35. package/skills/code-review/SKILL.md +89 -0
  36. package/skills/dart-3-updates/SKILL.md +223 -0
  37. package/skills/dart-add-unit-test/SKILL.md +126 -0
  38. package/skills/dart-collect-coverage/SKILL.md +145 -0
  39. package/skills/dart-fix-runtime-errors/SKILL.md +170 -0
  40. package/skills/dart-generate-test-mocks/SKILL.md +159 -0
  41. package/skills/dart-migrate-to-checks-package/SKILL.md +532 -0
  42. package/skills/dart-resolve-package-conflicts/SKILL.md +120 -0
  43. package/skills/dart-run-static-analysis/SKILL.md +108 -0
  44. package/skills/dart-use-pattern-matching/SKILL.md +240 -0
  45. package/skills/dart-use-pattern-matching/examples/json_patterns.dart +85 -0
  46. package/skills/detect-mobile-stack/SKILL.md +33 -0
  47. package/skills/effective-dart/SKILL.md +187 -0
  48. package/skills/firebase-ai/SKILL.md +93 -0
  49. package/skills/firebase-analytics/SKILL.md +129 -0
  50. package/skills/firebase-app-check/SKILL.md +124 -0
  51. package/skills/firebase-auth/SKILL.md +224 -0
  52. package/skills/firebase-cloud-firestore/SKILL.md +165 -0
  53. package/skills/firebase-cloud-functions/SKILL.md +148 -0
  54. package/skills/firebase-crashlytics/SKILL.md +182 -0
  55. package/skills/firebase-data-connect/SKILL.md +80 -0
  56. package/skills/firebase-database/SKILL.md +224 -0
  57. package/skills/firebase-in-app-messaging/SKILL.md +111 -0
  58. package/skills/firebase-messaging/SKILL.md +201 -0
  59. package/skills/firebase-remote-config/SKILL.md +131 -0
  60. package/skills/firebase-storage/SKILL.md +158 -0
  61. package/skills/flutter-add-integration-test/SKILL.md +167 -0
  62. package/skills/flutter-add-widget-preview/SKILL.md +149 -0
  63. package/skills/flutter-add-widget-test/SKILL.md +158 -0
  64. package/skills/flutter-adding-home-screen-widgets/SKILL.md +205 -0
  65. package/skills/flutter-animating-apps/SKILL.md +185 -0
  66. package/skills/flutter-app-architecture/SKILL.md +80 -0
  67. package/skills/flutter-apply-architecture-best-practices/SKILL.md +166 -0
  68. package/skills/flutter-build-responsive-layout/SKILL.md +143 -0
  69. package/skills/flutter-building-forms/SKILL.md +125 -0
  70. package/skills/flutter-building-layouts/SKILL.md +131 -0
  71. package/skills/flutter-building-plugins/SKILL.md +209 -0
  72. package/skills/flutter-caching-data/SKILL.md +171 -0
  73. package/skills/flutter-change-notifier/SKILL.md +138 -0
  74. package/skills/flutter-embedding-native-views/SKILL.md +200 -0
  75. package/skills/flutter-errors/SKILL.md +126 -0
  76. package/skills/flutter-fix-layout-issues/SKILL.md +134 -0
  77. package/skills/flutter-handling-concurrency/SKILL.md +182 -0
  78. package/skills/flutter-implement-json-serialization/SKILL.md +157 -0
  79. package/skills/flutter-improving-accessibility/SKILL.md +113 -0
  80. package/skills/flutter-interoperating-with-native-apis/SKILL.md +130 -0
  81. package/skills/flutter-login-usecase/SKILL.md +38 -0
  82. package/skills/flutter-managing-state/SKILL.md +206 -0
  83. package/skills/flutter-project-audit/SKILL.md +66 -0
  84. package/skills/flutter-reducing-app-size/SKILL.md +103 -0
  85. package/skills/flutter-secure-token-store/SKILL.md +35 -0
  86. package/skills/flutter-setting-up-on-macos/SKILL.md +78 -0
  87. package/skills/flutter-setup-declarative-routing/SKILL.md +259 -0
  88. package/skills/flutter-setup-localization/SKILL.md +214 -0
  89. package/skills/flutter-theming-apps/SKILL.md +163 -0
  90. package/skills/flutter-use-http-package/SKILL.md +178 -0
  91. package/skills/flutter-widget-review/SKILL.md +54 -0
  92. package/skills/flutter-working-with-databases/SKILL.md +203 -0
  93. package/skills/flutterfire-configure/SKILL.md +143 -0
  94. package/skills/mobile-security-audit/SKILL.md +101 -0
  95. package/skills/mockito/SKILL.md +149 -0
  96. package/skills/mocktail/SKILL.md +122 -0
  97. package/skills/patrol-e2e-testing/SKILL.md +224 -0
  98. package/skills/provider/SKILL.md +139 -0
  99. package/skills/riverpod/SKILL.md +246 -0
  100. package/skills/testing/SKILL.md +50 -0
  101. package/stacks/android/stack.json +8 -0
  102. package/stacks/flutter/stack.json +8 -0
  103. package/stacks/ios/stack.json +8 -0
  104. package/stacks/kotlin-multiplatform/stack.json +8 -0
  105. package/stacks/react-native/stack.json +8 -0
@@ -0,0 +1,223 @@
1
+ ---
2
+ name: dart-3-updates
3
+ description: Applies Dart 3 language features in Flutter/Dart code. Use when writing if-else or switch statements, creating new classes, or deciding between a data class and a record.
4
+ intents: [migration]
5
+ stacks: [flutter]
6
+ source: https://github.com/evanca/flutter-ai-rules
7
+ license: MIT
8
+ ---
9
+
10
+ # Dart 3 Updates Skill
11
+
12
+ This skill defines how to correctly use Dart 3 language features: branches, patterns, pattern types, and records.
13
+
14
+ ---
15
+
16
+ ## 1. Branches
17
+
18
+ ### if / if-case
19
+
20
+ ```dart
21
+ // Standard if
22
+ if (score >= 90) {
23
+ grade = 'A';
24
+ } else if (score >= 80) {
25
+ grade = 'B';
26
+ } else {
27
+ grade = 'C';
28
+ }
29
+
30
+ // if-case: match and destructure against a single pattern
31
+ if (pair case [int x, int y]) {
32
+ print('$x, $y');
33
+ }
34
+ ```
35
+
36
+ - `if` conditions must evaluate to a `bool`.
37
+ - In `if-case`, variables declared in the pattern are scoped to the matching branch.
38
+ - If the pattern does not match, control flows to the `else` branch (if present).
39
+
40
+ ### switch statements
41
+
42
+ ```dart
43
+ switch (command) {
44
+ case 'quit':
45
+ quit();
46
+ case 'start' || 'begin': // logical-or pattern
47
+ startGame();
48
+ default:
49
+ print('Unknown command');
50
+ }
51
+ ```
52
+
53
+ - Each matched `case` body executes and jumps to the end — `break` is **not required**.
54
+ - Non-empty cases can end with `continue`, `throw`, or `return`.
55
+ - Use `default` or `_` to handle unmatched values.
56
+ - Empty cases fall through; use `break` to prevent fallthrough in an empty case.
57
+ - Use `continue` with a label for non-sequential fallthrough.
58
+ - Use logical-or patterns (`case a || b`) to share a body between cases.
59
+
60
+ ### switch expressions
61
+
62
+ ```dart
63
+ final color = switch (shape) {
64
+ Circle() => 'red',
65
+ Square() => 'blue',
66
+ _ => 'unknown',
67
+ };
68
+ ```
69
+
70
+ - Omit `case`; use `=>` for bodies; separate cases with commas.
71
+ - Default must use `_` (not `default`).
72
+ - Produces a value.
73
+
74
+ ### Exhaustiveness
75
+
76
+ - Dart checks exhaustiveness in `switch` statements and expressions at compile time.
77
+ - Use `default`/`_`, enums, or `sealed` types to satisfy exhaustiveness.
78
+
79
+ ```dart
80
+ sealed class Shape {}
81
+ class Circle extends Shape {}
82
+ class Square extends Shape {}
83
+
84
+ // Dart knows all subtypes — no default needed:
85
+ String describe(Shape s) => switch (s) {
86
+ Circle() => 'circle',
87
+ Square() => 'square',
88
+ };
89
+ ```
90
+
91
+ ### Guard clauses
92
+
93
+ ```dart
94
+ switch (point) {
95
+ case (int x, int y) when x == y:
96
+ print('Diagonal: $x');
97
+ case (int x, int y):
98
+ print('$x, $y');
99
+ }
100
+ ```
101
+
102
+ - Add `when condition` after a pattern to further constrain matching.
103
+ - Usable in `if-case`, `switch` statements, and `switch` expressions.
104
+ - If the guard is `false`, execution proceeds to the next case.
105
+
106
+ ---
107
+
108
+ ## 2. Patterns
109
+
110
+ Patterns represent the **shape** of a value for matching and destructuring.
111
+
112
+ ### Uses
113
+
114
+ ```dart
115
+ // Variable declaration
116
+ var (a, [b, c]) = ('str', [1, 2]);
117
+
118
+ // Variable assignment (swap)
119
+ (b, a) = (a, b);
120
+
121
+ // for-in loop destructuring
122
+ for (final MapEntry(:key, :value) in map.entries) { ... }
123
+
124
+ // switch / if-case (see Branches section)
125
+ ```
126
+
127
+ - Wildcard `_` ignores parts of a matched value.
128
+ - Rest elements (`...`) in list patterns ignore remaining elements.
129
+ - Case patterns are **refutable**: if no match, execution continues to the next case.
130
+ - Destructured values in a case become local variables scoped to that case body.
131
+
132
+ ### Object patterns
133
+
134
+ ```dart
135
+ var Foo(:one, :two) = myFoo;
136
+ ```
137
+
138
+ ### JSON / nested data validation
139
+
140
+ ```dart
141
+ if (data case {'user': [String name, int age]}) {
142
+ print('$name, $age');
143
+ }
144
+ ```
145
+
146
+ ---
147
+
148
+ ## 3. Pattern Types
149
+
150
+ | Pattern | Syntax | Description |
151
+ |---|---|---|
152
+ | Logical-or | `p1 \|\| p2` | Matches if any branch matches. All branches must bind the same variables. |
153
+ | Logical-and | `p1 && p2` | Matches if both match. Variable names must not overlap. |
154
+ | Relational | `== c`, `< c`, `>= c` | Compares value to a constant. Combine with `&&` for ranges. |
155
+ | Cast | `subpattern as Type` | Asserts type, then matches inner pattern. Throws if type mismatch. |
156
+ | Null-check | `subpattern?` | Matches non-null; binds non-nullable type. |
157
+ | Null-assert | `subpattern!` | Matches non-null or throws. Use in declarations to eliminate nulls. |
158
+ | Constant | `42`, `'str'`, `const Foo()` | Matches if value equals the constant. |
159
+ | Variable | `var name`, `final Type name` | Binds matched value to a new variable. Typed form only matches the declared type. |
160
+ | Wildcard | `_`, `Type _` | Matches any value without binding. |
161
+ | Parenthesized | `(subpattern)` | Controls precedence. |
162
+ | List | `[p1, p2]` | Matches lists by position. Length must match unless a rest element is used. |
163
+ | Rest element | `...`, `...rest` | Matches arbitrary-length tails or collects remaining elements. |
164
+ | Map | `{'key': subpattern}` | Matches maps by key. Missing keys throw `StateError`. |
165
+ | Record | `(p1, p2)`, `(x: p1, y: p2)` | Matches records by shape; field names can be omitted if inferred. |
166
+ | Object | `ClassName(field: p)` | Matches by type and destructures via getters. Extra fields ignored. |
167
+
168
+ - Use parentheses to group lower-precedence patterns.
169
+ - All pattern types can be **nested and combined**.
170
+
171
+ ---
172
+
173
+ ## 4. Records
174
+
175
+ ```dart
176
+ // Create
177
+ var record = ('first', a: 2, b: true, 'last');
178
+
179
+ // Type annotation
180
+ ({int a, bool b}) namedRecord;
181
+
182
+ // Access
183
+ print(record.$1); // positional: 'first'
184
+ print(record.a); // named: 2
185
+ ```
186
+
187
+ - Records are **anonymous, immutable, fixed-size** aggregates.
188
+ - Each field can have a different type (heterogeneous).
189
+ - Fields are accessed via built-in getters (`$1`, `$2`, `.name`); no setters.
190
+ - Two records are equal if they have the same shape and equal field values.
191
+ - `hashCode` and `==` are automatically defined.
192
+
193
+ ### Multiple return values
194
+
195
+ ```dart
196
+ (String name, int age) userInfo(Map<String, dynamic> json) {
197
+ return (json['name'] as String, json['age'] as int);
198
+ }
199
+
200
+ var (name, age) = userInfo(json);
201
+ // Named fields:
202
+ final (:name, :age) = userInfo(json);
203
+ ```
204
+
205
+ ### Records vs. data classes
206
+
207
+ Use a **record** when:
208
+ - Returning multiple values from a single function (small, one-time use).
209
+ - Grouping a few values locally with no reuse across the codebase.
210
+ - You need structural equality with no additional behavior.
211
+
212
+ Use a **class** when:
213
+ - The type is reused across multiple files or features.
214
+ - You need methods, encapsulation, inheritance, or `copyWith`.
215
+ - The type is part of a public API or long-lived data model.
216
+ - Changing the shape must be caught by the type system across the codebase.
217
+
218
+ ### Other best practices
219
+
220
+ - Use `typedef` for record types to improve readability and maintainability.
221
+ - Changing a record type alias does not guarantee type safety across the codebase — only classes provide full abstraction.
222
+
223
+ ---
@@ -0,0 +1,126 @@
1
+ ---
2
+ name: dart-add-unit-test
3
+ description: Write and organize unit tests for functions, methods, and classes using `package:test`. Use when creating new logic or fixing bugs to ensure code remains correct and regression-free.
4
+ metadata:
5
+ model: models/gemini-3.1-pro-preview
6
+ last_modified: Mon, 03 Aug 2026 21:51:24 GMT
7
+ intents: [test]
8
+ stacks: [flutter]
9
+ source: https://github.com/dart-lang/skills
10
+ license: BSD-3-Clause
11
+ ---
12
+ # Testing Dart and Flutter Applications
13
+
14
+ ## Contents
15
+ - [Structuring Test Files](#structuring-test-files)
16
+ - [Writing Tests](#writing-tests)
17
+ - [Executing Tests](#executing-tests)
18
+ - [Test Implementation Workflow](#test-implementation-workflow)
19
+ - [Examples](#examples)
20
+
21
+ ## Structuring Test Files
22
+ Organize test files to mirror the `lib` directory structure to maintain predictability.
23
+
24
+ * Place all test code within the `test` directory at the root of the package.
25
+ * Append `_test.dart` to the end of all test file names (e.g., `lib/src/utils.dart` should be tested in `test/src/utils_test.dart`).
26
+ * If writing integration tests, place them in an `integration_test` directory at the root of the package.
27
+
28
+ ## Writing Tests
29
+ Utilize `package:test` as the standard testing library for Dart applications.
30
+
31
+ * Import `package:test/test.dart` (or `package:flutter_test/flutter_test.dart` for Flutter).
32
+ * Group related tests using the `group()` function to provide shared context.
33
+ * Define individual test cases using the `test()` function.
34
+ * Validate outcomes using the `expect()` function alongside matchers (e.g., `equals()`, `isTrue`, `throwsA()`).
35
+ * Write asynchronous tests using standard `async`/`await` syntax. The test runner automatically waits for the `Future` to complete.
36
+ * Manage test setup and teardown using `setUp()` and `tearDown()` callbacks.
37
+ * If testing code that relies on dependency injection, use `package:mockito` alongside `package:test` to generate mock objects, configure fixed scenarios, and verify interactions.
38
+
39
+ ## Executing Tests
40
+ Select the appropriate test runner based on the project type and test location.
41
+
42
+ * If working on a pure Dart project, execute tests using the `dart test` command.
43
+ * If working on a Flutter project, execute tests using the `flutter test` command.
44
+ * If running integration tests, explicitly specify the directory path, as the default runner ignores it: `dart test integration_test` or `flutter test integration_test`.
45
+
46
+ ## Test Implementation Workflow
47
+
48
+ Follow this sequential workflow when implementing new test suites. Copy the checklist to track your progress.
49
+
50
+ ### Task Progress
51
+ - [ ] 1. Create the test file in the `test/` directory, ensuring the `_test.dart` suffix.
52
+ - [ ] 2. Import `package:test/test.dart` and the target library.
53
+ - [ ] 3. Define a `main()` function.
54
+ - [ ] 4. Initialize shared resources or mocks using `setUp()`.
55
+ - [ ] 5. Write `test()` cases grouped by functionality using `group()`.
56
+ - [ ] 6. Execute the test suite using the appropriate CLI command.
57
+ - [ ] 7. **Feedback Loop**: Run test -> Review stack trace for failures -> Fix implementation or assertions -> Re-run until passing.
58
+
59
+ ## Examples
60
+
61
+ ### Standard Unit Test Suite
62
+ Demonstrates grouping, setup, synchronous, and asynchronous testing.
63
+
64
+ ```dart
65
+ import 'package:test/test.dart';
66
+ import 'package:my_package/calculator.dart';
67
+
68
+ void main() {
69
+ group('Calculator', () {
70
+ late Calculator calc;
71
+
72
+ setUp(() {
73
+ calc = Calculator();
74
+ });
75
+
76
+ test('adds two numbers correctly', () {
77
+ expect(calc.add(2, 3), equals(5));
78
+ });
79
+
80
+ test('handles asynchronous operations', () async {
81
+ final result = await calc.fetchRemoteValue();
82
+ expect(result, isNotNull);
83
+ expect(result, greaterThan(0));
84
+ });
85
+ });
86
+ }
87
+ ```
88
+
89
+ ### Mocking with Mockito
90
+ Demonstrates configuring a mock object for dependency injection testing.
91
+
92
+ ```dart
93
+ import 'package:test/test.dart';
94
+ import 'package:mockito/mockito.dart';
95
+ import 'package:mockito/annotations.dart';
96
+ import 'package:my_package/api_client.dart';
97
+ import 'package:my_package/data_service.dart';
98
+
99
+ // Generate the mock using build_runner: dart run build_runner build
100
+ @GenerateNiceMocks([MockSpec<ApiClient>()])
101
+ import 'data_service_test.mocks.dart';
102
+
103
+ void main() {
104
+ group('DataService', () {
105
+ late MockApiClient mockApiClient;
106
+ late DataService dataService;
107
+
108
+ setUp(() {
109
+ mockApiClient = MockApiClient();
110
+ dataService = DataService(apiClient: mockApiClient);
111
+ });
112
+
113
+ test('returns parsed data on successful API call', () async {
114
+ // Configure the mock
115
+ when(mockApiClient.get('/data')).thenAnswer((_) async => '{"id": 1}');
116
+
117
+ // Execute the system under test
118
+ final result = await dataService.fetchData();
119
+
120
+ // Verify outcomes and interactions
121
+ expect(result.id, equals(1));
122
+ verify(mockApiClient.get('/data')).called(1);
123
+ });
124
+ });
125
+ }
126
+ ```
@@ -0,0 +1,145 @@
1
+ ---
2
+ name: dart-collect-coverage
3
+ description: Collect coverage using the coverage packge and create an LCOV report
4
+ metadata:
5
+ model: models/gemini-3.1-pro-preview
6
+ last_modified: Fri, 24 Apr 2026 15:14:32 GMT
7
+ intents: [test]
8
+ stacks: [flutter]
9
+ source: https://github.com/dart-lang/skills
10
+ license: BSD-3-Clause
11
+ ---
12
+ # Implementing Dart and Flutter Test Coverage
13
+
14
+ ## Contents
15
+ - [Testing Fundamentals](#testing-fundamentals)
16
+ - [Coverage Directives](#coverage-directives)
17
+ - [Workflow: Configuring and Generating Coverage Reports](#workflow-configuring-and-generating-coverage-reports)
18
+ - [Workflow: Advanced Manual Coverage Collection](#workflow-advanced-manual-coverage-collection)
19
+ - [Examples](#examples)
20
+
21
+ ## Testing Fundamentals
22
+
23
+ Structure your test suites using the standard Dart testing paradigms. Use `package:test` for Dart projects and `flutter_test` for Flutter projects.
24
+
25
+ - **Unit Tests:** Verify individual functions, methods, or classes.
26
+ - **Component/Widget Tests:** Verify component behavior, layout, and interaction using mock objects (`package:mockito`).
27
+ - **Integration Tests:** Verify entire app flows on simulated or real devices.
28
+
29
+ ## Coverage Directives
30
+
31
+ Exclude specific lines, blocks, or entire files from coverage metrics using inline comments. Pass the `--check-ignore` flag during formatting to enforce these directives.
32
+
33
+ - Ignore a single line: `// coverage:ignore-line`
34
+ - Ignore a block of code: `// coverage:ignore-start` and `// coverage:ignore-end`
35
+ - Ignore an entire file: `// coverage:ignore-file`
36
+
37
+ ## Workflow: Configuring and Generating Coverage Reports
38
+
39
+ Follow this sequential workflow to add the coverage package, execute tests, and generate an LCOV report.
40
+
41
+ **Task Progress Checklist:**
42
+ - [ ] 1. Add `coverage` as a `dev_dependency`.
43
+ - [ ] 2. Execute the automated coverage script.
44
+ - [ ] 3. Validate the LCOV output.
45
+
46
+ ### 1. Add Dependencies
47
+ Add the `coverage` package as a `dev_dependency` to your project. Do not add it to standard dependencies.
48
+
49
+ If working in a standard Dart project:
50
+ ```bash
51
+ dart pub add dev:coverage
52
+ ```
53
+
54
+ If working in a Flutter project:
55
+ ```bash
56
+ flutter pub add dev:coverage
57
+ ```
58
+
59
+ ### 2. Collect Coverage and Generate LCOV
60
+ Use the bundled `test_with_coverage` script. This script automatically runs all tests, collects the JSON coverage data from the Dart VM, and formats it into an LCOV report.
61
+
62
+ ```bash
63
+ dart run coverage:test_with_coverage
64
+ ```
65
+ *Note: If working within a Dart workspace (monorepo), specify the test directories explicitly (e.g., `dart run coverage:test_with_coverage -- pkgs/foo/test pkgs/bar/test`).*
66
+
67
+ ### 3. Feedback Loop: Validate Output
68
+ **Run validator -> review errors -> fix:**
69
+ 1. Verify that the `coverage/` directory was created in the project root.
70
+ 2. Ensure `coverage/coverage.json` (raw data) and `coverage/lcov.info` (formatted report) exist.
71
+ 3. If coverage is missing for specific files, ensure they are imported and executed by your test files, or add `// coverage:ignore-file` if they are intentionally excluded.
72
+
73
+ ## Workflow: Advanced Manual Coverage Collection
74
+
75
+ If you require granular control over the VM service, isolate pausing, or need branch/function-level coverage, use the manual collection workflow.
76
+
77
+ **Task Progress Checklist:**
78
+ - [ ] 1. Run tests with VM service enabled.
79
+ - [ ] 2. Collect raw JSON coverage.
80
+ - [ ] 3. Format JSON to LCOV.
81
+
82
+ ### 1. Run Tests with VM Service
83
+ Execute tests while pausing isolates on exit and exposing the VM service on a specific port (e.g., 8181).
84
+
85
+ ```bash
86
+ dart run --pause-isolates-on-exit --disable-service-auth-codes --enable-vm-service=8181 test &
87
+ ```
88
+
89
+ ### 2. Collect Raw Coverage
90
+ Extract the coverage data from the running VM service and output it to a JSON file.
91
+
92
+ ```bash
93
+ dart run coverage:collect_coverage --wait-paused --uri=http://127.0.0.1:8181/ -o coverage/coverage.json --resume-isolates
94
+ ```
95
+ *Optional: Append `--function-coverage` and `--branch-coverage` to gather deeper metrics (requires Dart VM 2.17.0+).*
96
+
97
+ ### 3. Format to LCOV
98
+ Convert the raw JSON data into the standard LCOV format.
99
+
100
+ ```bash
101
+ dart run coverage:format_coverage --packages=.dart_tool/package_config.json --lcov -i coverage/coverage.json -o coverage/lcov.info --check-ignore
102
+ ```
103
+
104
+ ## Examples
105
+
106
+ ### Example: `pubspec.yaml` Configuration
107
+ Ensure your `pubspec.yaml` reflects the `coverage` package strictly under `dev_dependencies`.
108
+
109
+ ```yaml
110
+ name: my_dart_app
111
+ environment:
112
+ sdk: ^3.0.0
113
+
114
+ dependencies:
115
+ path: ^1.8.0
116
+
117
+ dev_dependencies:
118
+ test: ^1.24.0
119
+ coverage: ^1.15.0
120
+ ```
121
+
122
+ ### Example: Applying Ignore Directives
123
+ Use ignore directives to prevent generated code or untestable edge cases from lowering coverage scores.
124
+
125
+ ```dart
126
+ // coverage:ignore-file
127
+ import 'package:meta/meta.dart';
128
+
129
+ class SystemConfig {
130
+ final String env;
131
+
132
+ SystemConfig(this.env);
133
+
134
+ // coverage:ignore-start
135
+ void legacyInit() {
136
+ print('Deprecated initialization');
137
+ }
138
+ // coverage:ignore-end
139
+
140
+ bool isProduction() {
141
+ if (env == 'prod') return true;
142
+ return false; // coverage:ignore-line
143
+ }
144
+ }
145
+ ```
@@ -0,0 +1,170 @@
1
+ ---
2
+ name: dart-fix-runtime-errors
3
+ description: Uses get_runtime_errors and lsp to fetch an active stack trace, locate the failing line, apply a fix, and verify resolution via hot_reload.
4
+ metadata:
5
+ model: models/gemini-3.1-pro-preview
6
+ last_modified: Fri, 24 Apr 2026 15:13:22 GMT
7
+ intents: [debug]
8
+ stacks: [flutter]
9
+ source: https://github.com/dart-lang/skills
10
+ license: BSD-3-Clause
11
+ ---
12
+ # Resolving Dart Static Analysis Errors
13
+
14
+ ## Contents
15
+ - [Core Concepts & Guidelines](#core-concepts--guidelines)
16
+ - [Type System & Soundness](#type-system--soundness)
17
+ - [Null Safety](#null-safety)
18
+ - [Error Handling](#error-handling)
19
+ - [Workflows](#workflows)
20
+ - [Workflow: Static Analysis Resolution](#workflow-static-analysis-resolution)
21
+ - [Examples](#examples)
22
+
23
+ ## Core Concepts & Guidelines
24
+
25
+ ### Type System & Soundness
26
+ Enforce Dart's sound type system to prevent runtime invalid states.
27
+
28
+ * **Method Overrides:** Maintain sound return types (covariant) and parameter types (contravariant). Never tighten a parameter type in a subclass unless explicitly marked with the `covariant` keyword.
29
+ * **Generics & Collections:** Add explicit type annotations to generic classes (e.g., `List<T>`, `Map<K, V>`). Never assign a `List<dynamic>` to a typed list (e.g., `List<Cat>`).
30
+ * **Downcasting:** Avoid implicit downcasts from `dynamic`. Use explicit casts (e.g., `as List<Cat>`) when necessary, but ensure the underlying runtime type matches to prevent `TypeError` exceptions.
31
+ * **Strict Casts:** Enable `strict-casts: true` in `analysis_options.yaml` under `analyzer: language:` to force explicit casting and catch implicit downcast errors at compile time.
32
+
33
+ ### Null Safety
34
+ Eliminate static errors related to null safety by correctly managing variable initialization and nullability.
35
+
36
+ * **Modifiers:** Apply `?` for nullable types, `!` for null assertions, and `required` for named parameters that cannot be null.
37
+ * **Late Initialization:** Use the `late` keyword for non-nullable variables guaranteed to be initialized before use. Apply this specifically to top-level or instance variables where Dart's control flow analysis cannot definitively prove initialization.
38
+ * **Wildcards:** Use the `_` wildcard variable (Dart 3.7+) for non-binding local variables or parameters to avoid unused variable warnings.
39
+
40
+ ### Error Handling
41
+ Distinguish between recoverable exceptions and unrecoverable errors.
42
+
43
+ * **Catching:** Catch `Exception` subtypes for recoverable failures.
44
+ * **Errors:** Never explicitly catch `Error` or its subtypes (e.g., `TypeError`, `ArgumentError`). Errors indicate programming bugs that must be fixed, not caught. Enforce this by enabling the `avoid_catching_errors` linter rule.
45
+ * **Rethrowing:** Use `rethrow` inside a `catch` block to propagate an exception while preserving its original stack trace.
46
+
47
+ ## Workflows
48
+
49
+ ### Workflow: Static Analysis Resolution
50
+
51
+ Use this sequential workflow to identify, fix, and verify static analysis errors in a Dart project. Copy the checklist to track your progress.
52
+
53
+ **Task Progress:**
54
+ - [ ] 1. Run static analyzer.
55
+ - [ ] 2. Apply automated fixes.
56
+ - [ ] 3. Resolve remaining errors manually.
57
+ - [ ] 4. Verify fixes (Feedback Loop).
58
+
59
+ **1. Run static analyzer**
60
+ Execute the Dart analyzer to identify all static errors in the target directory or file.
61
+ ```bash
62
+ dart analyze . --fatal-infos
63
+ ```
64
+
65
+ **2. Apply automated fixes**
66
+ Use the `dart fix` tool to automatically resolve standard linting and analysis issues.
67
+ ```bash
68
+ # Preview changes
69
+ dart fix --dry-run
70
+ # Apply changes
71
+ dart fix --apply
72
+ ```
73
+
74
+ **3. Resolve remaining errors manually**
75
+ Review the remaining analyzer output and apply conditional logic based on the error type:
76
+
77
+ * **If the error is a Null Safety issue (e.g., "Property cannot be accessed on a nullable receiver"):**
78
+ * Verify if the variable can logically be null.
79
+ * If yes, use optional chaining (`?.`) or provide a fallback (`??`).
80
+ * If no, and initialization is guaranteed elsewhere, mark the declaration with `late`.
81
+ * **If the error is a Type Mismatch (e.g., "The argument type 'List<dynamic>' can't be assigned..."):**
82
+ * Trace the variable's initialization.
83
+ * Add explicit generic type annotations to the instantiation (e.g., `<int>[]` instead of `[]`).
84
+ * **If the error is an Invalid Override (e.g., "The parameter type doesn't match the overridden method"):**
85
+ * Widen the parameter type to match the superclass, OR
86
+ * Add the `covariant` keyword to the parameter if tightening the type is intentionally required by the domain logic.
87
+
88
+ **4. Verify fixes (Feedback Loop)**
89
+ Run the validator. Review errors. Fix.
90
+ ```bash
91
+ dart analyze .
92
+ dart test
93
+ ```
94
+ * **If `dart analyze` reports errors:** Return to Step 3.
95
+ * **If `dart test` fails with a `TypeError`:** You have introduced an invalid explicit cast (`as T`) or accessed an uninitialized `late` variable. Locate the runtime failure and correct the type hierarchy or initialization order.
96
+
97
+ ## Examples
98
+
99
+ ### Example: Fixing Dynamic List Assignments
100
+ **Input (Fails Static Analysis):**
101
+ ```dart
102
+ void printInts(List<int> a) => print(a);
103
+
104
+ void main() {
105
+ final list = []; // Inferred as List<dynamic>
106
+ list.add(1);
107
+ list.add(2);
108
+ printInts(list); // Error: List<dynamic> can't be assigned to List<int>
109
+ }
110
+ ```
111
+
112
+ **Output (Passes Static Analysis):**
113
+ ```dart
114
+ void printInts(List<int> a) => print(a);
115
+
116
+ void main() {
117
+ final list = <int>[]; // Explicitly typed
118
+ list.add(1);
119
+ list.add(2);
120
+ printInts(list);
121
+ }
122
+ ```
123
+
124
+ ### Example: Fixing Method Overrides (Contravariance)
125
+ **Input (Fails Static Analysis):**
126
+ ```dart
127
+ class Animal {
128
+ void chase(Animal a) {}
129
+ }
130
+
131
+ class Cat extends Animal {
132
+ @override
133
+ void chase(Mouse a) {} // Error: Tightening parameter type
134
+ }
135
+ ```
136
+
137
+ **Output (Passes Static Analysis):**
138
+ ```dart
139
+ class Animal {
140
+ void chase(Animal a) {}
141
+ }
142
+
143
+ class Cat extends Animal {
144
+ @override
145
+ void chase(covariant Mouse a) {} // Explicitly marked covariant
146
+ }
147
+ ```
148
+
149
+ ### Example: Fixing Null Safety with `late`
150
+ **Input (Fails Static Analysis):**
151
+ ```dart
152
+ class Thermometer {
153
+ String temperature; // Error: Non-nullable instance field must be initialized
154
+
155
+ void read() {
156
+ temperature = '20C';
157
+ }
158
+ }
159
+ ```
160
+
161
+ **Output (Passes Static Analysis):**
162
+ ```dart
163
+ class Thermometer {
164
+ late String temperature; // Defers initialization check to runtime
165
+
166
+ void read() {
167
+ temperature = '20C';
168
+ }
169
+ }
170
+ ```