@bdayadev/flutter-ultra-mcp 1.6.0 → 1.8.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.
@@ -10,7 +10,7 @@
10
10
  {
11
11
  "name": "flutter",
12
12
  "description": "Durable cross-platform Flutter automation via 8 specialized MCP servers, in-app mixin binding, and an optional DevTools panel. Replaces marionette_mcp and the official dart mcp-server for Claude Code.",
13
- "version": "1.6.0",
13
+ "version": "1.8.0",
14
14
  "author": {
15
15
  "name": "Bdaya-Dev",
16
16
  "url": "https://github.com/Bdaya-Dev"
@@ -23,5 +23,5 @@
23
23
  "tags": ["flutter", "dart", "mcp", "testing", "automation", "patrol", "cross-platform"]
24
24
  }
25
25
  ],
26
- "version": "1.6.0"
26
+ "version": "1.8.0"
27
27
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
3
3
  "name": "flutter",
4
- "version": "1.6.0",
4
+ "version": "1.8.0",
5
5
  "description": "Durable cross-platform Flutter automation via 8 specialized MCP servers, in-app mixin binding, and an optional DevTools panel. Replaces marionette_mcp and the official dart mcp-server for Claude Code.",
6
6
  "author": {
7
7
  "name": "Bdaya-Dev",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bdayadev/flutter-ultra-mcp",
3
- "version": "1.6.0",
3
+ "version": "1.8.0",
4
4
  "description": "Flutter Ultra MCP plugin monorepo — 8 MCP servers + ultra_flutter Dart packages + skills for Claude Code.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/Bdaya-Dev/flutter-ultra-mcp",
@@ -1,152 +1,140 @@
1
1
  ---
2
2
  name: flutter-bisect
3
- description: Automate git bisect to find the commit that introduced a bug. Flutter-aware: runs pub get + build_runner between commits. Use when a test passes on an older commit but fails on HEAD and you need to find exactly which commit broke it.
3
+ description: Automates git bisect to find the commit that introduced a bug. Flutter-aware with pub get, build_runner, and flutter_clean between commits. Use when a test passes on an older commit but fails on HEAD and you need to find exactly which commit broke it.
4
4
  disable-model-invocation: true
5
5
  ---
6
6
 
7
- # flutter-bisect — Automated Regression Finder
7
+ # Automated Regression Finder
8
8
 
9
- ## When to use
10
-
11
- Use this skill when a test (unit, widget, or patrol E2E) passes on an older commit but fails on HEAD and you need to pinpoint exactly which commit introduced the regression. Do not use for diagnosing a bug you already know the source of — use `flutter-debug` instead.
12
-
13
- ## Prerequisites
14
-
15
- - The working tree is in a git repository (`git status` returns without error).
16
- - The user provides (or you can infer) a **known-good** commit reference: a tag (`v1.2.0`), a branch name (`main@{7 days ago}`), or a full SHA.
17
- - A **test oracle** is specified: a unit/widget test name pattern, a patrol test file, or a Bash-style exit-code command.
18
- - No uncommitted changes that would interfere — stash them first (see Edge cases).
9
+ Pinpoints the exact commit that broke a passing test via `git bisect`, running Flutter-aware setup at each step. For diagnosing a bug you already know the source of, use `flutter-debug` instead.
19
10
 
20
11
  ## Workflow
21
12
 
22
- ### 1. Confirm inputs before starting
23
-
24
- Ask (or confirm from context) the following before calling any git command:
13
+ ### 1. Confirm inputs
25
14
 
26
- - **Good commit**: the last-known-good reference (tag, SHA, or relative ref).
15
+ - **Good commit**: last-known-good tag, SHA, or relative ref.
27
16
  - **Bad commit**: defaults to `HEAD`.
28
- - **Oracle type**: `unit`, `widget`, or `patrol`.
17
+ - **Oracle type**: `unit`, `widget`, `golden`, or `patrol`.
29
18
  - **Oracle selector**: test name pattern or patrol `testFilePath`.
30
- - **Project**: call `mcp__plugin_flutter_flutter-ultra-build__list_projects` if not already known.
31
- - **Has build_runner**: check for `build.yaml` in the project root — if present, set `needs_build_runner=true`.
19
+ - **Project**: `mcp__plugin_flutter_flutter-ultra-build__list_projects` if not known.
20
+ - **Has build_runner**: check for `build.yaml` in the project root.
32
21
 
33
22
  ### 2. Stash uncommitted changes
34
23
 
35
- Before touching any git ref, check for dirty working tree:
36
-
37
- ```bash
38
- git -C <project-root> status --porcelain
39
- ```
40
-
41
- If output is non-empty, stash:
42
-
43
- ```bash
44
- git -C <project-root> stash push -m "flutter-bisect-autoStash"
45
- ```
46
-
47
- Record whether a stash was created — you must restore it in step 7.
24
+ Check for dirty working tree via Bash `git status --porcelain`. If non-empty, stash with `git stash push -m "flutter-bisect-autoStash"`.
48
25
 
49
26
  ### 3. Start bisect
50
27
 
51
28
  ```bash
52
- git -C <project-root> bisect start --first-parent HEAD <good-commit>
29
+ git bisect start --first-parent HEAD <good-commit>
53
30
  ```
54
31
 
55
- `--first-parent` skips noise from merged feature branches and keeps the walk on the mainline. Git prints the number of steps remaining — surface this to the user.
32
+ `--first-parent` keeps the walk on the mainline.
56
33
 
57
- ### 4. At each bisect step — the Flutter-aware oracle loop
58
-
59
- Repeat until git prints `<sha> is the first bad commit`:
34
+ ### 4. At each bisect step
60
35
 
61
36
  #### 4a. Get current commit info
62
37
 
63
38
  ```bash
64
- git -C <project-root> log -1 --format="%H %s"
39
+ git log -1 --format="%H %s"
65
40
  ```
66
41
 
67
- Show the user which commit is under test and how many steps remain.
68
-
69
- #### 4b. Restore Flutter state for this commit
70
-
71
- Run these in order — do not skip even if pubspec.yaml looks unchanged (lockfile may differ):
42
+ #### 4b. Restore Flutter state
72
43
 
73
- 1. **pub get**: `mcp__plugin_flutter_flutter-ultra-build__pub_get` with the project name.
74
- - If pub get fails (e.g. dependency conflict introduced by this commit), mark the commit **bad** and continue — a broken dep is a broken state.
75
- 2. **build_runner** (only if `needs_build_runner=true`):
76
- - Call `mcp__plugin_flutter_flutter-ultra-build__start_build_runner_build`.
77
- - Poll `mcp__plugin_flutter_flutter-ultra-build__poll_build_runner_job` until done.
78
- - Get result via `mcp__plugin_flutter_flutter-ultra-build__get_build_runner_result`.
79
- - If build_runner fails: mark the commit **bad** and continue.
44
+ 1. `mcp__plugin_flutter_flutter-ultra-build__pub_get` always run even if pubspec.yaml looks unchanged.
45
+ - If pub get fails (dependency conflict): mark **bad** and continue.
46
+ 2. If `needs_build_runner`:
47
+ - `mcp__plugin_flutter_flutter-ultra-build__start_build_runner_build`
48
+ - `mcp__plugin_flutter_flutter-ultra-build__poll_build_runner_job`
49
+ - `mcp__plugin_flutter_flutter-ultra-build__get_build_runner_result`
50
+ - If build_runner fails: mark **bad** and continue.
51
+ 3. If the commit changes Flutter SDK version (`.tool-versions`, `fvm`): `mcp__plugin_flutter_flutter-ultra-build__flutter_clean` before pub get.
80
52
 
81
53
  #### 4c. Run the oracle
82
54
 
83
55
  **Unit/widget oracle:**
84
56
 
85
- - Start: `mcp__plugin_flutter_flutter-ultra-build__start_run_unit_tests` with `testNamePattern` (or `start_run_widget_tests`).
86
- - Poll: `mcp__plugin_flutter_flutter-ultra-build__poll_run_unit_tests` (or `poll_run_widget_tests`).
87
- - Result: `mcp__plugin_flutter_flutter-ultra-build__get_run_unit_tests_result` (or `get_run_widget_tests_result`).
88
- - If all targeted tests pass **good**. If any fail **bad**.
57
+ - `mcp__plugin_flutter_flutter-ultra-build__start_run_unit_tests` (or `start_run_widget_tests`) with `testNamePattern`.
58
+ - `mcp__plugin_flutter_flutter-ultra-build__poll_run_unit_tests` (or `poll_run_widget_tests`).
59
+ - `mcp__plugin_flutter_flutter-ultra-build__get_run_unit_tests_result` (or `get_run_widget_tests_result`).
60
+ - All targeted tests pass -> **good**. Any fail -> **bad**.
61
+
62
+ **Golden oracle:**
63
+
64
+ - `mcp__plugin_flutter_flutter-ultra-build__start_run_golden_tests`
65
+ - `mcp__plugin_flutter_flutter-ultra-build__poll_run_golden_tests`
66
+ - `mcp__plugin_flutter_flutter-ultra-build__get_run_golden_tests_result`
89
67
 
90
68
  **Patrol oracle:**
91
69
 
92
- - Start: `mcp__plugin_flutter_flutter-ultra-patrol__start_patrol_test` with `testFilePath` and `device`.
93
- - Poll: `mcp__plugin_flutter_flutter-ultra-patrol__poll_patrol_job`.
94
- - Result: `mcp__plugin_flutter_flutter-ultra-patrol__get_patrol_result`.
95
- - If all steps pass → **good**. If any fail → **bad**.
70
+ - `mcp__plugin_flutter_flutter-ultra-patrol__start_patrol_test` with `testFilePath` and `device`.
71
+ - `mcp__plugin_flutter_flutter-ultra-patrol__poll_patrol_job`.
72
+ - `mcp__plugin_flutter_flutter-ultra-patrol__get_patrol_result`.
96
73
 
97
74
  #### 4d. Mark the commit
98
75
 
99
76
  ```bash
100
- # if oracle passed:
101
- git -C <project-root> bisect good
102
-
103
- # if oracle failed:
104
- git -C <project-root> bisect bad
77
+ git bisect good # if oracle passed
78
+ git bisect bad # if oracle failed
105
79
  ```
106
80
 
107
- Git will output the next commit to test, or the final verdict. Loop back to 4a.
108
-
109
- ### 5. Capture and report the first bad commit
110
-
111
- When git prints `<sha> is the first bad commit`, capture the full details:
112
-
113
- ```bash
114
- git -C <project-root> show --stat <sha>
115
- git -C <project-root> log -1 --format="%H%n%an <%ae>%n%ad%n%s%n%b" --date=iso <sha>
116
- ```
81
+ Loop back to 4a until git prints `<sha> is the first bad commit`.
117
82
 
118
- Present a structured report (see Output format).
83
+ ### 5. Build verification (optional)
119
84
 
120
- ### 6. Reset bisect
85
+ If the regression might be a build failure rather than a test failure, also run the platform build at each step using the build server's `start_build_{platform}` -> `poll_build_{platform}_job` -> `get_build_{platform}_result` pattern. Build failure -> **bad**.
121
86
 
122
- Always reset, even on error:
87
+ ### 6. Report the first bad commit
123
88
 
124
89
  ```bash
125
- git -C <project-root> bisect reset
90
+ git show --stat <sha>
91
+ git log -1 --format="%H%n%an <%ae>%n%ad%n%s%n%b" --date=iso <sha>
126
92
  ```
127
93
 
128
- ### 7. Restore stash (if created in step 2)
94
+ ### 7. Reset and restore
129
95
 
130
96
  ```bash
131
- git -C <project-root> stash pop
97
+ git bisect reset
98
+ git stash pop # if stash was created
132
99
  ```
133
100
 
134
101
  ## Edge cases
135
102
 
136
- | Situation | Handling |
137
- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
138
- | **Merge commits on the walk** | `--first-parent` avoids them; if user omits it intentionally (to bisect a merged branch), remove the flag and warn that step count increases. |
139
- | **Uncommitted changes** | Auto-stash in step 2; restore in step 7. If stash pop fails (conflict), warn the user and leave the stash intact — do not discard it. |
140
- | **Submodule repo** | `git bisect` operates on the outer repo. If the Flutter project is a submodule, confirm the user wants to bisect the outer aggregate, not the inner submodule. Pass the correct `-C <path>` to all git commands. |
141
- | **Flutter SDK version change** | If a commit changes the Flutter SDK constraint (`.tool-versions`, `fvm` config, `flutter.constraints`), call `mcp__plugin_flutter_flutter-ultra-build__flutter_clean` before pub get to clear the compiled kernel cache. |
142
- | **pub get resolves a different lockfile** | Expected this is exactly what the skill needs. Never pin the lockfile artificially during bisect. |
143
- | **Oracle is flaky** | If the oracle fails on a commit that visually looks clean, re-run it once. If it fails again, mark bad. Do not retry more than once per commit — flakiness analysis is out of scope here; use `flutter-debug` after bisect completes. |
144
- | **All commits bad (misconfigured good ref)** | If `git bisect start` immediately shows 0 steps or git says the good commit is not an ancestor, stop and ask the user to verify the good commit reference. |
103
+ | Situation | Handling |
104
+ |-----------|----------|
105
+ | **Merge commits** | `--first-parent` avoids them. Remove the flag only if the user explicitly wants to bisect a merged branch. |
106
+ | **Uncommitted changes** | Auto-stash in step 2; restore in step 7. |
107
+ | **Submodule repo** | Confirm the user wants to bisect the outer aggregate, not the inner submodule. |
108
+ | **Flutter SDK version change** | `mcp__plugin_flutter_flutter-ultra-build__flutter_clean` before pub get. |
109
+ | **Flaky oracle** | Re-run once. If it fails again, mark bad. |
110
+ | **All commits bad** | Stop and ask the user to verify the good commit reference. |
111
+
112
+ ## Tool reference
113
+
114
+ | Action | Tool |
115
+ |--------|------|
116
+ | List projects | `mcp__plugin_flutter_flutter-ultra-build__list_projects` |
117
+ | Pub get | `mcp__plugin_flutter_flutter-ultra-build__pub_get` |
118
+ | Flutter clean | `mcp__plugin_flutter_flutter-ultra-build__flutter_clean` |
119
+ | Build runner start | `mcp__plugin_flutter_flutter-ultra-build__start_build_runner_build` |
120
+ | Build runner poll | `mcp__plugin_flutter_flutter-ultra-build__poll_build_runner_job` |
121
+ | Build runner result | `mcp__plugin_flutter_flutter-ultra-build__get_build_runner_result` |
122
+ | Start unit tests | `mcp__plugin_flutter_flutter-ultra-build__start_run_unit_tests` |
123
+ | Poll unit tests | `mcp__plugin_flutter_flutter-ultra-build__poll_run_unit_tests` |
124
+ | Get unit results | `mcp__plugin_flutter_flutter-ultra-build__get_run_unit_tests_result` |
125
+ | Start widget tests | `mcp__plugin_flutter_flutter-ultra-build__start_run_widget_tests` |
126
+ | Poll widget tests | `mcp__plugin_flutter_flutter-ultra-build__poll_run_widget_tests` |
127
+ | Get widget results | `mcp__plugin_flutter_flutter-ultra-build__get_run_widget_tests_result` |
128
+ | Start golden tests | `mcp__plugin_flutter_flutter-ultra-build__start_run_golden_tests` |
129
+ | Poll golden tests | `mcp__plugin_flutter_flutter-ultra-build__poll_run_golden_tests` |
130
+ | Get golden results | `mcp__plugin_flutter_flutter-ultra-build__get_run_golden_tests_result` |
131
+ | Start patrol test | `mcp__plugin_flutter_flutter-ultra-patrol__start_patrol_test` |
132
+ | Poll patrol | `mcp__plugin_flutter_flutter-ultra-patrol__poll_patrol_job` |
133
+ | Get patrol result | `mcp__plugin_flutter_flutter-ultra-patrol__get_patrol_result` |
134
+ | Build (any platform) | `start_build_{platform}` via the build server |
145
135
 
146
136
  ## Output format
147
137
 
148
- After bisect completes, produce:
149
-
150
138
  ```
151
139
  ## Bisect Result
152
140
 
@@ -155,48 +143,30 @@ Author: <name> <<email>>
155
143
  Date: <iso date>
156
144
  Message: <subject line>
157
145
 
158
- <body if present>
159
-
160
146
  Files changed:
161
147
  <git show --stat output>
162
148
 
163
149
  Steps taken: <N> commits tested across <M> total candidates.
164
150
  ```
165
151
 
166
- If bisect could not converge (user cancelled, all commits bad, or git error), produce:
167
-
168
- ```
169
- ## Bisect Aborted
170
-
171
- Reason: <what went wrong>
172
- Last tested commit: <sha or "none">
173
- Recommendation: <next debugging step>
174
- ```
175
-
176
152
  ## Example
177
153
 
178
154
  ```
179
- User: "The InvoiceBloc unit test was green on v1.3.0 but fails on HEAD. Find which commit broke it."
180
-
181
- 1. list_projects project: "invora-flutter"
182
- 2. Check build.yaml present needs_build_runner=true
183
- 3. git status clean no stash needed
184
- 4. git bisect start --first-parent HEAD v1.3.0 "~6 steps (roughly 53 revisions)"
185
- 5. [commit abc123] pub_get ok; build_runner ok; run_unit_tests(pattern: "InvoiceBloc") FAIL bisect bad
186
- 6. [commit def456] pub_get ok; build_runner ok; run_unit_tests FAIL bisect bad
187
- 7. [commit ghi789] pub_get → ok; build_runner → ok; run_unit_tests → PASS → bisect good
188
- 8. [commit jkl012] pub_get ok; build_runner ok; run_unit_tests FAIL bisect bad
189
- 9. [commit mno345] pub_get → ok; build_runner → ok; run_unit_tests → PASS → bisect good
190
- 10. [commit pqr678] pub_get ok; build_runner → ok; run_unit_tests → FAIL → bisect bad
191
- 11. git: "pqr678 is the first bad commit"
192
- 12. git show --stat pqr678 → "refactor(billing): collapse invoice state machine"
193
- 13. git bisect reset
194
- → Report: first bad commit pqr678, author, date, changed files
155
+ User: "/flutter:bisect The InvoiceBloc test was green on v1.3.0 but fails on HEAD."
156
+
157
+ 1. list_projects -> "my-app", build.yaml present -> needs_build_runner=true
158
+ 2. git status -> clean, no stash needed
159
+ 3. git bisect start --first-parent HEAD v1.3.0 -> "~6 steps"
160
+ 4. [commit abc123] pub_get -> ok; build_runner -> ok; run_unit_tests("InvoiceBloc") -> FAIL -> bad
161
+ 5. [commit def456] pub_get -> ok; build_runner -> ok; run_unit_tests -> FAIL -> bad
162
+ 6. [commit ghi789] pub_get -> ok; build_runner -> ok; run_unit_tests -> PASS -> good
163
+ 7. ... (3 more steps)
164
+ 8. git: "pqr678 is the first bad commit" -> "refactor(billing): collapse invoice state machine"
165
+ 9. git bisect reset
166
+ -> Report with commit details and changed files
195
167
  ```
196
168
 
197
169
  ## See also
198
170
 
199
171
  - `flutter-test` — run the full test suite without bisecting
200
- - `flutter-debug` — inspect live runtime state after bisect identifies a suspect commit
201
- - `mcp__plugin_flutter_flutter-ultra-build__start_build_runner_build` — build_runner reference
202
- - `mcp__plugin_flutter_flutter-ultra-patrol__start_patrol_test` — patrol oracle reference
172
+ - `flutter-debug` — inspect live runtime state after identifying the suspect commit
@@ -1,156 +1,155 @@
1
1
  ---
2
2
  name: flutter-debug
3
- description: Attaching to a running Flutter app and triaging an error from the stack trace, widget tree, render tree, and recent screenshot. Use when the user reports a runtime exception, layout overflow, or unexpected behaviour and you need to inspect live state.
3
+ description: Attaches to a running Flutter app and triages an error from the stack trace, widget tree, render tree, network traffic, and screenshots. Use when the user reports a runtime exception, layout overflow, blank screen, unexpected behaviour, performance jank, or network failure and you need to inspect live state.
4
4
  ---
5
5
 
6
- # flutter-debug — Attach, Inspect, and Triage
6
+ # Attach, Inspect, and Triage
7
7
 
8
- ## When to use
9
-
10
- Use this skill when the user reports a runtime exception, a layout overflow, a blank screen, unexpected navigation, or any "it's broken" situation in a running Flutter app. The goal is to collect enough live evidence to diagnose the root cause without guessing. Propose code fixes only after inspecting live state — never before.
11
-
12
- ## Prerequisites
13
-
14
- - A Flutter app is running in debug mode (VM Service available).
15
- - The user has described the symptom: exception message, screen name, reproduction steps, or "just broke".
16
- - Do **not** modify any source files during this skill unless the user explicitly asks for a fix.
8
+ Collect live evidence before diagnosing. Propose code fixes only after inspecting live state.
17
9
 
18
10
  ## Workflow
19
11
 
20
- Follow the triage ladder in order — stop at the level where the root cause becomes clear.
21
-
22
12
  ### 1. Attach to the session
23
13
 
24
- - Call `mcp__plugin_flutter_flutter-ultra-runtime__discover_sessions` list all active sessions.
25
- - Pick the session matching the reported app (by name or port).
26
- - Call `mcp__plugin_flutter_flutter-ultra-runtime__attach` with `sessionId`.
27
-
28
- ### 2. Capture initial state
14
+ - `mcp__plugin_flutter_flutter-ultra-runtime__discover_sessions` to find active sessions.
15
+ - `mcp__plugin_flutter_flutter-ultra-runtime__attach` with the matching session.
29
16
 
30
- Run these together immediately after attach:
17
+ ### 2. Capture initial state (run together)
31
18
 
32
- - `mcp__plugin_flutter_flutter-ultra-runtime__screenshot` — visual snapshot of the current screen.
33
- - `mcp__plugin_flutter_flutter-ultra-runtime__get_runtime_errors` — all unhandled exceptions since last clear.
34
- - `mcp__plugin_flutter_flutter-ultra-runtime__get_logs` — recent `debugPrint` / `print` / framework log output.
19
+ - `mcp__plugin_flutter_flutter-ultra-runtime__screenshot` — visual snapshot.
20
+ - `mcp__plugin_flutter_flutter-ultra-runtime__get_runtime_errors` — unhandled exceptions.
21
+ - `mcp__plugin_flutter_flutter-ultra-runtime__get_logs` — recent framework/app log output.
22
+ - `mcp__plugin_flutter_flutter-ultra-runtime__log_buffer_stats` — check if logs were truncated.
35
23
 
36
24
  ### 3. Triage by error type
37
25
 
38
26
  #### 3a. Runtime exception (stack trace present)
39
27
 
40
- 1. Read the stack trace from `get_runtime_errors` — identify the throwing file and line.
41
- 2. Call `mcp__plugin_flutter_flutter-ultra-runtime__evaluate` to inspect the problematic object:
28
+ 1. Read the stack trace from `mcp__plugin_flutter_flutter-ultra-runtime__get_runtime_errors`.
29
+ 2. `mcp__plugin_flutter_flutter-ultra-runtime__evaluate` to inspect the problematic object:
42
30
  ```dart
43
- // Example: check if a value is null
44
31
  MyWidget.of(context)?.someField?.toString() ?? 'NULL'
45
32
  ```
46
- 3. Call `mcp__plugin_flutter_flutter-ultra-runtime__get_widget_tree` focused on the widget subtree around the reported location — pass `widgetId` if known from the stack frame.
47
- 4. Look for: null state, missing providers, incorrect key types, uninitialized controllers.
33
+ 3. `mcp__plugin_flutter_flutter-ultra-runtime__get_widget_tree` around the error location.
34
+ 4. `mcp__plugin_flutter_flutter-ultra-runtime__get_widget_details` on a specific widget for full properties.
48
35
 
49
- #### 3b. Layout overflow (RenderFlex / RenderBox overflow)
36
+ #### 3b. Layout overflow (RenderFlex / RenderBox)
50
37
 
51
- 1. Call `mcp__plugin_flutter_flutter-ultra-runtime__dump_render_tree` — search the output for `OVERFLOWED` or constraint violations.
52
- 2. Call `mcp__plugin_flutter_flutter-ultra-runtime__toggle_debug_paint` to enable visual constraint overlays; take another `screenshot`.
53
- 3. Identify the overflowing `RenderFlex` or `RenderConstrainedBox` and trace it back to the widget via `get_widget_tree`.
54
- 4. Common causes: missing `Expanded`/`Flexible`, fixed height in a `Column` inside a scrollable, `Text` without `overflow: TextOverflow.ellipsis`.
38
+ 1. `mcp__plugin_flutter_flutter-ultra-runtime__dump_render_tree` — search for `OVERFLOWED`.
39
+ 2. `mcp__plugin_flutter_flutter-ultra-runtime__toggle_debug_paint` to enable visual overlays.
40
+ 3. `mcp__plugin_flutter_flutter-ultra-runtime__screenshot` capture the debug paint view.
41
+ 4. Trace the overflowing render object back to its widget via `mcp__plugin_flutter_flutter-ultra-runtime__get_widget_tree`.
55
42
 
56
43
  #### 3c. Blank screen / wrong route
57
44
 
58
- 1. Call `mcp__plugin_flutter_flutter-ultra-runtime__evaluate`:
45
+ 1. `mcp__plugin_flutter_flutter-ultra-runtime__evaluate`:
59
46
  ```dart
60
47
  GoRouter.of(context).routerDelegate.currentConfiguration.fullPath
61
48
  ```
62
- to confirm the actual current route.
63
- 2. Call `mcp__plugin_flutter_flutter-ultra-runtime__get_widget_tree` from root — look for `ErrorWidget`, empty `SizedBox`, or a redirect loop (same route repeated in the navigator stack).
64
- 3. Check `get_logs` for GoRouter redirect events or `debugPrint` from route guards.
49
+ 2. `mcp__plugin_flutter_flutter-ultra-runtime__get_widget_tree` look for `ErrorWidget` or empty `SizedBox`.
50
+ 3. `mcp__plugin_flutter_flutter-ultra-runtime__get_logs` for redirect events.
65
51
 
66
- #### 3d. State / data issue (wrong data shown, stale UI)
52
+ #### 3d. State / data issue
67
53
 
68
- 1. Call `mcp__plugin_flutter_flutter-ultra-runtime__evaluate` to read the current BLoC/Riverpod/Provider state:
69
- ```dart
70
- context.read<MyBloc>().state.toString()
71
- // or for Riverpod:
72
- ProviderScope.containerOf(context).read(myProvider).toString()
73
- ```
74
- 2. Compare against expected values from the user's description.
75
- 3. Call `mcp__plugin_flutter_flutter-ultra-runtime__get_widget_tree` to verify the widget rebuilds are reaching the right subtree.
54
+ 1. `mcp__plugin_flutter_flutter-ultra-runtime__evaluate` to read BLoC/Riverpod/Provider state.
55
+ 2. `mcp__plugin_flutter_flutter-ultra-runtime__get_widget_tree` to verify rebuild propagation.
56
+ 3. `mcp__plugin_flutter_flutter-ultra-runtime__find_widget` to locate specific widgets showing wrong data.
76
57
 
77
- #### 3e. Accessibility / semantics issue
58
+ #### 3e. Network / API failure
78
59
 
79
- 1. Call `mcp__plugin_flutter_flutter-ultra-runtime__dump_semantics_tree` look for missing labels, incorrect roles, or hidden interactive elements.
80
- 2. Check for `excludeFromSemantics: true` incorrectly applied to interactive widgets.
60
+ 1. `mcp__plugin_flutter_flutter-ultra-runtime__start_http_capture` to begin recording.
61
+ 2. Reproduce the action that triggers the API call.
62
+ 3. `mcp__plugin_flutter_flutter-ultra-runtime__get_http_events` to inspect requests/responses.
63
+ 4. `mcp__plugin_flutter_flutter-ultra-runtime__decode_grpc_message` for gRPC payloads.
64
+ 5. `mcp__plugin_flutter_flutter-ultra-runtime__stop_http_capture` when done.
65
+ 6. For web targets, also check `mcp__plugin_flutter_flutter-ultra-browser__console_logs` and `mcp__plugin_flutter_flutter-ultra-browser__network_requests` for CORS or fetch errors.
81
66
 
82
- ### 4. Inspect the widget tree around the problem
67
+ #### 3f. Performance jank
83
68
 
84
- - Call `mcp__plugin_flutter_flutter-ultra-runtime__get_widget_tree` with the suspected parent widget key or type as anchor.
85
- - Call `mcp__plugin_flutter_flutter-ultra-runtime__get_widget_details` on a specific widget ID to get its full properties (constraints, size, key, state).
86
- - Call `mcp__plugin_flutter_flutter-ultra-runtime__find_widget` to locate a specific widget by key or text when the tree is large.
69
+ 1. `mcp__plugin_flutter_flutter-ultra-runtime__toggle_perf_overlay` to enable the performance overlay.
70
+ 2. `mcp__plugin_flutter_flutter-ultra-runtime__screenshot` to capture the overlay.
71
+ 3. `mcp__plugin_flutter_flutter-ultra-runtime__start_frame_tracking` to begin frame timing capture.
72
+ 4. Reproduce the janky interaction.
73
+ 5. `mcp__plugin_flutter_flutter-ultra-runtime__get_frame_timing` to read build/raster times.
74
+ 6. `mcp__plugin_flutter_flutter-ultra-runtime__stop_frame_tracking`.
75
+ 7. `mcp__plugin_flutter_flutter-ultra-runtime__start_rebuild_tracking` to find excessive rebuilds.
76
+ 8. `mcp__plugin_flutter_flutter-ultra-runtime__get_rebuild_stats` to identify hot widgets.
77
+ 9. `mcp__plugin_flutter_flutter-ultra-runtime__stop_rebuild_tracking`.
78
+ 10. `mcp__plugin_flutter_flutter-ultra-runtime__get_memory_usage` and `mcp__plugin_flutter_flutter-ultra-runtime__get_allocation_profile` for memory pressure issues.
87
79
 
88
- ### 5. Deeper render inspection
80
+ #### 3g. Accessibility / semantics issue
89
81
 
90
- If layout is the issue and the widget tree alone is not enough:
82
+ 1. `mcp__plugin_flutter_flutter-ultra-runtime__dump_semantics_tree` check for missing labels or roles.
83
+ 2. For mobile, `mcp__plugin_flutter_flutter-ultra-native-mobile__dump_a11y_tree` for the OS-level accessibility tree.
91
84
 
92
- - Call `mcp__plugin_flutter_flutter-ultra-runtime__dump_render_tree` — this shows sizes, constraints, and positions for every render object.
93
- - Call `mcp__plugin_flutter_flutter-ultra-runtime__dump_layer_tree` for compositing and repaint boundary issues (useful for performance jank or incorrect clipping).
85
+ #### 3h. Mobile-specific issues
94
86
 
95
- ### 6. Evaluate in-app expressions
87
+ 1. `mcp__plugin_flutter_flutter-ultra-native-mobile__start_device_logs` to capture platform-level logs.
88
+ 2. `mcp__plugin_flutter_flutter-ultra-native-mobile__poll_device_logs` to read logcat/syslog.
89
+ 3. `mcp__plugin_flutter_flutter-ultra-native-mobile__stop_device_logs` when done.
96
90
 
97
- Use `mcp__plugin_flutter_flutter-ultra-runtime__evaluate` freely to inspect live objects:
91
+ ### 4. Deeper inspection
98
92
 
99
- - Check if a future completed: `myCompleter.isCompleted`
100
- - Read a stream's last value: `myStreamController.stream` (wrap in a Future)
101
- - Confirm a service is initialized: `MyService.instance != null`
93
+ - `mcp__plugin_flutter_flutter-ultra-runtime__dump_render_tree` sizes, constraints, positions.
94
+ - `mcp__plugin_flutter_flutter-ultra-runtime__dump_layer_tree` compositing, repaint boundaries.
95
+ - `mcp__plugin_flutter_flutter-ultra-runtime__find_widget` to locate a specific widget by key or text.
96
+ - `mcp__plugin_flutter_flutter-ultra-runtime__count_widget_tree_nodes` to gauge tree complexity.
97
+ - `mcp__plugin_flutter_flutter-ultra-runtime__start_tail_logs` + `mcp__plugin_flutter_flutter-ultra-runtime__poll_tail_logs` for live log streaming during reproduction.
102
98
 
103
- ### 7. Test the fix
99
+ ### 5. Evaluate in-app expressions
104
100
 
105
- Once the root cause is identified and a code fix is proposed (or applied at user request):
101
+ `mcp__plugin_flutter_flutter-ultra-runtime__evaluate` freely to inspect live objects:
106
102
 
107
- - Call `mcp__plugin_flutter_flutter-ultra-runtime__hot_reload` to apply changes without losing app state.
108
- - Repeat step 3 (appropriate branch) to confirm the error is gone.
109
- - Call `mcp__plugin_flutter_flutter-ultra-runtime__screenshot` for a before/after comparison.
110
- - If hot reload is not sufficient (e.g. `initState` changed), call `mcp__plugin_flutter_flutter-ultra-runtime__hot_restart`.
103
+ - `myCompleter.isCompleted`
104
+ - `context.read<MyBloc>().state.toString()`
105
+ - `ProviderScope.containerOf(context).read(myProvider).toString()`
111
106
 
112
- ## Common patterns and their diagnosis
107
+ ### 6. Test the fix
113
108
 
114
- | Symptom | First tool | What to look for |
115
- | ------------------------------------------ | ----------------------------------------- | -------------------------------------------------------------------- |
116
- | `Null check operator used on a null value` | `get_runtime_errors` + `evaluate` | Null state before async load completes; missing null guard |
117
- | `RenderFlex overflowed by N pixels` | `dump_render_tree` + `toggle_debug_paint` | Column/Row child without `Expanded`; fixed height container |
118
- | Blank white screen | `get_widget_tree` + `evaluate` (route) | `ErrorWidget` at root; redirect loop; unhandled exception in build |
119
- | `setState called after dispose` | `get_runtime_errors` + `get_logs` | Async callback holding stale `BuildContext`; missing `mounted` check |
120
- | Navigation not working | `evaluate` (GoRouter path) + `get_logs` | Route guard redirecting; wrong named route; deep link not registered |
121
- | Infinite loading spinner | `evaluate` (state) + `get_logs` | Future never completing; stream not emitting; provider not notifying |
122
- | Wrong data displayed | `evaluate` (BLoC/provider state) | Stale state; `context.watch` vs `context.read` misuse |
109
+ 1. Apply the code change.
110
+ 2. `mcp__plugin_flutter_flutter-ultra-runtime__hot_reload` (or `mcp__plugin_flutter_flutter-ultra-runtime__hot_restart` if `initState` changed).
111
+ 3. Re-run the appropriate triage step to confirm the error is gone.
112
+ 4. `mcp__plugin_flutter_flutter-ultra-runtime__screenshot` for before/after comparison.
123
113
 
124
- ## Output format
114
+ ## Common patterns
125
115
 
126
- After triage, produce:
116
+ | Symptom | First tool | What to look for |
117
+ |---------|-----------|-----------------|
118
+ | `Null check operator used on null value` | `get_runtime_errors` + `evaluate` | Null state before async load completes |
119
+ | `RenderFlex overflowed by N pixels` | `dump_render_tree` + `toggle_debug_paint` | Missing `Expanded`/`Flexible` |
120
+ | Blank white screen | `get_widget_tree` + `evaluate` (route) | `ErrorWidget` at root; redirect loop |
121
+ | `setState called after dispose` | `get_runtime_errors` + `get_logs` | Async callback with stale `BuildContext` |
122
+ | Navigation not working | `evaluate` (GoRouter path) + `get_logs` | Route guard redirecting |
123
+ | Infinite loading spinner | `evaluate` (state) + `get_logs` | Future never completing |
124
+ | Wrong data displayed | `evaluate` (BLoC/provider state) | Stale state; `watch` vs `read` misuse |
125
+ | API returning errors | `start_http_capture` + `get_http_events` | 401/403/500 responses; CORS blocks |
126
+ | UI jank during scrolling | `start_frame_tracking` + `get_frame_timing` | Frames exceeding 16ms budget |
127
+ | Memory growing unbounded | `get_memory_usage` + `get_allocation_profile` | Leaked listeners or controllers |
128
+
129
+ ## Output format
127
130
 
128
131
  1. **Root cause**: one sentence identifying the exact problem.
129
- 2. **Evidence**: which tool output revealed it (stack trace line, widget tree excerpt, render tree constraint).
130
- 3. **Proposed fix**: specific code change with file and line reference (do not edit unless asked).
131
- 4. **Screenshots**: before state screenshot path; after-fix screenshot path if hot_reload was applied.
132
+ 2. **Evidence**: which tool output revealed it.
133
+ 3. **Proposed fix**: specific code change with file:line reference (do not edit unless asked).
134
+ 4. **Screenshots**: before/after paths.
132
135
 
133
136
  ## Example
134
137
 
135
138
  ```
136
- User: "The invoices list is showing a blank white screen after I merged the new filter PR."
137
-
138
- 1. discover_sessions attach(sessionId: "flutter-1")
139
- 2. screenshot blank screen confirmed
140
- 3. get_runtime_errors "Null check operator used on null value at invoice_list_bloc.dart:47"
141
- 4. evaluate: context.read<InvoiceListBloc>().state.toString() "InvoiceListInitial"
142
- (bloc never emitted data the filter query returned null instead of empty list)
143
- 5. get_widget_tree root is ErrorWidget wrapping the list scaffold
144
- 6. Root cause: InvoiceListBloc.mapEventToState at line 47 calls `event.filter!` but
145
- filter is null on first load after the PR introduced a nullable field.
146
- 7. Proposed fix: change `event.filter!` to `event.filter ?? const InvoiceFilter()` at
147
- invoice_list_bloc.dart:47.
148
- 8. hot_reload → screenshot → list loads correctly.
139
+ User: "The invoices list shows a blank white screen after merging the filter PR."
140
+
141
+ 1. discover_sessions -> attach(sessionId: "flutter-1")
142
+ 2. screenshot -> blank screen confirmed
143
+ 3. get_runtime_errors -> "Null check operator on null value at invoice_list_bloc.dart:47"
144
+ 4. evaluate: context.read<InvoiceListBloc>().state -> "InvoiceListInitial"
145
+ 5. get_widget_tree -> root is ErrorWidget wrapping the list scaffold
146
+ 6. start_http_capture -> get_http_events -> GET /api/invoices returned 200 with empty filter
147
+ 7. Root cause: line 47 calls `event.filter!` but filter is null on first load
148
+ 8. Proposed fix: `event.filter ?? const InvoiceFilter()` at line 47
149
+ 9. hot_reload -> screenshot -> list loads correctly
149
150
  ```
150
151
 
151
152
  ## See also
152
153
 
153
- - Sibling skill: `flutter-drive` for driving interactive flows before/after a fix
154
- - `mcp__plugin_flutter_flutter-ultra-runtime__get_runtime_errors` — unhandled exception log
155
- - `mcp__plugin_flutter_flutter-ultra-runtime__dump_render_tree` — full render object tree with constraints
156
- - `mcp__plugin_flutter_flutter-ultra-runtime__evaluate` — arbitrary Dart expression in live app context
154
+ - `flutter-drive` drive interactive flows to reproduce the bug
155
+ - `flutter-test` — run the test suite after applying a fix