@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.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/dart/ultra_flutter/pubspec.yaml +1 -1
- package/dart/ultra_flutter_devtools/pubspec.yaml +1 -1
- package/package.json +1 -1
- package/skills/UPSTREAM-LICENSES +75 -0
- package/skills/add-integration-test/SKILL.md +179 -0
- package/skills/add-unit-test/SKILL.md +141 -0
- package/skills/add-widget-preview/SKILL.md +166 -0
- package/skills/add-widget-test/SKILL.md +171 -0
- package/skills/apply-architecture-best-practices/SKILL.md +182 -0
- package/skills/build-cli-app/SKILL.md +200 -0
- package/skills/build-responsive-layout/SKILL.md +160 -0
- package/skills/collect-coverage/SKILL.md +168 -0
- package/skills/fix-layout-issues/SKILL.md +152 -0
- package/skills/fix-runtime-errors/SKILL.md +197 -0
- package/skills/generate-test-mocks/SKILL.md +177 -0
- package/skills/implement-json-serialization/SKILL.md +168 -0
- package/skills/migrate-to-checks-package/SKILL.md +156 -0
- package/skills/resolve-package-conflicts/SKILL.md +140 -0
- package/skills/run-static-analysis/SKILL.md +120 -0
- package/skills/setup-declarative-routing/SKILL.md +293 -0
- package/skills/setup-localization/SKILL.md +247 -0
- package/skills/use-http-package/SKILL.md +189 -0
- package/skills/use-pattern-matching/SKILL.md +169 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: build-responsive-layout
|
|
3
|
+
description: Use `LayoutBuilder`, `MediaQuery`, or `Expanded/Flexible` to create a layout that adapts to different screen sizes. Use when you need the UI to look good on both mobile and tablet/desktop form factors.
|
|
4
|
+
last_modified: Tue, 21 Apr 2026 20:17:40 GMT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Implementing Adaptive Layouts
|
|
8
|
+
|
|
9
|
+
## Contents
|
|
10
|
+
|
|
11
|
+
- [Space Measurement Guidelines](#space-measurement-guidelines)
|
|
12
|
+
- [Widget Sizing and Constraints](#widget-sizing-and-constraints)
|
|
13
|
+
- [Device and Orientation Behaviors](#device-and-orientation-behaviors)
|
|
14
|
+
- [Workflow: Constructing an Adaptive Layout](#workflow-constructing-an-adaptive-layout)
|
|
15
|
+
- [Workflow: Optimizing for Large Screens](#workflow-optimizing-for-large-screens)
|
|
16
|
+
- [Examples](#examples)
|
|
17
|
+
|
|
18
|
+
## Space Measurement Guidelines
|
|
19
|
+
|
|
20
|
+
Determine the available space accurately to ensure layouts adapt to the app window, not just the physical device.
|
|
21
|
+
|
|
22
|
+
- **Use `MediaQuery.sizeOf(context)`** to get the size of the entire app window.
|
|
23
|
+
- **Use `LayoutBuilder`** to make layout decisions based on the parent widget's allocated space. Evaluate `constraints.maxWidth` to determine the appropriate widget tree to return.
|
|
24
|
+
- **Do not use `MediaQuery.orientationOf` or `OrientationBuilder`** near the top of the widget tree to switch layouts. Device orientation does not accurately reflect the available app window space.
|
|
25
|
+
- **Do not check for hardware types** (e.g., "phone" vs. "tablet"). Flutter apps run in resizable windows, multi-window modes, and picture-in-picture. Base all layout decisions strictly on available window space.
|
|
26
|
+
|
|
27
|
+
## Widget Sizing and Constraints
|
|
28
|
+
|
|
29
|
+
Understand and apply Flutter's core layout rule: **Constraints go down. Sizes go up. Parent sets position.**
|
|
30
|
+
|
|
31
|
+
- **Distribute Space:** Use `Expanded` and `Flexible` within `Row`, `Column`, or `Flex` widgets.
|
|
32
|
+
- Use `Expanded` to force a child to fill all remaining available space (equivalent to `Flexible` with `fit: FlexFit.tight` and a `flex` factor of 1.0).
|
|
33
|
+
- Use `Flexible` to allow a child to size itself up to a specific limit while still expanding/contracting. Use the `flex` factor to define the ratio of space consumption among siblings.
|
|
34
|
+
- **Constrain Width:** Prevent widgets from consuming all horizontal space on large screens. Wrap widgets like `GridView` or `ListView` in a `ConstrainedBox` or `Container` and define a `maxWidth` in the `BoxConstraints`.
|
|
35
|
+
- **Lazy Rendering:** Always use `ListView.builder` or `GridView.builder` when rendering lists with an unknown or large number of items.
|
|
36
|
+
|
|
37
|
+
## Device and Orientation Behaviors
|
|
38
|
+
|
|
39
|
+
Ensure the app behaves correctly across all device form factors and input methods.
|
|
40
|
+
|
|
41
|
+
- **Do not lock screen orientation.** Locking orientation causes severe layout issues on foldable devices, often resulting in letterboxing (the app centered with black borders). Android large format tiers require both portrait and landscape support.
|
|
42
|
+
- **Fallback for Locked Orientation:** If business requirements strictly mandate a locked orientation, use the `Display API` to retrieve physical screen dimensions instead of `MediaQuery`. `MediaQuery` fails to receive the larger window size in compatibility modes.
|
|
43
|
+
- **Support Multiple Inputs:** Implement support for basic mice, trackpads, and keyboard shortcuts. Ensure touch targets are appropriately sized and keyboard navigation is accessible.
|
|
44
|
+
|
|
45
|
+
## Workflow: Constructing an Adaptive Layout
|
|
46
|
+
|
|
47
|
+
Follow this workflow to implement a layout that adapts to the available `BoxConstraints`.
|
|
48
|
+
|
|
49
|
+
**Task Progress:**
|
|
50
|
+
|
|
51
|
+
- [ ] Identify the target widget that requires adaptive behavior.
|
|
52
|
+
- [ ] Wrap the widget tree in a `LayoutBuilder`.
|
|
53
|
+
- [ ] Extract the `constraints.maxWidth` from the builder callback.
|
|
54
|
+
- [ ] Define an adaptive breakpoint (e.g., `largeScreenMinWidth = 600`).
|
|
55
|
+
- [ ] **If `maxWidth > largeScreenMinWidth`:** Return a large-screen layout (e.g., a `Row` placing a navigation sidebar and content area side-by-side).
|
|
56
|
+
- [ ] **If `maxWidth <= largeScreenMinWidth`:** Return a small-screen layout (e.g., a `Column` or standard navigation-style approach).
|
|
57
|
+
- [ ] Run validator -> resize the application window -> review layout transitions -> fix overflow errors.
|
|
58
|
+
|
|
59
|
+
## Workflow: Optimizing for Large Screens
|
|
60
|
+
|
|
61
|
+
Follow this workflow to prevent UI elements from stretching unnaturally on large displays.
|
|
62
|
+
|
|
63
|
+
**Task Progress:**
|
|
64
|
+
|
|
65
|
+
- [ ] Identify full-width components (e.g., `ListView`, text blocks, forms).
|
|
66
|
+
- [ ] **If optimizing a list:** Convert `ListView.builder` to `GridView.builder` using `SliverGridDelegateWithMaxCrossAxisExtent` to automatically adjust column counts based on window size.
|
|
67
|
+
- [ ] **If optimizing a form or text block:** Wrap the component in a `ConstrainedBox`.
|
|
68
|
+
- [ ] Apply `BoxConstraints(maxWidth: [optimal_width])` to the `ConstrainedBox`.
|
|
69
|
+
- [ ] Wrap the `ConstrainedBox` in a `Center` widget to keep the constrained content centered on large screens.
|
|
70
|
+
- [ ] Run validator -> test on desktop/tablet target -> review horizontal stretching -> adjust `maxWidth` or grid extents.
|
|
71
|
+
|
|
72
|
+
## Examples
|
|
73
|
+
|
|
74
|
+
### Adaptive Layout using LayoutBuilder
|
|
75
|
+
|
|
76
|
+
Demonstrates switching between a mobile and desktop layout based on available width.
|
|
77
|
+
|
|
78
|
+
```dart
|
|
79
|
+
import 'package:flutter/material.dart';
|
|
80
|
+
|
|
81
|
+
const double largeScreenMinWidth = 600.0;
|
|
82
|
+
|
|
83
|
+
class AdaptiveLayout extends StatelessWidget {
|
|
84
|
+
const AdaptiveLayout({super.key});
|
|
85
|
+
|
|
86
|
+
@override
|
|
87
|
+
Widget build(BuildContext context) {
|
|
88
|
+
return LayoutBuilder(
|
|
89
|
+
builder: (context, constraints) {
|
|
90
|
+
if (constraints.maxWidth > largeScreenMinWidth) {
|
|
91
|
+
return _buildLargeScreenLayout();
|
|
92
|
+
} else {
|
|
93
|
+
return _buildSmallScreenLayout();
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
Widget _buildLargeScreenLayout() {
|
|
100
|
+
return Row(
|
|
101
|
+
children: [
|
|
102
|
+
const SizedBox(width: 250, child: Placeholder(color: Colors.blue)),
|
|
103
|
+
const VerticalDivider(width: 1),
|
|
104
|
+
Expanded(child: const Placeholder(color: Colors.green)),
|
|
105
|
+
],
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
Widget _buildSmallScreenLayout() {
|
|
110
|
+
return const Placeholder(color: Colors.green);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Constraining Width on Large Screens
|
|
116
|
+
|
|
117
|
+
Demonstrates preventing a widget from consuming all horizontal space.
|
|
118
|
+
|
|
119
|
+
```dart
|
|
120
|
+
import 'package:flutter/material.dart';
|
|
121
|
+
|
|
122
|
+
class ConstrainedContent extends StatelessWidget {
|
|
123
|
+
const ConstrainedContent({super.key});
|
|
124
|
+
|
|
125
|
+
@override
|
|
126
|
+
Widget build(BuildContext context) {
|
|
127
|
+
return Scaffold(
|
|
128
|
+
body: Center(
|
|
129
|
+
child: ConstrainedBox(
|
|
130
|
+
constraints: const BoxConstraints(
|
|
131
|
+
maxWidth: 800.0, // Maximum width for readability
|
|
132
|
+
),
|
|
133
|
+
child: ListView.builder(
|
|
134
|
+
itemCount: 50,
|
|
135
|
+
itemBuilder: (context, index) {
|
|
136
|
+
return ListTile(
|
|
137
|
+
title: Text('Item $index'),
|
|
138
|
+
);
|
|
139
|
+
},
|
|
140
|
+
),
|
|
141
|
+
),
|
|
142
|
+
),
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Flutter Ultra Integration
|
|
149
|
+
|
|
150
|
+
After building the layout, verify responsiveness across breakpoints:
|
|
151
|
+
|
|
152
|
+
- `mcp__plugin_flutter_flutter-ultra-runtime__audit_responsive` — Automated responsive audit at multiple viewport sizes
|
|
153
|
+
- `mcp__plugin_flutter_flutter-ultra-runtime__screenshot` — Capture screenshots at each breakpoint
|
|
154
|
+
- `mcp__plugin_flutter_flutter-ultra-runtime__dump_render_tree` — Inspect render tree for constraint issues
|
|
155
|
+
- `mcp__plugin_flutter_flutter-ultra-runtime__get_runtime_errors` — Check for overflow errors at different sizes
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
> **Attribution:** This skill is vendored from [flutter/skills](https://github.com/flutter/skills) (BSD-3-Clause).
|
|
160
|
+
> 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: collect-coverage
|
|
3
|
+
description: Collect coverage using the coverage packge and create an LCOV report
|
|
4
|
+
last_modified: Fri, 24 Apr 2026 15:14:32 GMT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Implementing Dart and Flutter Test Coverage
|
|
8
|
+
|
|
9
|
+
## Contents
|
|
10
|
+
|
|
11
|
+
- [Testing Fundamentals](#testing-fundamentals)
|
|
12
|
+
- [Coverage Directives](#coverage-directives)
|
|
13
|
+
- [Workflow: Configuring and Generating Coverage Reports](#workflow-configuring-and-generating-coverage-reports)
|
|
14
|
+
- [Workflow: Advanced Manual Coverage Collection](#workflow-advanced-manual-coverage-collection)
|
|
15
|
+
- [Examples](#examples)
|
|
16
|
+
|
|
17
|
+
## Testing Fundamentals
|
|
18
|
+
|
|
19
|
+
Structure your test suites using the standard Dart testing paradigms. Use `package:test` for Dart projects and `flutter_test` for Flutter projects.
|
|
20
|
+
|
|
21
|
+
- **Unit Tests:** Verify individual functions, methods, or classes.
|
|
22
|
+
- **Component/Widget Tests:** Verify component behavior, layout, and interaction using mock objects (`package:mockito`).
|
|
23
|
+
- **Integration Tests:** Verify entire app flows on simulated or real devices.
|
|
24
|
+
|
|
25
|
+
## Coverage Directives
|
|
26
|
+
|
|
27
|
+
Exclude specific lines, blocks, or entire files from coverage metrics using inline comments. Pass the `--check-ignore` flag during formatting to enforce these directives.
|
|
28
|
+
|
|
29
|
+
- Ignore a single line: `// coverage:ignore-line`
|
|
30
|
+
- Ignore a block of code: `// coverage:ignore-start` and `// coverage:ignore-end`
|
|
31
|
+
- Ignore an entire file: `// coverage:ignore-file`
|
|
32
|
+
|
|
33
|
+
## Workflow: Configuring and Generating Coverage Reports
|
|
34
|
+
|
|
35
|
+
Follow this sequential workflow to add the coverage package, execute tests, and generate an LCOV report.
|
|
36
|
+
|
|
37
|
+
**Task Progress Checklist:**
|
|
38
|
+
|
|
39
|
+
- [ ] 1. Add `coverage` as a `dev_dependency`.
|
|
40
|
+
- [ ] 2. Execute the automated coverage script.
|
|
41
|
+
- [ ] 3. Validate the LCOV output.
|
|
42
|
+
|
|
43
|
+
### 1. Add Dependencies
|
|
44
|
+
|
|
45
|
+
Add the `coverage` package as a `dev_dependency` to your project. Do not add it to standard dependencies.
|
|
46
|
+
|
|
47
|
+
If working in a standard Dart project:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
dart pub add dev:coverage
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
If working in a Flutter project:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
flutter pub add dev:coverage
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 2. Collect Coverage and Generate LCOV
|
|
60
|
+
|
|
61
|
+
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.
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
dart run coverage:test_with_coverage
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
_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`)._
|
|
68
|
+
|
|
69
|
+
### 3. Feedback Loop: Validate Output
|
|
70
|
+
|
|
71
|
+
**Run validator -> review errors -> fix:**
|
|
72
|
+
|
|
73
|
+
1. Verify that the `coverage/` directory was created in the project root.
|
|
74
|
+
2. Ensure `coverage/coverage.json` (raw data) and `coverage/lcov.info` (formatted report) exist.
|
|
75
|
+
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.
|
|
76
|
+
|
|
77
|
+
## Workflow: Advanced Manual Coverage Collection
|
|
78
|
+
|
|
79
|
+
If you require granular control over the VM service, isolate pausing, or need branch/function-level coverage, use the manual collection workflow.
|
|
80
|
+
|
|
81
|
+
**Task Progress Checklist:**
|
|
82
|
+
|
|
83
|
+
- [ ] 1. Run tests with VM service enabled.
|
|
84
|
+
- [ ] 2. Collect raw JSON coverage.
|
|
85
|
+
- [ ] 3. Format JSON to LCOV.
|
|
86
|
+
|
|
87
|
+
### 1. Run Tests with VM Service
|
|
88
|
+
|
|
89
|
+
Execute tests while pausing isolates on exit and exposing the VM service on a specific port (e.g., 8181).
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
dart run --pause-isolates-on-exit --disable-service-auth-codes --enable-vm-service=8181 test &
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### 2. Collect Raw Coverage
|
|
96
|
+
|
|
97
|
+
Extract the coverage data from the running VM service and output it to a JSON file.
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
dart run coverage:collect_coverage --wait-paused --uri=http://127.0.0.1:8181/ -o coverage/coverage.json --resume-isolates
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
_Optional: Append `--function-coverage` and `--branch-coverage` to gather deeper metrics (requires Dart VM 2.17.0+)._
|
|
104
|
+
|
|
105
|
+
### 3. Format to LCOV
|
|
106
|
+
|
|
107
|
+
Convert the raw JSON data into the standard LCOV format.
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
dart run coverage:format_coverage --packages=.dart_tool/package_config.json --lcov -i coverage/coverage.json -o coverage/lcov.info --check-ignore
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Examples
|
|
114
|
+
|
|
115
|
+
### Example: `pubspec.yaml` Configuration
|
|
116
|
+
|
|
117
|
+
Ensure your `pubspec.yaml` reflects the `coverage` package strictly under `dev_dependencies`.
|
|
118
|
+
|
|
119
|
+
```yaml
|
|
120
|
+
name: my_dart_app
|
|
121
|
+
environment:
|
|
122
|
+
sdk: ^3.0.0
|
|
123
|
+
|
|
124
|
+
dependencies:
|
|
125
|
+
path: ^1.8.0
|
|
126
|
+
|
|
127
|
+
dev_dependencies:
|
|
128
|
+
test: ^1.24.0
|
|
129
|
+
coverage: ^1.15.0
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### Example: Applying Ignore Directives
|
|
133
|
+
|
|
134
|
+
Use ignore directives to prevent generated code or untestable edge cases from lowering coverage scores.
|
|
135
|
+
|
|
136
|
+
```dart
|
|
137
|
+
// coverage:ignore-file
|
|
138
|
+
import 'package:meta/meta.dart';
|
|
139
|
+
|
|
140
|
+
class SystemConfig {
|
|
141
|
+
final String env;
|
|
142
|
+
|
|
143
|
+
SystemConfig(this.env);
|
|
144
|
+
|
|
145
|
+
// coverage:ignore-start
|
|
146
|
+
void legacyInit() {
|
|
147
|
+
print('Deprecated initialization');
|
|
148
|
+
}
|
|
149
|
+
// coverage:ignore-end
|
|
150
|
+
|
|
151
|
+
bool isProduction() {
|
|
152
|
+
if (env == 'prod') return true;
|
|
153
|
+
return false; // coverage:ignore-line
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Flutter Ultra Integration
|
|
159
|
+
|
|
160
|
+
Collect coverage directly via the test runner:
|
|
161
|
+
|
|
162
|
+
- `mcp__plugin_flutter_flutter-ultra-build__start_run_unit_tests` — Run tests with `coverage: true` to collect LCOV data
|
|
163
|
+
- `mcp__plugin_flutter_flutter-ultra-build__get_run_unit_tests_result` — Get results including coverage report path
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
> **Attribution:** This skill is vendored from [dart-lang/skills](https://github.com/dart-lang/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,152 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: fix-layout-issues
|
|
3
|
+
description: Fixes Flutter layout errors (overflows, unbounded constraints) using Dart and Flutter MCP tools. Use when addressing "RenderFlex overflowed", "Vertical viewport was given unbounded height", or similar layout issues.
|
|
4
|
+
last_modified: Tue, 21 Apr 2026 19:45:59 GMT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Resolving Flutter Layout Errors
|
|
8
|
+
|
|
9
|
+
## Contents
|
|
10
|
+
|
|
11
|
+
- [Constraint Violation Diagnostics](#constraint-violation-diagnostics)
|
|
12
|
+
- [Layout Error Resolution Workflow](#layout-error-resolution-workflow)
|
|
13
|
+
- [Examples](#examples)
|
|
14
|
+
|
|
15
|
+
## Constraint Violation Diagnostics
|
|
16
|
+
|
|
17
|
+
Flutter layout operates on a strict rule: **Constraints go down. Sizes go up. Parent sets position.** Layout errors occur when this negotiation fails, typically due to unbounded constraints or unconstrained children.
|
|
18
|
+
|
|
19
|
+
Diagnose layout failures using the following error signatures:
|
|
20
|
+
|
|
21
|
+
- **"Vertical viewport was given unbounded height"**: Triggered when a scrollable widget (`ListView`, `GridView`) is placed inside an unconstrained vertical parent (`Column`). The parent provides infinite height, and the child attempts to expand infinitely.
|
|
22
|
+
- **"An InputDecorator...cannot have an unbounded width"**: Triggered when a `TextField` or `TextFormField` is placed inside an unconstrained horizontal parent (`Row`). The text field attempts to determine its width based on infinite available space.
|
|
23
|
+
- **"RenderFlex overflowed"**: Triggered when a child of a `Row` or `Column` requests a size larger than the parent's allocated constraints. Visually indicated by yellow and black warning stripes.
|
|
24
|
+
- **"Incorrect use of ParentData widget"**: Triggered when a `ParentDataWidget` is not a direct descendant of its required ancestor. (e.g., `Expanded` outside a `Flex`, `Positioned` outside a `Stack`).
|
|
25
|
+
- **"RenderBox was not laid out"**: A cascading side-effect error. Ignore this and look further up the stack trace for the primary constraint violation (usually an unbounded height/width error).
|
|
26
|
+
|
|
27
|
+
## Layout Error Resolution Workflow
|
|
28
|
+
|
|
29
|
+
Copy and use this checklist to systematically resolve layout constraint violations.
|
|
30
|
+
|
|
31
|
+
### Task Progress
|
|
32
|
+
|
|
33
|
+
- [ ] Run the application in debug mode to capture the exact layout exception in the console.
|
|
34
|
+
- [ ] Identify the primary error message (ignore cascading "RenderBox was not laid out" errors).
|
|
35
|
+
- [ ] Apply the conditional fix based on the specific error type:
|
|
36
|
+
- **If "Vertical viewport was given unbounded height"**: Wrap the scrollable child (`ListView`, `GridView`) in an `Expanded` widget to consume remaining space, or wrap it in a `SizedBox` to provide an absolute height constraint.
|
|
37
|
+
- **If "An InputDecorator...cannot have an unbounded width"**: Wrap the `TextField` or `TextFormField` in an `Expanded` or `Flexible` widget.
|
|
38
|
+
- **If "RenderFlex overflowed"**: Constrain the overflowing child by wrapping it in an `Expanded` widget (to force it to fit) or a `Flexible` widget (to allow it to be smaller than the allocated space).
|
|
39
|
+
- **If "Incorrect use of ParentData widget"**: Move the `ParentDataWidget` to be a direct child of its required parent. Ensure `Expanded`/`Flexible` are direct children of `Row`/`Column`/`Flex`. Ensure `Positioned` is a direct child of `Stack`.
|
|
40
|
+
- [ ] Execute Flutter hot reload.
|
|
41
|
+
- [ ] Run validator -> review errors -> fix: Inspect the UI to verify the red/grey error screen or yellow/black overflow stripes are resolved. If new layout errors appear, repeat the workflow.
|
|
42
|
+
|
|
43
|
+
## Examples
|
|
44
|
+
|
|
45
|
+
### Fixing Unbounded Height (ListView in Column)
|
|
46
|
+
|
|
47
|
+
**Input (Error State):**
|
|
48
|
+
|
|
49
|
+
```dart
|
|
50
|
+
// Throws "Vertical viewport was given unbounded height"
|
|
51
|
+
Column(
|
|
52
|
+
children: <Widget>[
|
|
53
|
+
const Text('Header'),
|
|
54
|
+
ListView(
|
|
55
|
+
children: const <Widget>[
|
|
56
|
+
ListTile(title: Text('Item 1')),
|
|
57
|
+
ListTile(title: Text('Item 2')),
|
|
58
|
+
],
|
|
59
|
+
),
|
|
60
|
+
],
|
|
61
|
+
)
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
**Output (Resolved State):**
|
|
65
|
+
|
|
66
|
+
```dart
|
|
67
|
+
// Wrap ListView in Expanded to constrain its height to the remaining Column space
|
|
68
|
+
Column(
|
|
69
|
+
children: <Widget>[
|
|
70
|
+
const Text('Header'),
|
|
71
|
+
Expanded(
|
|
72
|
+
child: ListView(
|
|
73
|
+
children: const <Widget>[
|
|
74
|
+
ListTile(title: Text('Item 1')),
|
|
75
|
+
ListTile(title: Text('Item 2')),
|
|
76
|
+
],
|
|
77
|
+
),
|
|
78
|
+
),
|
|
79
|
+
],
|
|
80
|
+
)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Fixing Unbounded Width (TextField in Row)
|
|
84
|
+
|
|
85
|
+
**Input (Error State):**
|
|
86
|
+
|
|
87
|
+
```dart
|
|
88
|
+
// Throws "An InputDecorator...cannot have an unbounded width"
|
|
89
|
+
Row(
|
|
90
|
+
children: [
|
|
91
|
+
const Icon(Icons.search),
|
|
92
|
+
TextField(),
|
|
93
|
+
],
|
|
94
|
+
)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
**Output (Resolved State):**
|
|
98
|
+
|
|
99
|
+
```dart
|
|
100
|
+
// Wrap TextField in Expanded to constrain its width to the remaining Row space
|
|
101
|
+
Row(
|
|
102
|
+
children: [
|
|
103
|
+
const Icon(Icons.search),
|
|
104
|
+
Expanded(
|
|
105
|
+
child: TextField(),
|
|
106
|
+
),
|
|
107
|
+
],
|
|
108
|
+
)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Fixing RenderFlex Overflow
|
|
112
|
+
|
|
113
|
+
**Input (Error State):**
|
|
114
|
+
|
|
115
|
+
```dart
|
|
116
|
+
// Throws "A RenderFlex overflowed by X pixels on the right"
|
|
117
|
+
Row(
|
|
118
|
+
children: [
|
|
119
|
+
const Icon(Icons.info),
|
|
120
|
+
const Text('This is a very long text string that will definitely overflow the available screen width and cause a RenderFlex error.'),
|
|
121
|
+
],
|
|
122
|
+
)
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**Output (Resolved State):**
|
|
126
|
+
|
|
127
|
+
```dart
|
|
128
|
+
// Wrap the Text widget in Expanded to force it to wrap within the available constraints
|
|
129
|
+
Row(
|
|
130
|
+
children: [
|
|
131
|
+
const Icon(Icons.info),
|
|
132
|
+
Expanded(
|
|
133
|
+
child: const Text('This is a very long text string that will definitely overflow the available screen width and cause a RenderFlex error.'),
|
|
134
|
+
),
|
|
135
|
+
],
|
|
136
|
+
)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Flutter Ultra Integration
|
|
140
|
+
|
|
141
|
+
Diagnose and verify layout fixes with live app inspection:
|
|
142
|
+
|
|
143
|
+
- `mcp__plugin_flutter_flutter-ultra-runtime__get_runtime_errors` — Fetch current runtime errors including RenderFlex overflows
|
|
144
|
+
- `mcp__plugin_flutter_flutter-ultra-runtime__dump_render_tree` — Inspect render tree to see constraint propagation
|
|
145
|
+
- `mcp__plugin_flutter_flutter-ultra-runtime__toggle_debug_paint` — Toggle debug paint to visualize layout boundaries
|
|
146
|
+
- `mcp__plugin_flutter_flutter-ultra-runtime__hot_reload` — Hot reload after applying fix to verify immediately
|
|
147
|
+
- `mcp__plugin_flutter_flutter-ultra-runtime__screenshot` — Capture before/after screenshots of the fix
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
> **Attribution:** This skill is vendored from [flutter/skills](https://github.com/flutter/skills) (BSD-3-Clause).
|
|
152
|
+
> Synced by `scripts/sync-upstream-skills.mjs`. Do not edit manually — changes will be overwritten on next sync.
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: 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
|
+
last_modified: Fri, 24 Apr 2026 15:13:22 GMT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Resolving Dart Static Analysis Errors
|
|
8
|
+
|
|
9
|
+
## Contents
|
|
10
|
+
|
|
11
|
+
- [Core Concepts & Guidelines](#core-concepts--guidelines)
|
|
12
|
+
- [Type System & Soundness](#type-system--soundness)
|
|
13
|
+
- [Null Safety](#null-safety)
|
|
14
|
+
- [Error Handling](#error-handling)
|
|
15
|
+
- [Workflows](#workflows)
|
|
16
|
+
- [Workflow: Static Analysis Resolution](#workflow-static-analysis-resolution)
|
|
17
|
+
- [Examples](#examples)
|
|
18
|
+
|
|
19
|
+
## Core Concepts & Guidelines
|
|
20
|
+
|
|
21
|
+
### Type System & Soundness
|
|
22
|
+
|
|
23
|
+
Enforce Dart's sound type system to prevent runtime invalid states.
|
|
24
|
+
|
|
25
|
+
- **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.
|
|
26
|
+
- **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>`).
|
|
27
|
+
- **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.
|
|
28
|
+
- **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.
|
|
29
|
+
|
|
30
|
+
### Null Safety
|
|
31
|
+
|
|
32
|
+
Eliminate static errors related to null safety by correctly managing variable initialization and nullability.
|
|
33
|
+
|
|
34
|
+
- **Modifiers:** Apply `?` for nullable types, `!` for null assertions, and `required` for named parameters that cannot be null.
|
|
35
|
+
- **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.
|
|
36
|
+
- **Wildcards:** Use the `_` wildcard variable (Dart 3.7+) for non-binding local variables or parameters to avoid unused variable warnings.
|
|
37
|
+
|
|
38
|
+
### Error Handling
|
|
39
|
+
|
|
40
|
+
Distinguish between recoverable exceptions and unrecoverable errors.
|
|
41
|
+
|
|
42
|
+
- **Catching:** Catch `Exception` subtypes for recoverable failures.
|
|
43
|
+
- **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.
|
|
44
|
+
- **Rethrowing:** Use `rethrow` inside a `catch` block to propagate an exception while preserving its original stack trace.
|
|
45
|
+
|
|
46
|
+
## Workflows
|
|
47
|
+
|
|
48
|
+
### Workflow: Static Analysis Resolution
|
|
49
|
+
|
|
50
|
+
Use this sequential workflow to identify, fix, and verify static analysis errors in a Dart project. Copy the checklist to track your progress.
|
|
51
|
+
|
|
52
|
+
**Task Progress:**
|
|
53
|
+
|
|
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
|
+
|
|
62
|
+
```bash
|
|
63
|
+
dart analyze . --fatal-infos
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**2. Apply automated fixes**
|
|
67
|
+
Use the `dart fix` tool to automatically resolve standard linting and analysis issues.
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# Preview changes
|
|
71
|
+
dart fix --dry-run
|
|
72
|
+
# Apply changes
|
|
73
|
+
dart fix --apply
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**3. Resolve remaining errors manually**
|
|
77
|
+
Review the remaining analyzer output and apply conditional logic based on the error type:
|
|
78
|
+
|
|
79
|
+
- **If the error is a Null Safety issue (e.g., "Property cannot be accessed on a nullable receiver"):**
|
|
80
|
+
- Verify if the variable can logically be null.
|
|
81
|
+
- If yes, use optional chaining (`?.`) or provide a fallback (`??`).
|
|
82
|
+
- If no, and initialization is guaranteed elsewhere, mark the declaration with `late`.
|
|
83
|
+
- **If the error is a Type Mismatch (e.g., "The argument type 'List<dynamic>' can't be assigned..."):**
|
|
84
|
+
- Trace the variable's initialization.
|
|
85
|
+
- Add explicit generic type annotations to the instantiation (e.g., `<int>[]` instead of `[]`).
|
|
86
|
+
- **If the error is an Invalid Override (e.g., "The parameter type doesn't match the overridden method"):**
|
|
87
|
+
- Widen the parameter type to match the superclass, OR
|
|
88
|
+
- Add the `covariant` keyword to the parameter if tightening the type is intentionally required by the domain logic.
|
|
89
|
+
|
|
90
|
+
**4. Verify fixes (Feedback Loop)**
|
|
91
|
+
Run the validator. Review errors. Fix.
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
dart analyze .
|
|
95
|
+
dart test
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
- **If `dart analyze` reports errors:** Return to Step 3.
|
|
99
|
+
- **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.
|
|
100
|
+
|
|
101
|
+
## Examples
|
|
102
|
+
|
|
103
|
+
### Example: Fixing Dynamic List Assignments
|
|
104
|
+
|
|
105
|
+
**Input (Fails Static Analysis):**
|
|
106
|
+
|
|
107
|
+
```dart
|
|
108
|
+
void printInts(List<int> a) => print(a);
|
|
109
|
+
|
|
110
|
+
void main() {
|
|
111
|
+
final list = []; // Inferred as List<dynamic>
|
|
112
|
+
list.add(1);
|
|
113
|
+
list.add(2);
|
|
114
|
+
printInts(list); // Error: List<dynamic> can't be assigned to List<int>
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Output (Passes Static Analysis):**
|
|
119
|
+
|
|
120
|
+
```dart
|
|
121
|
+
void printInts(List<int> a) => print(a);
|
|
122
|
+
|
|
123
|
+
void main() {
|
|
124
|
+
final list = <int>[]; // Explicitly typed
|
|
125
|
+
list.add(1);
|
|
126
|
+
list.add(2);
|
|
127
|
+
printInts(list);
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Example: Fixing Method Overrides (Contravariance)
|
|
132
|
+
|
|
133
|
+
**Input (Fails Static Analysis):**
|
|
134
|
+
|
|
135
|
+
```dart
|
|
136
|
+
class Animal {
|
|
137
|
+
void chase(Animal a) {}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
class Cat extends Animal {
|
|
141
|
+
@override
|
|
142
|
+
void chase(Mouse a) {} // Error: Tightening parameter type
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Output (Passes Static Analysis):**
|
|
147
|
+
|
|
148
|
+
```dart
|
|
149
|
+
class Animal {
|
|
150
|
+
void chase(Animal a) {}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
class Cat extends Animal {
|
|
154
|
+
@override
|
|
155
|
+
void chase(covariant Mouse a) {} // Explicitly marked covariant
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Example: Fixing Null Safety with `late`
|
|
160
|
+
|
|
161
|
+
**Input (Fails Static Analysis):**
|
|
162
|
+
|
|
163
|
+
```dart
|
|
164
|
+
class Thermometer {
|
|
165
|
+
String temperature; // Error: Non-nullable instance field must be initialized
|
|
166
|
+
|
|
167
|
+
void read() {
|
|
168
|
+
temperature = '20C';
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Output (Passes Static Analysis):**
|
|
174
|
+
|
|
175
|
+
```dart
|
|
176
|
+
class Thermometer {
|
|
177
|
+
late String temperature; // Defers initialization check to runtime
|
|
178
|
+
|
|
179
|
+
void read() {
|
|
180
|
+
temperature = '20C';
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Flutter Ultra Integration
|
|
186
|
+
|
|
187
|
+
Diagnose and fix runtime errors in the live app:
|
|
188
|
+
|
|
189
|
+
- `mcp__plugin_flutter_flutter-ultra-runtime__get_runtime_errors` — Fetch active stack traces from the running app
|
|
190
|
+
- `mcp__plugin_flutter_flutter-ultra-runtime__evaluate` — Evaluate expressions in the running isolate
|
|
191
|
+
- `mcp__plugin_flutter_flutter-ultra-runtime__hot_reload` — Hot reload after applying fix to verify immediately
|
|
192
|
+
- `mcp__plugin_flutter_flutter-ultra-runtime__get_logs` — View recent log output for context
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
> **Attribution:** This skill is vendored from [dart-lang/skills](https://github.com/dart-lang/skills) (BSD-3-Clause).
|
|
197
|
+
> Synced by `scripts/sync-upstream-skills.mjs`. Do not edit manually — changes will be overwritten on next sync.
|