@bdayadev/flutter-ultra-mcp 1.11.7 → 1.13.0

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.
@@ -0,0 +1,177 @@
1
+ ---
2
+ name: generate-test-mocks
3
+ description: Define and generate mock objects for external dependencies using `package:mockito` and `build_runner`. Use when unit testing classes that depend on complex external services like APIs or databases.
4
+ last_modified: Fri, 24 Apr 2026 15:13:58 GMT
5
+ ---
6
+
7
+ # Testing and Mocking Dart Applications
8
+
9
+ ## Contents
10
+
11
+ - [Structuring Code for Testability](#structuring-code-for-testability)
12
+ - [Managing Dependencies](#managing-dependencies)
13
+ - [Generating Mocks](#generating-mocks)
14
+ - [Implementing Unit Tests](#implementing-unit-tests)
15
+ - [Workflow: Creating and Running Mocked Tests](#workflow-creating-and-running-mocked-tests)
16
+ - [Examples](#examples)
17
+
18
+ ## Structuring Code for Testability
19
+
20
+ Design Dart classes to support dependency injection. Isolate complex external dependencies (like API clients or databases) so they can be replaced with mock objects during testing.
21
+
22
+ - Inject external services (e.g., `http.Client`) through class constructors.
23
+ - Represent URLs strictly as `Uri` objects using `Uri.parse(string)`.
24
+ - Utilize Dart's object-oriented features (classes, mixins) to define clear interfaces for external interactions.
25
+
26
+ ## Managing Dependencies
27
+
28
+ Configure the `pubspec.yaml` file with the necessary testing and code generation packages.
29
+
30
+ - Add runtime dependencies (e.g., `package:http`) using `dart pub add http`.
31
+ - Add testing dependencies using `dart pub add dev:test dev:mockito dev:build_runner`.
32
+ - Import HTTP libraries with a prefix to avoid namespace collisions: `import 'package:http/http.dart' as http;`.
33
+
34
+ ## Generating Mocks
35
+
36
+ Use `package:mockito` and `build_runner` to automatically generate mock classes for fixed scenarios and behavior verification.
37
+
38
+ - Always use the `@GenerateNiceMocks` annotation (preferable to `@GenerateMocks` to avoid missing stub exceptions).
39
+ - Place the annotation in the test file, passing a list of `MockSpec<Type>()` objects.
40
+ - Import the generated file using the `.mocks.dart` extension.
41
+ - Execute `build_runner` to generate the mock files: `dart run build_runner build`.
42
+
43
+ ## Implementing Unit Tests
44
+
45
+ Isolate the system under test using the generated mock objects. Use `package:test` to structure the test suite.
46
+
47
+ - **Stubbing:** Configure mock behavior before interacting with the system under test.
48
+ - Use `when(mock.method()).thenReturn(value)` for synchronous methods.
49
+ - **CRITICAL:** Always use `thenAnswer((_) async => value)` for methods returning a `Future` or `Stream`. Never use `thenReturn` for asynchronous returns.
50
+ - **Verification:** Assert that the system under test interacted with the mock object correctly.
51
+ - Use `verify(mock.method()).called(1)` to check exact invocation counts.
52
+ - Use argument matchers like `any`, `anyNamed`, or `captureAny` for flexible verification.
53
+
54
+ ## Workflow: Creating and Running Mocked Tests
55
+
56
+ Use the following checklist to implement and verify mocked unit tests.
57
+
58
+ ### Task Progress
59
+
60
+ - [ ] 1. Identify the external dependency to mock (e.g., `http.Client`).
61
+ - [ ] 2. Inject the dependency into the target class constructor.
62
+ - [ ] 3. Create a test file (e.g., `target_test.dart`) and add `@GenerateNiceMocks([MockSpec<Dependency>()])`.
63
+ - [ ] 4. Add the `part` or `import` directive for the generated `.mocks.dart` file.
64
+ - [ ] 5. Run `dart run build_runner build` to generate the mock classes.
65
+ - [ ] 6. Write the test cases using `group()` and `test()`.
66
+ - [ ] 7. Stub required behaviors using `when()`.
67
+ - [ ] 8. Execute the target method.
68
+ - [ ] 9. Verify interactions using `verify()` and assert outcomes using `expect()`.
69
+ - [ ] 10. Run the test suite using `dart test`.
70
+
71
+ ### Feedback Loop: Test Failures
72
+
73
+ If tests fail or `build_runner` encounters errors:
74
+
75
+ 1. **Run validator:** Execute `dart test` or `dart run build_runner build`.
76
+ 2. **Review errors:** Check for missing stubs, mismatched argument matchers, or syntax errors in the generated files.
77
+ 3. **Fix:**
78
+ - If a mock method throws an unexpected null error, ensure you used `@GenerateNiceMocks`.
79
+ - If an async stub throws an `ArgumentError`, change `thenReturn` to `thenAnswer`.
80
+ - If `build_runner` fails, ensure the `.mocks.dart` import matches the file name exactly.
81
+ 4. Repeat until all tests pass.
82
+
83
+ ## Examples
84
+
85
+ ### High-Fidelity Mocking and Testing Example
86
+
87
+ **1. System Under Test (`lib/api_service.dart`)**
88
+
89
+ ```dart
90
+ import 'dart:convert';
91
+ import 'package:http/http.dart' as http;
92
+
93
+ class ApiService {
94
+ final http.Client client;
95
+
96
+ ApiService(this.client);
97
+
98
+ Future<String> fetchData(String urlString) async {
99
+ final uri = Uri.parse(urlString);
100
+ final response = await client.get(uri);
101
+
102
+ if (response.statusCode == 200) {
103
+ return jsonDecode(response.body)['data'];
104
+ } else {
105
+ throw Exception('Failed to load data');
106
+ }
107
+ }
108
+ }
109
+ ```
110
+
111
+ **2. Test Implementation (`test/api_service_test.dart`)**
112
+
113
+ ```dart
114
+ import 'package:test/test.dart';
115
+ import 'package:mockito/annotations.dart';
116
+ import 'package:mockito/mockito.dart';
117
+ import 'package:http/http.dart' as http;
118
+ import 'package:my_app/api_service.dart';
119
+
120
+ // Generate the mock class for http.Client
121
+ @GenerateNiceMocks([MockSpec<http.Client>()])
122
+ import 'api_service_test.mocks.dart';
123
+
124
+ void main() {
125
+ group('ApiService', () {
126
+ late ApiService apiService;
127
+ late MockClient mockHttpClient;
128
+
129
+ setUp(() {
130
+ mockHttpClient = MockClient();
131
+ apiService = ApiService(mockHttpClient);
132
+ });
133
+
134
+ test('returns data if the http call completes successfully', () async {
135
+ // Arrange: Stub the async HTTP GET request using thenAnswer
136
+ when(mockHttpClient.get(any)).thenAnswer(
137
+ (_) async => http.Response('{"data": "Success"}', 200),
138
+ );
139
+
140
+ // Act
141
+ final result = await apiService.fetchData('https://api.example.com/data');
142
+
143
+ // Assert
144
+ expect(result, 'Success');
145
+
146
+ // Verify the mock was called with the correct Uri
147
+ verify(mockHttpClient.get(Uri.parse('https://api.example.com/data'))).called(1);
148
+ });
149
+
150
+ test('throws an exception if the http call completes with an error', () {
151
+ // Arrange
152
+ when(mockHttpClient.get(any)).thenAnswer(
153
+ (_) async => http.Response('Not Found', 404),
154
+ );
155
+
156
+ // Act & Assert
157
+ expect(
158
+ apiService.fetchData('https://api.example.com/data'),
159
+ throwsException,
160
+ );
161
+ });
162
+ });
163
+ }
164
+ ```
165
+
166
+ ## Flutter Ultra Integration
167
+
168
+ Run build_runner to generate mock classes:
169
+
170
+ - `mcp__plugin_flutter_flutter-ultra-build__start_build_runner_build` — Run build_runner to generate \*.mocks.dart files
171
+ - `mcp__plugin_flutter_flutter-ultra-build__poll_build_runner_job` — Monitor generation progress
172
+ - `mcp__plugin_flutter_flutter-ultra-build__get_build_runner_result` — Check for generation errors
173
+
174
+ ---
175
+
176
+ > **Attribution:** This skill is vendored from [dart-lang/skills](https://github.com/dart-lang/skills) (BSD-3-Clause).
177
+ > Synced by `scripts/sync-upstream-skills.mjs`. Do not edit manually — changes will be overwritten on next sync.
@@ -0,0 +1,168 @@
1
+ ---
2
+ name: implement-json-serialization
3
+ description: Create model classes with `fromJson` and `toJson` methods using `dart:convert`. Use when manually mapping JSON keys to class properties for simple data structures.
4
+ last_modified: Tue, 21 Apr 2026 21:44:50 GMT
5
+ ---
6
+
7
+ # Serializing JSON Manually in Flutter
8
+
9
+ ## Contents
10
+
11
+ - [Core Guidelines](#core-guidelines)
12
+ - [Workflow: Implementing a Serializable Model](#workflow-implementing-a-serializable-model)
13
+ - [Workflow: Fetching and Parsing JSON](#workflow-fetching-and-parsing-json)
14
+ - [Examples](#examples)
15
+
16
+ ## Core Guidelines
17
+
18
+ - **Import `dart:convert`**: Utilize Flutter's built-in `dart:convert` library for manual JSON encoding (`jsonEncode`) and decoding (`jsonDecode`).
19
+ - **Enforce Type Safety**: Always cast the `dynamic` result of `jsonDecode()` to the expected type, typically `Map<String, dynamic>` for objects or `List<dynamic>` for arrays.
20
+ - **Encapsulate Serialization Logic**: Define plain model classes containing properties corresponding to the JSON structure. Implement a `fromJson` factory constructor and a `toJson` method within the model.
21
+ - **Handle Background Parsing**: If parsing large JSON documents (execution time > 16ms), offload the parsing logic to a separate isolate using Flutter's `compute()` function to prevent UI jank.
22
+ - **Throw Exceptions on Failure**: When handling HTTP responses, throw an exception if the status code is not successful (e.g., not 200 OK or 201 Created). Do not return `null`.
23
+
24
+ ## Workflow: Implementing a Serializable Model
25
+
26
+ Use this checklist to implement manual JSON serialization for a data model.
27
+
28
+ **Task Progress:**
29
+
30
+ - [ ] Define the plain model class with `final` properties.
31
+ - [ ] Implement the `factory Model.fromJson(Map<String, dynamic> json)` constructor.
32
+ - [ ] Implement the `Map<String, dynamic> toJson()` method.
33
+ - [ ] Write unit tests for both serialization methods.
34
+ - [ ] Run validator -> review type mismatch errors -> fix casting logic.
35
+
36
+ 1. **Define the Model**: Create a class with properties matching the JSON keys.
37
+ 2. **Implement `fromJson`**: Extract values from the `Map` and cast them to the appropriate Dart types. Use pattern matching or explicit casting.
38
+ 3. **Implement `toJson`**: Return a `Map<String, dynamic>` mapping the class properties back to their JSON string keys.
39
+ 4. **Validate**: Execute unit tests to ensure type safety, autocompletion, and compile-time exception handling function correctly.
40
+
41
+ ## Workflow: Fetching and Parsing JSON
42
+
43
+ Use this conditional workflow when retrieving and parsing JSON from a network request.
44
+
45
+ **Task Progress:**
46
+
47
+ - [ ] Execute the HTTP request.
48
+ - [ ] Validate the response status code.
49
+ - [ ] Determine parsing strategy (Synchronous vs. Isolate).
50
+ - [ ] Decode and map the JSON to the model.
51
+
52
+ 1. **Execute Request**: Use the `http` package to perform the network call.
53
+ 2. **Validate Response**:
54
+ - If `response.statusCode == 200` (or 201 for POST), proceed to parsing.
55
+ - If the status code indicates failure, throw an `Exception`.
56
+ 3. **Determine Parsing Strategy**:
57
+ - If parsing a **small payload** (e.g., a single object), parse synchronously on the main thread.
58
+ - If parsing a **large payload** (e.g., an array of thousands of objects), use `compute(parseFunction, response.body)` to parse in a background isolate.
59
+ 4. **Decode and Map**: Pass the decoded JSON to your model's `fromJson` constructor.
60
+
61
+ ## Examples
62
+
63
+ ### High-Fidelity Model Implementation
64
+
65
+ ```dart
66
+ import 'dart:convert';
67
+
68
+ class User {
69
+ final int id;
70
+ final String name;
71
+ final String email;
72
+
73
+ const User({
74
+ required this.id,
75
+ required this.name,
76
+ required this.email,
77
+ });
78
+
79
+ // Factory constructor for deserialization
80
+ factory User.fromJson(Map<String, dynamic> json) {
81
+ return switch (json) {
82
+ {
83
+ 'id': int id,
84
+ 'name': String name,
85
+ 'email': String email,
86
+ } =>
87
+ User(
88
+ id: id,
89
+ name: name,
90
+ email: email,
91
+ ),
92
+ _ => throw const FormatException('Failed to load User.'),
93
+ };
94
+ }
95
+
96
+ // Method for serialization
97
+ Map<String, dynamic> toJson() {
98
+ return {
99
+ 'id': id,
100
+ 'name': name,
101
+ 'email': email,
102
+ };
103
+ }
104
+ }
105
+ ```
106
+
107
+ ### Synchronous Parsing (Small Payload)
108
+
109
+ ```dart
110
+ import 'dart:convert';
111
+ import 'package:http/http.dart' as http;
112
+
113
+ Future<User> fetchUser(http.Client client, int userId) async {
114
+ final response = await client.get(
115
+ Uri.parse('https://api.example.com/users/$userId'),
116
+ headers: {'Accept': 'application/json'},
117
+ );
118
+
119
+ if (response.statusCode == 200) {
120
+ // Decode returns dynamic, cast to Map<String, dynamic>
121
+ final Map<String, dynamic> jsonMap = jsonDecode(response.body) as Map<String, dynamic>;
122
+ return User.fromJson(jsonMap);
123
+ } else {
124
+ throw Exception('Failed to load user');
125
+ }
126
+ }
127
+ ```
128
+
129
+ ### Background Parsing (Large Payload)
130
+
131
+ ```dart
132
+ import 'dart:convert';
133
+ import 'package:flutter/foundation.dart';
134
+ import 'package:http/http.dart' as http;
135
+
136
+ // Top-level function required for compute()
137
+ List<User> parseUsers(String responseBody) {
138
+ final parsed = (jsonDecode(responseBody) as List<dynamic>).cast<Map<String, dynamic>>();
139
+ return parsed.map<User>((json) => User.fromJson(json)).toList();
140
+ }
141
+
142
+ Future<List<User>> fetchUsers(http.Client client) async {
143
+ final response = await client.get(
144
+ Uri.parse('https://api.example.com/users'),
145
+ headers: {'Accept': 'application/json'},
146
+ );
147
+
148
+ if (response.statusCode == 200) {
149
+ // Offload expensive parsing to a background isolate
150
+ return compute(parseUsers, response.body);
151
+ } else {
152
+ throw Exception('Failed to load users');
153
+ }
154
+ }
155
+ ```
156
+
157
+ ## Flutter Ultra Integration
158
+
159
+ If using code generation (json_serializable), run the build runner:
160
+
161
+ - `mcp__plugin_flutter_flutter-ultra-build__start_build_runner_build` — Run build_runner to generate serialization code
162
+ - `mcp__plugin_flutter_flutter-ultra-build__poll_build_runner_job` — Monitor code generation progress
163
+ - `mcp__plugin_flutter_flutter-ultra-build__analyze` — Verify generated code has no analysis errors
164
+
165
+ ---
166
+
167
+ > **Attribution:** This skill is vendored from [flutter/skills](https://github.com/flutter/skills) (BSD-3-Clause).
168
+ > Synced by `scripts/sync-upstream-skills.mjs`. Do not edit manually — changes will be overwritten on next sync.
@@ -0,0 +1,156 @@
1
+ ---
2
+ name: migrate-to-checks-package
3
+ description: Replace the usage of `expect` and similar functions from `package:matcher` to `package:checks` equivalents.
4
+ last_modified: Fri, 24 Apr 2026 15:15:22 GMT
5
+ ---
6
+
7
+ # Migrating Dart Tests to Package Checks
8
+
9
+ ## Contents
10
+
11
+ - [Dependency Management](#dependency-management)
12
+ - [Syntax Migration Guidelines](#syntax-migration-guidelines)
13
+ - [Utilizing Dart MCP Tools](#utilizing-dart-mcp-tools)
14
+ - [Migration Workflow](#migration-workflow)
15
+ - [Examples](#examples)
16
+
17
+ ## Dependency Management
18
+
19
+ Manage dependencies using the Dart Tooling MCP Server `pub` tool or standard CLI commands.
20
+
21
+ - Add `package:checks` as a `dev_dependency` using `dart pub add dev:checks`.
22
+ - Remove `package:matcher` if it is explicitly listed in the `pubspec.yaml` (note: it is often transitively included by `package:test`, which is fine).
23
+ - Import `package:checks/checks.dart` in all test files undergoing migration.
24
+
25
+ ## Syntax Migration Guidelines
26
+
27
+ Transition test assertions from the `package:matcher` syntax to the literate API provided by `package:checks`.
28
+
29
+ - **Basic Equality:** Replace `expect(actual, equals(expected))` or `expect(actual, expected)` with `check(actual).equals(expected)`.
30
+ - **Type Checking:** Replace `expect(actual, isA<Type>())` with `check(actual).isA<Type>()`.
31
+ - **Property Extraction:** Replace `expect(actual.property, expected)` with `check(actual).has((a) => a.property, 'property name').equals(expected)`.
32
+ - **Cascades for Multiple Checks:** Use Dart's cascade operator (`..`) to chain multiple expectations on a single subject.
33
+ - **Asynchronous Expectations:**
34
+ - If checking a `Future`, `await` the `check` call: `await check(someFuture).completes((r) => r.equals(expected));`.
35
+ - If checking a `Stream`, wrap it in a `StreamQueue` for multiple checks, or use `.withQueue` for single/broadcast checks.
36
+
37
+ ## Utilizing Dart MCP Tools
38
+
39
+ Leverage the Dart MCP Server tools to automate and validate the migration process.
40
+
41
+ - Use `pub` to run `dart pub get` or `dart pub add`.
42
+ - Use `analyze_files` to run static analysis on the project or specific paths.
43
+ - Use `run_tests` to execute Dart or Flutter tests with an agent-centric UX. ALWAYS use this instead of shell commands like `dart test`.
44
+ - Use `dart_fix` to apply automated fixes if applicable.
45
+
46
+ ## Migration Workflow
47
+
48
+ Copy and use the following checklist to track progress when migrating a test suite:
49
+
50
+ - [ ] **Task Progress**
51
+ - [ ] Add `package:checks` as a dev dependency.
52
+ - [ ] Identify all test files using `package:matcher` (`expect` calls).
53
+ - [ ] Import `package:checks/checks.dart` in target test files.
54
+ - [ ] Rewrite all `expect(...)` statements to `check(...)` statements.
55
+ - [ ] Run static analyzer (`analyze_files`).
56
+ - [ ] Run tests (`run_tests`).
57
+
58
+ ### Feedback Loop: Static Analysis
59
+
60
+ 1. Run the `analyze_files` tool on the modified test directories.
61
+ 2. Review any static analysis warnings or errors (e.g., missing imports, incorrect generic types on `isA`, unawaited futures).
62
+ 3. Fix the warnings.
63
+ 4. Repeat until the analyzer returns zero issues.
64
+
65
+ ### Feedback Loop: Test Validation
66
+
67
+ 1. Run the `run_tests` tool.
68
+ 2. If tests fail, review the failure output. `package:checks` provides detailed context (e.g., `Which: has length of <2>`).
69
+ 3. Adjust the `check()` expectations or the underlying code to resolve the failure.
70
+ 4. Repeat until all tests pass.
71
+
72
+ ## Examples
73
+
74
+ ### Basic Assertions
75
+
76
+ **Input (`matcher`):**
77
+
78
+ ```dart
79
+ expect(someList.length, 1);
80
+ expect(someString, startsWith('a'));
81
+ expect(someObject, isA<Map>());
82
+ ```
83
+
84
+ **Output (`checks`):**
85
+
86
+ ```dart
87
+ check(someList).length.equals(1);
88
+ check(someString).startsWith('a');
89
+ check(someObject).isA<Map>();
90
+ ```
91
+
92
+ ### Composed Expectations
93
+
94
+ **Input (`matcher`):**
95
+
96
+ ```dart
97
+ expect('foo,bar,baz', allOf([
98
+ contains('foo'),
99
+ isNot(startsWith('bar')),
100
+ endsWith('baz')
101
+ ]));
102
+ ```
103
+
104
+ **Output (`checks`):**
105
+
106
+ ```dart
107
+ check('foo,bar,baz')
108
+ ..contains('foo')
109
+ ..not((s) => s.startsWith('bar'))
110
+ ..endsWith('baz');
111
+ ```
112
+
113
+ ### Asynchronous Futures
114
+
115
+ **Input (`matcher`):**
116
+
117
+ ```dart
118
+ expect(Future.value(10), completion(equals(10)));
119
+ expect(Future.error('oh no'), throwsA(equals('oh no')));
120
+ ```
121
+
122
+ **Output (`checks`):**
123
+
124
+ ```dart
125
+ await check(Future.value(10)).completes((it) => it.equals(10));
126
+ await check(Future.error('oh no')).throws<String>().equals('oh no');
127
+ ```
128
+
129
+ ### Asynchronous Streams
130
+
131
+ **Input (`matcher`):**
132
+
133
+ ```dart
134
+ var stdout = StreamQueue(Stream.fromIterable(['Ready', 'Go']));
135
+ await expectLater(stdout, emitsThrough('Ready'));
136
+ ```
137
+
138
+ **Output (`checks`):**
139
+
140
+ ```dart
141
+ var stdout = StreamQueue(Stream.fromIterable(['Ready', 'Go']));
142
+ await check(stdout).emitsThrough((it) => it.equals('Ready'));
143
+ ```
144
+
145
+ ## Flutter Ultra Integration
146
+
147
+ Validate the migration with static analysis and tests:
148
+
149
+ - `mcp__plugin_flutter_flutter-ultra-build__analyze` — Check for type errors after migration
150
+ - `mcp__plugin_flutter_flutter-ultra-build__fix` — Apply automated fixes for simple migrations
151
+ - `mcp__plugin_flutter_flutter-ultra-build__start_run_unit_tests` — Run tests to verify migration didn't break assertions
152
+
153
+ ---
154
+
155
+ > **Attribution:** This skill is vendored from [dart-lang/skills](https://github.com/dart-lang/skills) (BSD-3-Clause).
156
+ > Synced by `scripts/sync-upstream-skills.mjs`. Do not edit manually — changes will be overwritten on next sync.
@@ -0,0 +1,140 @@
1
+ ---
2
+ name: resolve-package-conflicts
3
+ description: Workflow for fixing package version conflicts. Use this when `pub get` fails due to incompatible package versions.
4
+ last_modified: Fri, 24 Apr 2026 15:11:14 GMT
5
+ ---
6
+
7
+ # Managing Dart Dependencies
8
+
9
+ ## Contents
10
+
11
+ - [Core Concepts](#core-concepts)
12
+ - [Version Constraints](#version-constraints)
13
+ - [Workflow: Auditing Dependencies](#workflow-auditing-dependencies)
14
+ - [Workflow: Upgrading Dependencies](#workflow-upgrading-dependencies)
15
+ - [Workflow: Resolving Version Conflicts](#workflow-resolving-version-conflicts)
16
+ - [Examples](#examples)
17
+
18
+ ## Core Concepts
19
+
20
+ Dart enforces a strict single-version rule for dependencies: a project and all its transitive dependencies must resolve to a single, shared version of any given package. This prevents runtime type mismatches but introduces the risk of "version lock."
21
+
22
+ To mitigate version lock, Dart relies on version constraints rather than pinned versions in the `pubspec.yaml`. The `pubspec.lock` file maintains the exact resolved versions for reproducible builds.
23
+
24
+ Understand the output columns of `dart pub outdated`:
25
+
26
+ - **Current:** The version currently recorded in `pubspec.lock`.
27
+ - **Upgradable:** The latest version allowed by the constraints in `pubspec.yaml`. `dart pub upgrade` resolves to this.
28
+ - **Resolvable:** The absolute latest version that can be resolved when factoring in all other dependencies in the project.
29
+ - **Latest:** The latest published version of the package (excluding prereleases).
30
+
31
+ ## Version Constraints
32
+
33
+ - **Use Caret Syntax:** Always use caret syntax (e.g., `^1.2.3`) for dependencies in `pubspec.yaml`. This allows `pub` to select newer, non-breaking versions (up to, but not including, the next major version) during resolution.
34
+ - **Tighten Dev Dependencies:** Set the lower bound of `dev_dependencies` to the exact version currently used. This reduces resolution complexity and prevents older, incompatible dev tools from being selected.
35
+ - **Enforce Lockfiles in CI:** Use `dart pub get --enforce-lockfile` in CI/CD pipelines to ensure the exact versions tested locally are used in production.
36
+
37
+ ## Workflow: Auditing Dependencies
38
+
39
+ Run this workflow periodically to identify stale packages that may impact stability or performance.
40
+
41
+ **Task Progress:**
42
+
43
+ - [ ] Run `dart pub outdated`.
44
+ - [ ] Review the **Upgradable** column to identify packages that can be updated without modifying `pubspec.yaml`.
45
+ - [ ] Review the **Resolvable** column to identify packages that require constraint modifications in `pubspec.yaml` to update.
46
+ - [ ] Identify any packages marked as retracted or discontinued.
47
+
48
+ ## Workflow: Upgrading Dependencies
49
+
50
+ Use conditional logic based on the audit results to upgrade dependencies.
51
+
52
+ **Task Progress:**
53
+
54
+ - [ ] **If updating to "Upgradable" versions:**
55
+ - [ ] Run `dart pub upgrade`.
56
+ - [ ] Run `dart pub upgrade --tighten` to automatically update the lower bounds in `pubspec.yaml` to match the newly resolved versions.
57
+ - [ ] **If updating to "Resolvable" versions (Major updates):**
58
+ - [ ] Manually edit `pubspec.yaml` to bump the version constraint to match the "Resolvable" column (e.g., change `^0.11.0` to `^0.12.1`).
59
+ - [ ] Run `dart pub upgrade` to resolve the new constraints and update `pubspec.lock`.
60
+ - [ ] **Feedback Loop:**
61
+ - [ ] Run `dart analyze` -> review errors -> fix breaking API changes.
62
+ - [ ] Run `dart test` -> review failures -> fix regressions.
63
+
64
+ ## Workflow: Resolving Version Conflicts
65
+
66
+ When `pub` cannot find a set of concrete versions that satisfy all constraints, or when dealing with a retracted package version, manipulate the lockfile surgically.
67
+
68
+ **NEVER** delete the entire `pubspec.lock` file and run `dart pub get`. This causes uncontrolled upgrades across the entire dependency graph.
69
+
70
+ **Task Progress:**
71
+
72
+ - [ ] Open `pubspec.lock`.
73
+ - [ ] Locate the specific YAML block for the conflicting or retracted package.
74
+ - [ ] Delete ONLY that package's entry from the lockfile.
75
+ - [ ] Run `dart pub get` to fetch the newest compatible, non-retracted version for that specific package.
76
+ - [ ] **Feedback Loop:**
77
+ - [ ] Run `dart pub deps` -> verify the dependency graph resolves correctly.
78
+ - [ ] If resolution fails, identify the transitive dependency causing the lock, update its constraint in `pubspec.yaml`, and retry.
79
+
80
+ ## Examples
81
+
82
+ ### Tightening Constraints
83
+
84
+ When `dart pub outdated` shows a package is resolvable to a higher minor/patch version, use the `--tighten` flag to update the `pubspec.yaml` automatically.
85
+
86
+ **Input (`pubspec.yaml`):**
87
+
88
+ ```yaml
89
+ dependencies:
90
+ http: ^0.13.0
91
+ ```
92
+
93
+ **Command:**
94
+
95
+ ```bash
96
+ dart pub upgrade --tighten http
97
+ ```
98
+
99
+ **Output (`pubspec.yaml`):**
100
+
101
+ ```yaml
102
+ dependencies:
103
+ http: ^0.13.5
104
+ ```
105
+
106
+ ### Surgical Lockfile Removal
107
+
108
+ If `package_a` is retracted or locked in a conflict, remove only its block from `pubspec.lock`.
109
+
110
+ **Before (`pubspec.lock`):**
111
+
112
+ ```yaml
113
+ packages:
114
+ package_a:
115
+ dependency: 'direct main'
116
+ description:
117
+ name: package_a
118
+ url: 'https://pub.dev'
119
+ source: hosted
120
+ version: '1.0.0' # Retracted version
121
+ package_b:
122
+ dependency: 'direct main'
123
+ # ...
124
+ ```
125
+
126
+ **Action:** Delete the `package_a` block entirely. Leave `package_b` untouched. Run `dart pub get`.
127
+
128
+ ## Flutter Ultra Integration
129
+
130
+ Investigate and resolve dependency conflicts:
131
+
132
+ - `mcp__plugin_flutter_flutter-ultra-build__pub_get` — Run pub get to see the current resolution state
133
+ - `mcp__plugin_flutter_flutter-ultra-build__pub_deps` — View the full dependency tree
134
+ - `mcp__plugin_flutter_flutter-ultra-build__pub_outdated` — Check which packages are outdated
135
+ - `mcp__plugin_flutter_flutter-ultra-build__pub_upgrade` — Attempt upgrade to resolve conflicts
136
+
137
+ ---
138
+
139
+ > **Attribution:** This skill is vendored from [dart-lang/skills](https://github.com/dart-lang/skills) (BSD-3-Clause).
140
+ > Synced by `scripts/sync-upstream-skills.mjs`. Do not edit manually — changes will be overwritten on next sync.