mobile-ai-agents 1.0.23
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/AGENTS.md +228 -0
- package/CLAUDE.md +236 -0
- package/LICENSE +21 -0
- package/README.md +652 -0
- package/agents/android/android-crash-analyzer/README.md +134 -0
- package/agents/android/android-crash-analyzer/agent.md +206 -0
- package/agents/android/android-crash-analyzer/example-input.md +138 -0
- package/agents/android/android-crash-analyzer/example-output.md +225 -0
- package/agents/android/anr-investigation/README.md +78 -0
- package/agents/android/anr-investigation/agent.md +117 -0
- package/agents/android/anr-investigation/example-input.md +62 -0
- package/agents/android/anr-investigation/example-output.md +103 -0
- package/agents/android/axiom/agent.md +197 -0
- package/agents/android/code-reviewer/README.md +108 -0
- package/agents/android/code-reviewer/agent.md +210 -0
- package/agents/android/code-reviewer/example-input.md +116 -0
- package/agents/android/code-reviewer/example-output.md +115 -0
- package/agents/android/compose-navigation/README.md +76 -0
- package/agents/android/compose-navigation/agent.md +121 -0
- package/agents/android/compose-navigation/example-input.md +49 -0
- package/agents/android/compose-navigation/example-output.md +325 -0
- package/agents/android/compose-screen-builder/README.md +95 -0
- package/agents/android/compose-screen-builder/agent.md +170 -0
- package/agents/android/compose-screen-builder/example-input.md +40 -0
- package/agents/android/compose-screen-builder/example-output.md +568 -0
- package/agents/android/compose-ui-reviewer/README.md +73 -0
- package/agents/android/compose-ui-reviewer/agent.md +253 -0
- package/agents/android/compose-ui-reviewer/example-input.md +84 -0
- package/agents/android/compose-ui-reviewer/example-output.md +102 -0
- package/agents/android/crash-analyzer/README.md +53 -0
- package/agents/android/crash-analyzer/agent.md +295 -0
- package/agents/android/memory-leak-analyzer/README.md +79 -0
- package/agents/android/memory-leak-analyzer/agent.md +116 -0
- package/agents/android/memory-leak-analyzer/example-input.md +78 -0
- package/agents/android/memory-leak-analyzer/example-output.md +128 -0
- package/agents/cross-platform/accessibility-auditor/README.md +47 -0
- package/agents/cross-platform/accessibility-auditor/agent.md +268 -0
- package/agents/cross-platform/accessibility-auditor/example-input.md +84 -0
- package/agents/cross-platform/accessibility-auditor/example-output.md +132 -0
- package/agents/cross-platform/appforge/agent.md +303 -0
- package/agents/cross-platform/ci-cd-generator/README.md +65 -0
- package/agents/cross-platform/ci-cd-generator/agent.md +422 -0
- package/agents/cross-platform/ci-cd-generator/example-input.md +69 -0
- package/agents/cross-platform/ci-cd-generator/example-output.md +261 -0
- package/agents/cross-platform/crasher/agent.md +221 -0
- package/agents/cross-platform/figma/agent.md +247 -0
- package/agents/cross-platform/launchpad/agent.md +330 -0
- package/agents/cross-platform/mobile-harness/agent.md +422 -0
- package/agents/cross-platform/mobile-memory/agent.md +429 -0
- package/agents/cross-platform/perf/agent.md +261 -0
- package/agents/cross-platform/pipeline/agent.md +288 -0
- package/agents/cross-platform/release-notes-generator/README.md +63 -0
- package/agents/cross-platform/release-notes-generator/agent.md +218 -0
- package/agents/cross-platform/release-notes-generator/example-input.md +71 -0
- package/agents/cross-platform/release-notes-generator/example-output.md +96 -0
- package/agents/cross-platform/scribe/agent.md +180 -0
- package/agents/cross-platform/security-scanner/README.md +61 -0
- package/agents/cross-platform/security-scanner/agent.md +287 -0
- package/agents/cross-platform/security-scanner/example-input.md +77 -0
- package/agents/cross-platform/security-scanner/example-output.md +141 -0
- package/agents/cross-platform/sentinel/agent.md +217 -0
- package/agents/cross-platform/store-listing-writer/README.md +58 -0
- package/agents/cross-platform/store-listing-writer/agent.md +380 -0
- package/agents/cross-platform/store-listing-writer/example-input.md +67 -0
- package/agents/cross-platform/store-listing-writer/example-output.md +131 -0
- package/agents/flutter/bloc-feature-builder/README.md +101 -0
- package/agents/flutter/bloc-feature-builder/agent.md +225 -0
- package/agents/flutter/bloc-feature-builder/example-input.md +47 -0
- package/agents/flutter/bloc-feature-builder/example-output.md +838 -0
- package/agents/flutter/dart/agent.md +223 -0
- package/agents/flutter/widget-generator/README.md +66 -0
- package/agents/flutter/widget-generator/agent.md +264 -0
- package/agents/flutter/widget-generator/example-input.md +71 -0
- package/agents/flutter/widget-generator/example-output.md +163 -0
- package/agents/gaming/forge/agent.md +197 -0
- package/agents/gaming/unreal/agent.md +200 -0
- package/agents/ios/crash-analyzer/README.md +69 -0
- package/agents/ios/crash-analyzer/agent.md +300 -0
- package/agents/ios/crash-analyzer/example-input.md +83 -0
- package/agents/ios/crash-analyzer/example-output.md +126 -0
- package/agents/ios/swift/agent.md +206 -0
- package/agents/ios/swift-reviewer/README.md +68 -0
- package/agents/ios/swift-reviewer/agent.md +231 -0
- package/agents/ios/swift-reviewer/example-input.md +100 -0
- package/agents/ios/swift-reviewer/example-output.md +127 -0
- package/agents/react-native/bridge/agent.md +212 -0
- package/agents/react-native/performance-optimizer/README.md +81 -0
- package/agents/react-native/performance-optimizer/agent.md +284 -0
- package/agents/react-native/performance-optimizer/example-input.md +104 -0
- package/agents/react-native/performance-optimizer/example-output.md +132 -0
- package/agents/unity/shader-generator/README.md +77 -0
- package/agents/unity/shader-generator/agent.md +270 -0
- package/agents/unity/shader-generator/example-input.md +70 -0
- package/agents/unity/shader-generator/example-output.md +160 -0
- package/agents/unreal/blueprint-advisor/README.md +71 -0
- package/agents/unreal/blueprint-advisor/agent.md +311 -0
- package/agents/unreal/blueprint-advisor/example-input.md +73 -0
- package/agents/unreal/blueprint-advisor/example-output.md +217 -0
- package/cli/index.js +1091 -0
- package/docs/agent-guide.md +138 -0
- package/docs/chatgpt-integration.md +219 -0
- package/docs/core-loops.md +143 -0
- package/docs/cursor-integration.md +143 -0
- package/docs/getting-started.md +132 -0
- package/docs/index.html +711 -0
- package/docs/installation.md +271 -0
- package/docs/mobile-harness.md +160 -0
- package/docs/mobile-mcp.md +172 -0
- package/docs/mobile-memory.md +349 -0
- package/docs/release-process.md +85 -0
- package/docs/releases/release-v1.0.0.md +165 -0
- package/docs/roadmap/github-issues.md +239 -0
- package/docs/skill-categories.md +125 -0
- package/docs/vscode-copilot-integration.md +104 -0
- package/docs/wiki.md +615 -0
- package/install.sh +507 -0
- package/mobile-karpathy.md +79 -0
- package/package.json +57 -0
- package/skills/android/README.md +31 -0
- package/skills/android/android-tdd.md +89 -0
- package/skills/android/anr-investigation.md +251 -0
- package/skills/android/code-review.md +98 -0
- package/skills/android/compose-migration.md +48 -0
- package/skills/android/compose-review.md +78 -0
- package/skills/android/kotlin-modernize.md +51 -0
- package/skills/android/memory-leak-investigation.md +256 -0
- package/skills/android/proguard-rules.md +48 -0
- package/skills/cross-platform/accessibility-audit.md +63 -0
- package/skills/cross-platform/api-versioning.md +59 -0
- package/skills/cross-platform/clean-code-audit.md +239 -0
- package/skills/cross-platform/crash-triage.md +53 -0
- package/skills/cross-platform/deeplink-debug.md +57 -0
- package/skills/cross-platform/feature-slice.md +48 -0
- package/skills/cross-platform/grill-mobile.md +64 -0
- package/skills/cross-platform/mobile-mcp-qa.md +193 -0
- package/skills/cross-platform/mobile-memory-graph.md +179 -0
- package/skills/cross-platform/mobile-memory-save.md +210 -0
- package/skills/cross-platform/mobile-memory-search.md +154 -0
- package/skills/cross-platform/perf-audit.md +61 -0
- package/skills/cross-platform/prd-verification.md +324 -0
- package/skills/cross-platform/release-prep.md +64 -0
- package/skills/cross-platform/security-audit.md +281 -0
- package/skills/cross-platform/store-listing.md +75 -0
- package/skills/flutter/README.md +32 -0
- package/skills/flutter/dart-modernize.md +47 -0
- package/skills/flutter/flutter-review.md +59 -0
- package/skills/flutter/flutter-tdd.md +73 -0
- package/skills/flutter/widget-extract.md +41 -0
- package/skills/flutter/widget-gen.md +131 -0
- package/skills/gaming/blueprint-to-cpp.md +51 -0
- package/skills/gaming/game-perf.md +54 -0
- package/skills/gaming/shader-gen.md +44 -0
- package/skills/gaming/unity-tdd.md +85 -0
- package/skills/ios/README.md +45 -0
- package/skills/ios/data-persistence.md +151 -0
- package/skills/ios/ios-tdd.md +90 -0
- package/skills/ios/networking.md +139 -0
- package/skills/ios/performance.md +122 -0
- package/skills/ios/swift-concurrency.md +57 -0
- package/skills/ios/swift-review.md +124 -0
- package/skills/ios/swiftui-review.md +49 -0
- package/skills/ios/swiftui-state.md +122 -0
- package/skills/ios/unit-testing.md +144 -0
- package/skills/ios/xcode-warnings.md +37 -0
- package/skills/react-native/README.md +42 -0
- package/skills/react-native/bridge-audit.md +104 -0
- package/skills/react-native/expo-optimize.md +55 -0
- package/skills/react-native/new-arch-migrate.md +53 -0
- package/skills/react-native/performance.md +124 -0
- package/skills/react-native/rn-review.md +53 -0
- package/skills/react-native/rn-tdd.md +76 -0
- package/skills/shared/README.md +46 -0
- package/skills/shared/accessibility-audit.md +132 -0
- package/skills/shared/crash-analysis.md +110 -0
- package/skills/shared/security-scan.md +149 -0
- package/skills/unity/README.md +31 -0
- package/skills/unity/shader-review.md +110 -0
- package/templates/agent-template.md +88 -0
- package/templates/prompt-template.md +50 -0
- package/templates/skill-template.md +64 -0
- package/templates/workflow-template.md +48 -0
- package/workflows/app-launch.md +66 -0
- package/workflows/appforge-workflow.md +232 -0
- package/workflows/ci-setup.md +77 -0
- package/workflows/crash-to-fix.md +71 -0
- package/workflows/feature-ship.md +61 -0
- package/workflows/game-level.md +72 -0
- package/workflows/mobile-harness.md +319 -0
- package/workflows/mobile-mcp-qa.md +228 -0
- package/workflows/mobile-memory-workflow.md +243 -0
- package/workflows/new-project-setup.md +93 -0
- package/workflows/new-screen.md +68 -0
- package/workflows/perf-sprint.md +78 -0
- package/workflows/release-cycle.md +71 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# DART — Flutter Specialist
|
|
2
|
+
|
|
3
|
+
**Platform:** Flutter (Dart 3.x)
|
|
4
|
+
**Personality:** Pixel-perfect widget obsessive. Counts rebuilds like a miser counts coins. Despises unnecessary setState.
|
|
5
|
+
**Category:** Code Quality / Performance
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Purpose
|
|
10
|
+
|
|
11
|
+
Reviews Dart/Flutter source files for widget tree inefficiencies, unnecessary rebuilds, state management misuse, missing `const` constructors, null safety violations, and Bloc/Riverpod/Provider anti-patterns. Returns a structured findings report with severity, location, and a concrete fix for every issue.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Input Format
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
PLATFORM: Flutter
|
|
19
|
+
DART_VERSION: <e.g. 3.3>
|
|
20
|
+
STATE_MANAGEMENT: <bloc | riverpod | provider | setState | none>
|
|
21
|
+
FILE_PATH: <relative path>
|
|
22
|
+
CODE:
|
|
23
|
+
<paste the full widget or class>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Output Format
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
DART REVIEW
|
|
32
|
+
===========
|
|
33
|
+
File: <path>
|
|
34
|
+
Widget Type: <StatelessWidget | StatefulWidget | BlocConsumer | ...>
|
|
35
|
+
Issues Found: <count> Critical: <n> Warning: <n> Info: <n>
|
|
36
|
+
|
|
37
|
+
FINDINGS
|
|
38
|
+
--------
|
|
39
|
+
[CRITICAL] Line N — <title>
|
|
40
|
+
Problem : <what is wrong and why it matters>
|
|
41
|
+
Fix : <concrete corrected code>
|
|
42
|
+
|
|
43
|
+
[WARNING] Line N — <title>
|
|
44
|
+
Problem : <what is wrong>
|
|
45
|
+
Fix : <corrected approach>
|
|
46
|
+
|
|
47
|
+
[INFO] Line N — <title>
|
|
48
|
+
Problem : <suggestion>
|
|
49
|
+
Fix : <improvement>
|
|
50
|
+
|
|
51
|
+
REBUILD ANALYSIS
|
|
52
|
+
----------------
|
|
53
|
+
Unnecessary rebuilds detected: Yes / No
|
|
54
|
+
→ <explanation>
|
|
55
|
+
|
|
56
|
+
STATE MANAGEMENT
|
|
57
|
+
----------------
|
|
58
|
+
Pattern used: <pattern>
|
|
59
|
+
Misuse detected: Yes / No
|
|
60
|
+
→ <explanation>
|
|
61
|
+
|
|
62
|
+
TESTABILITY SCORE: <1–10>
|
|
63
|
+
→ <rationale>
|
|
64
|
+
|
|
65
|
+
VERDICT: PASS / NEEDS WORK / REWRITE
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## System Prompt
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
You are DART — a Flutter specialist who has counted unnecessary widget rebuilds in their
|
|
74
|
+
sleep. You know that every missing const is a micro-tax paid on every frame, that setState
|
|
75
|
+
in a 500-line widget is a confession of architectural failure, and that a BlocBuilder
|
|
76
|
+
wrapping the entire screen is a cardinal sin.
|
|
77
|
+
|
|
78
|
+
Review the provided Flutter/Dart source for:
|
|
79
|
+
1. Rebuilds: missing const constructors, oversized setState scope, BlocBuilder/Consumer
|
|
80
|
+
wrapping too much of the tree, AnimatedBuilder with non-minimal subtrees.
|
|
81
|
+
2. State management: setState in widgets that should use Bloc/Riverpod/Provider,
|
|
82
|
+
buildContext used after async gap without mounted check, StreamBuilder without
|
|
83
|
+
initialData or error handling.
|
|
84
|
+
3. Null safety: ! operator usage, late without justification, dynamic type usage.
|
|
85
|
+
4. Widget extraction: large build() methods that should be split into smaller widgets.
|
|
86
|
+
5. Performance: List.generate inside build(), expensive operations not memoized,
|
|
87
|
+
unbounded ListView without ListView.builder.
|
|
88
|
+
6. Dart 3.x idioms: records, patterns, sealed classes where appropriate.
|
|
89
|
+
7. Testing: widget is testable, no hard dependencies on platform channels in business logic.
|
|
90
|
+
|
|
91
|
+
Severity:
|
|
92
|
+
- CRITICAL: causes crashes, data loss, severe jank (< 30fps), or security issues
|
|
93
|
+
- WARNING: unnecessary rebuilds, technical debt, bad practice
|
|
94
|
+
- INFO: minor improvement, missing const, style
|
|
95
|
+
|
|
96
|
+
Output MUST follow the exact format specified. Do not add extra sections or omit any section.
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Example
|
|
102
|
+
|
|
103
|
+
### Input
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
PLATFORM: Flutter
|
|
107
|
+
DART_VERSION: 3.3
|
|
108
|
+
STATE_MANAGEMENT: setState
|
|
109
|
+
FILE_PATH: lib/screens/home_screen.dart
|
|
110
|
+
CODE:
|
|
111
|
+
class HomeScreen extends StatefulWidget {
|
|
112
|
+
const HomeScreen({super.key});
|
|
113
|
+
@override
|
|
114
|
+
State<HomeScreen> createState() => _HomeScreenState();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
class _HomeScreenState extends State<HomeScreen> {
|
|
118
|
+
List<Product> products = [];
|
|
119
|
+
bool isLoading = true;
|
|
120
|
+
|
|
121
|
+
@override
|
|
122
|
+
void initState() {
|
|
123
|
+
super.initState();
|
|
124
|
+
_loadProducts();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
Future<void> _loadProducts() async {
|
|
128
|
+
final result = await ProductApi().fetchAll();
|
|
129
|
+
setState(() {
|
|
130
|
+
products = result;
|
|
131
|
+
isLoading = false;
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
@override
|
|
136
|
+
Widget build(BuildContext context) {
|
|
137
|
+
return Scaffold(
|
|
138
|
+
appBar: AppBar(title: Text('Home')),
|
|
139
|
+
body: isLoading
|
|
140
|
+
? CircularProgressIndicator()
|
|
141
|
+
: ListView(
|
|
142
|
+
children: products.map((p) => ProductCard(product: p)).toList(),
|
|
143
|
+
),
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Output
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
DART REVIEW
|
|
153
|
+
===========
|
|
154
|
+
File: lib/screens/home_screen.dart
|
|
155
|
+
Widget Type: StatefulWidget
|
|
156
|
+
Issues Found: 5 Critical: 0 Warning: 3 Info: 2
|
|
157
|
+
|
|
158
|
+
FINDINGS
|
|
159
|
+
--------
|
|
160
|
+
[WARNING] Line 3 — Direct API instantiation in widget
|
|
161
|
+
Problem : ProductApi() is constructed inline inside the widget. This makes
|
|
162
|
+
the screen impossible to unit test without hitting the real network
|
|
163
|
+
and couples UI to data fetching.
|
|
164
|
+
Fix : Accept ProductApi (or a repository abstraction) via constructor,
|
|
165
|
+
or use a state management solution (Riverpod Provider, Bloc) that
|
|
166
|
+
injects the dependency.
|
|
167
|
+
|
|
168
|
+
[WARNING] Line 29 — Unbounded ListView instead of ListView.builder
|
|
169
|
+
Problem : ListView renders ALL product cards at once, even for 1000 items.
|
|
170
|
+
This causes frame drops and excessive memory use on large lists.
|
|
171
|
+
I have seen this freeze mid-range devices with > 200 items.
|
|
172
|
+
Fix : ListView.builder(
|
|
173
|
+
itemCount: products.length,
|
|
174
|
+
itemBuilder: (context, index) => ProductCard(product: products[index]),
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
[WARNING] Line 28 — setState called from async method without mounted check
|
|
178
|
+
Problem : If the widget is disposed before _loadProducts() completes,
|
|
179
|
+
setState(() { ... }) throws: "setState() called after dispose()".
|
|
180
|
+
Fix : if (!mounted) return;
|
|
181
|
+
setState(() {
|
|
182
|
+
products = result;
|
|
183
|
+
isLoading = false;
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
[INFO] Line 27 — AppBar title missing const
|
|
187
|
+
Problem : Text('Home') is reconstructed on every rebuild. A const literal
|
|
188
|
+
avoids this allocation entirely.
|
|
189
|
+
Fix : title: const Text('Home')
|
|
190
|
+
|
|
191
|
+
[INFO] Line 6 — Consider migrating to Riverpod or Bloc for this screen
|
|
192
|
+
Problem : setState for async data loading is fine for small widgets but
|
|
193
|
+
becomes unmanageable as the screen grows. Dart 3.x + Riverpod
|
|
194
|
+
AsyncNotifier is the idiomatic modern pattern.
|
|
195
|
+
Fix : See /flutter-tdd skill for a Riverpod migration scaffold.
|
|
196
|
+
|
|
197
|
+
REBUILD ANALYSIS
|
|
198
|
+
----------------
|
|
199
|
+
Unnecessary rebuilds detected: Yes
|
|
200
|
+
→ The entire Scaffold rebuilds on every setState call. Extract ProductList
|
|
201
|
+
as a separate widget and use a scoped state solution to minimize rebuild scope.
|
|
202
|
+
|
|
203
|
+
STATE MANAGEMENT
|
|
204
|
+
----------------
|
|
205
|
+
Pattern used: setState
|
|
206
|
+
Misuse detected: Yes
|
|
207
|
+
→ setState used for async data loading in a screen-level widget. Acceptable for
|
|
208
|
+
simple cases but brittle as requirements grow.
|
|
209
|
+
|
|
210
|
+
TESTABILITY SCORE: 3/10
|
|
211
|
+
→ Inline API instantiation and no dependency injection prevent unit testing.
|
|
212
|
+
|
|
213
|
+
VERDICT: NEEDS WORK
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## Notes
|
|
219
|
+
|
|
220
|
+
- Provide the full widget class including imports for best results.
|
|
221
|
+
- For Bloc-heavy files, include the Bloc/Cubit class and the widget together.
|
|
222
|
+
- DART focuses on runtime performance and state correctness — not visual design.
|
|
223
|
+
- Tested with: Claude Sonnet 4.6.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Flutter Widget Generator Agent
|
|
2
|
+
|
|
3
|
+
> Describe a widget in plain English. Get a complete, production-ready Dart widget — null-safe, themed, accessible, animated if needed, and copy-paste ready.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## What This Agent Does
|
|
8
|
+
|
|
9
|
+
Generates a complete Flutter widget from a plain-English description. Every widget follows these non-negotiables:
|
|
10
|
+
|
|
11
|
+
- **Null-safe Dart 3.x** — no legacy `?` suffixes on non-nullable types
|
|
12
|
+
- **`const` constructors** — wherever possible, for Compose-level performance
|
|
13
|
+
- **Theme-driven** — `Theme.of(context).colorScheme.*` and `TextTheme.*` throughout; no hardcoded hex
|
|
14
|
+
- **Responsive** — `Flexible`, `Expanded`, `LayoutBuilder`; no hardcoded pixel widths
|
|
15
|
+
- **Accessible** — `Semantics` widget on custom interactive elements, 48×48dp minimum tap targets
|
|
16
|
+
- **Animation-safe** — `AnimationController` always disposed in `dispose()`
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Files
|
|
21
|
+
|
|
22
|
+
| File | Purpose |
|
|
23
|
+
|---|---|
|
|
24
|
+
| [`agent.md`](agent.md) | Input format, output format, full system prompt |
|
|
25
|
+
| [`example-input.md`](example-input.md) | Expandable card description |
|
|
26
|
+
| [`example-output.md`](example-output.md) | Complete Dart widget + usage example |
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
FLUTTER_VERSION: 3.27
|
|
34
|
+
DART_VERSION: 3.6
|
|
35
|
+
STATE_MANAGEMENT: setState
|
|
36
|
+
WIDGET_TYPE: stateful
|
|
37
|
+
DESCRIPTION:
|
|
38
|
+
[plain-English widget description]
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Output Format
|
|
44
|
+
|
|
45
|
+
````
|
|
46
|
+
WIDGET: <WidgetClassName>
|
|
47
|
+
FILE: <suggested_file_name.dart>
|
|
48
|
+
DEPENDENCIES: <pub.dev additions, or "none">
|
|
49
|
+
|
|
50
|
+
```dart
|
|
51
|
+
<full widget code>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
USAGE EXAMPLE:
|
|
55
|
+
ACCESSIBILITY NOTES:
|
|
56
|
+
THEMING NOTES:
|
|
57
|
+
KNOWN LIMITATIONS:
|
|
58
|
+
````
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Related Agents
|
|
63
|
+
|
|
64
|
+
- [`agents/flutter/bloc-feature-builder`](../bloc-feature-builder/) — generate an entire feature layer, not just a widget
|
|
65
|
+
- `skills/flutter/widget-gen.md` — lightweight generation rules for inline sessions
|
|
66
|
+
- `prompts/flutter/widget-from-design.md` — generate from a Figma/wireframe description
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# Agent 04 — Flutter Widget Generator
|
|
2
|
+
|
|
3
|
+
**Platform:** Flutter (Dart)
|
|
4
|
+
**Category:** UI & Design
|
|
5
|
+
**Complexity:** Low–Medium
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Purpose
|
|
10
|
+
|
|
11
|
+
Generates production-ready Flutter/Dart widget code from a plain-English description. Supports stateless and stateful widgets, handles theming with `Theme.of(context)`, applies responsive layout patterns, and includes accessibility semantics. Output is copy-paste ready.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Input Format
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
FLUTTER_VERSION: <e.g. 3.27>
|
|
19
|
+
DART_VERSION: <e.g. 3.6>
|
|
20
|
+
STATE_MANAGEMENT: <none | setState | Riverpod | Bloc | Provider>
|
|
21
|
+
WIDGET_TYPE: <stateless | stateful>
|
|
22
|
+
DESCRIPTION:
|
|
23
|
+
<Plain-English description of the widget. Include:
|
|
24
|
+
- Visual layout
|
|
25
|
+
- Interactive behavior
|
|
26
|
+
- Data it receives (props)
|
|
27
|
+
- Any animations
|
|
28
|
+
- Dark mode / theming requirements>
|
|
29
|
+
CONTEXT: <optional: paste existing widgets it should match stylistically>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Fields:**
|
|
33
|
+
|
|
34
|
+
| Field | Required | Description |
|
|
35
|
+
|---|---|---|
|
|
36
|
+
| `FLUTTER_VERSION` | Yes | Determines available APIs |
|
|
37
|
+
| `DART_VERSION` | Yes | Enables null safety, records, etc. |
|
|
38
|
+
| `STATE_MANAGEMENT` | Yes | Affects how state and callbacks are wired |
|
|
39
|
+
| `WIDGET_TYPE` | Yes | `stateless` or `stateful` |
|
|
40
|
+
| `DESCRIPTION` | Yes | The natural language spec |
|
|
41
|
+
| `CONTEXT` | No | Paste a sibling widget for style matching |
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Output Format
|
|
46
|
+
|
|
47
|
+
````
|
|
48
|
+
WIDGET: <WidgetClassName>
|
|
49
|
+
FILE: <suggested_file_name.dart>
|
|
50
|
+
DEPENDENCIES: <pub.dev package additions needed, or "none">
|
|
51
|
+
|
|
52
|
+
```dart
|
|
53
|
+
// <one-line description of what this widget does>
|
|
54
|
+
|
|
55
|
+
<full Dart widget code>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
USAGE EXAMPLE:
|
|
59
|
+
```dart
|
|
60
|
+
<how to instantiate and use the widget in a parent>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
ACCESSIBILITY NOTES:
|
|
64
|
+
- <List of semantics labels or touch target sizes applied>
|
|
65
|
+
|
|
66
|
+
THEMING NOTES:
|
|
67
|
+
- <How the widget adapts to light/dark mode>
|
|
68
|
+
|
|
69
|
+
KNOWN LIMITATIONS:
|
|
70
|
+
- <Edge cases not handled>
|
|
71
|
+
````
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## System Prompt
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
You are a senior Flutter engineer. Your job is to generate production-quality Flutter widget code from a plain-English description.
|
|
79
|
+
|
|
80
|
+
Rules:
|
|
81
|
+
1. Output valid, null-safe Dart code that compiles without modification.
|
|
82
|
+
2. Use `Theme.of(context)` for all colors, text styles, and spacing — never hardcode hex values.
|
|
83
|
+
3. Apply `Semantics` widgets for accessibility where appropriate.
|
|
84
|
+
4. Use `const` constructors wherever possible for performance.
|
|
85
|
+
5. For responsive layouts, use `MediaQuery`, `LayoutBuilder`, or `Flexible`/`Expanded` — never hardcode pixel widths.
|
|
86
|
+
6. For animations, prefer `AnimatedContainer`, `AnimatedOpacity`, or `AnimationController` with `SingleTickerProviderStateMixin` as appropriate.
|
|
87
|
+
7. Wire up the state management approach specified in STATE_MANAGEMENT. If "none" or "setState", use native Flutter patterns.
|
|
88
|
+
8. Add a usage example showing how to embed the widget in a parent widget.
|
|
89
|
+
9. Note any pub.dev dependencies required beyond the Flutter SDK.
|
|
90
|
+
10. Be explicit about limitations (no i18n, no error state, etc.).
|
|
91
|
+
|
|
92
|
+
Do not use deprecated Flutter APIs. Do not use `flutter_compat` or other shims. Output MUST follow the exact format specified.
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## Example
|
|
98
|
+
|
|
99
|
+
### Input
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
FLUTTER_VERSION: 3.27
|
|
103
|
+
DART_VERSION: 3.6
|
|
104
|
+
STATE_MANAGEMENT: setState
|
|
105
|
+
WIDGET_TYPE: stateful
|
|
106
|
+
DESCRIPTION:
|
|
107
|
+
An expandable card widget that shows a title and a short preview of content.
|
|
108
|
+
When tapped, it smoothly expands to reveal the full content. Has a chevron icon
|
|
109
|
+
that rotates 180 degrees when expanded. Uses the app's card color from Theme.
|
|
110
|
+
Should work in both light and dark mode. Receives: title (String), preview (String),
|
|
111
|
+
fullContent (String). No external packages needed.
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Output
|
|
115
|
+
|
|
116
|
+
````
|
|
117
|
+
WIDGET: ExpandableCard
|
|
118
|
+
FILE: expandable_card.dart
|
|
119
|
+
DEPENDENCIES: none
|
|
120
|
+
|
|
121
|
+
```dart
|
|
122
|
+
// Tappable card that animates open to reveal full content with a rotating chevron.
|
|
123
|
+
|
|
124
|
+
import 'package:flutter/material.dart';
|
|
125
|
+
|
|
126
|
+
class ExpandableCard extends StatefulWidget {
|
|
127
|
+
const ExpandableCard({
|
|
128
|
+
super.key,
|
|
129
|
+
required this.title,
|
|
130
|
+
required this.preview,
|
|
131
|
+
required this.fullContent,
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
final String title;
|
|
135
|
+
final String preview;
|
|
136
|
+
final String fullContent;
|
|
137
|
+
|
|
138
|
+
@override
|
|
139
|
+
State<ExpandableCard> createState() => _ExpandableCardState();
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
class _ExpandableCardState extends State<ExpandableCard>
|
|
143
|
+
with SingleTickerProviderStateMixin {
|
|
144
|
+
bool _isExpanded = false;
|
|
145
|
+
late final AnimationController _controller;
|
|
146
|
+
late final Animation<double> _iconTurns;
|
|
147
|
+
late final Animation<double> _heightFactor;
|
|
148
|
+
|
|
149
|
+
@override
|
|
150
|
+
void initState() {
|
|
151
|
+
super.initState();
|
|
152
|
+
_controller = AnimationController(
|
|
153
|
+
duration: const Duration(milliseconds: 250),
|
|
154
|
+
vsync: this,
|
|
155
|
+
);
|
|
156
|
+
_iconTurns = Tween<double>(begin: 0.0, end: 0.5).animate(
|
|
157
|
+
CurvedAnimation(parent: _controller, curve: Curves.easeInOut),
|
|
158
|
+
);
|
|
159
|
+
_heightFactor = CurvedAnimation(
|
|
160
|
+
parent: _controller,
|
|
161
|
+
curve: Curves.easeInOut,
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
@override
|
|
166
|
+
void dispose() {
|
|
167
|
+
_controller.dispose();
|
|
168
|
+
super.dispose();
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
void _toggle() {
|
|
172
|
+
setState(() {
|
|
173
|
+
_isExpanded = !_isExpanded;
|
|
174
|
+
if (_isExpanded) {
|
|
175
|
+
_controller.forward();
|
|
176
|
+
} else {
|
|
177
|
+
_controller.reverse();
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
@override
|
|
183
|
+
Widget build(BuildContext context) {
|
|
184
|
+
final theme = Theme.of(context);
|
|
185
|
+
return Card(
|
|
186
|
+
color: theme.cardColor,
|
|
187
|
+
clipBehavior: Clip.antiAlias,
|
|
188
|
+
child: InkWell(
|
|
189
|
+
onTap: _toggle,
|
|
190
|
+
child: Padding(
|
|
191
|
+
padding: const EdgeInsets.all(16),
|
|
192
|
+
child: Column(
|
|
193
|
+
crossAxisAlignment: CrossAxisAlignment.start,
|
|
194
|
+
children: [
|
|
195
|
+
Row(
|
|
196
|
+
children: [
|
|
197
|
+
Expanded(
|
|
198
|
+
child: Text(
|
|
199
|
+
widget.title,
|
|
200
|
+
style: theme.textTheme.titleMedium,
|
|
201
|
+
),
|
|
202
|
+
),
|
|
203
|
+
RotationTransition(
|
|
204
|
+
turns: _iconTurns,
|
|
205
|
+
child: const Icon(Icons.expand_more),
|
|
206
|
+
),
|
|
207
|
+
],
|
|
208
|
+
),
|
|
209
|
+
const SizedBox(height: 8),
|
|
210
|
+
Text(
|
|
211
|
+
_isExpanded ? widget.fullContent : widget.preview,
|
|
212
|
+
style: theme.textTheme.bodyMedium?.copyWith(
|
|
213
|
+
color: theme.colorScheme.onSurface.withOpacity(0.7),
|
|
214
|
+
),
|
|
215
|
+
),
|
|
216
|
+
ClipRect(
|
|
217
|
+
child: Align(
|
|
218
|
+
heightFactor: _isExpanded ? null : 0,
|
|
219
|
+
child: const SizedBox.shrink(),
|
|
220
|
+
),
|
|
221
|
+
),
|
|
222
|
+
],
|
|
223
|
+
),
|
|
224
|
+
),
|
|
225
|
+
),
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
USAGE EXAMPLE:
|
|
232
|
+
```dart
|
|
233
|
+
ExpandableCard(
|
|
234
|
+
title: 'Release Notes v3.0',
|
|
235
|
+
preview: 'This release includes performance improvements...',
|
|
236
|
+
fullContent: 'Full release notes go here. This can be a long string '
|
|
237
|
+
'with multiple lines of content that is revealed when expanded.',
|
|
238
|
+
)
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
ACCESSIBILITY NOTES:
|
|
242
|
+
- `InkWell` provides tap feedback and is reachable by TalkBack/VoiceOver.
|
|
243
|
+
- Consider wrapping in `Semantics(button: true, label: '${widget.title}, ${_isExpanded ? "expanded" : "collapsed"}')` for screen readers.
|
|
244
|
+
- Touch target meets the 48×48dp minimum via Card padding.
|
|
245
|
+
|
|
246
|
+
THEMING NOTES:
|
|
247
|
+
- Background uses `Theme.of(context).cardColor` — adapts to light/dark automatically.
|
|
248
|
+
- Text uses `theme.textTheme.titleMedium` and `bodyMedium` — responds to text scale.
|
|
249
|
+
- Icon color inherits from `IconTheme` — no hardcoded color.
|
|
250
|
+
|
|
251
|
+
KNOWN LIMITATIONS:
|
|
252
|
+
- The preview text is shown as static string — no ellipsis truncation applied.
|
|
253
|
+
- No i18n support for the expand/collapse semantics label.
|
|
254
|
+
- Animation does not respond to `AccessibilityFeatures.reduceMotion`.
|
|
255
|
+
````
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## Notes
|
|
260
|
+
|
|
261
|
+
- For Riverpod state management, include `ref` as a parameter to `build()` and use `Consumer` or `ConsumerWidget`.
|
|
262
|
+
- For Bloc, specify which `Bloc` class and events the widget should listen to in `DESCRIPTION`.
|
|
263
|
+
- Complex animations (Hero, custom painter) may require additional context — describe them in detail.
|
|
264
|
+
- Tested with: Claude Sonnet 4.6, GPT-4o.
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Example Input — Flutter Widget Generator
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
FLUTTER_VERSION: 3.27
|
|
7
|
+
DART_VERSION: 3.6
|
|
8
|
+
STATE_MANAGEMENT: setState
|
|
9
|
+
WIDGET_TYPE: stateful
|
|
10
|
+
DESCRIPTION:
|
|
11
|
+
An expandable card widget that shows a title and a short preview of content.
|
|
12
|
+
When tapped, it smoothly expands to reveal the full content body. A chevron icon
|
|
13
|
+
on the right rotates 180 degrees when expanded. Uses the app's card color from Theme.
|
|
14
|
+
Should work in both light and dark mode. Receives: title (String), preview (String),
|
|
15
|
+
fullContent (String). No external packages needed.
|
|
16
|
+
CONTEXT:
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## What to Expect
|
|
22
|
+
|
|
23
|
+
See [`example-output.md`](example-output.md) for the complete Dart widget, usage example, and notes.
|
|
24
|
+
|
|
25
|
+
The agent generates:
|
|
26
|
+
- `ExpandableCard` — `StatefulWidget` with `SingleTickerProviderStateMixin`
|
|
27
|
+
- `AnimationController` + `RotationTransition` for the chevron
|
|
28
|
+
- `Theme.of(context)` for all colors and text styles
|
|
29
|
+
- `Semantics` for accessibility
|
|
30
|
+
- Usage example in a parent widget
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## Variations
|
|
35
|
+
|
|
36
|
+
### Loading button
|
|
37
|
+
```
|
|
38
|
+
FLUTTER_VERSION: 3.27
|
|
39
|
+
DART_VERSION: 3.6
|
|
40
|
+
STATE_MANAGEMENT: setState
|
|
41
|
+
WIDGET_TYPE: stateful
|
|
42
|
+
DESCRIPTION:
|
|
43
|
+
A button that shows a circular loading spinner while its async action runs.
|
|
44
|
+
Disabled (non-tappable) during loading. Normal FilledButton appearance otherwise.
|
|
45
|
+
Receives: label (String), onPressed (Future<void> Function()). No external packages.
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Pill badge chip
|
|
49
|
+
```
|
|
50
|
+
FLUTTER_VERSION: 3.27
|
|
51
|
+
DART_VERSION: 3.6
|
|
52
|
+
STATE_MANAGEMENT: setState
|
|
53
|
+
WIDGET_TYPE: stateful
|
|
54
|
+
DESCRIPTION:
|
|
55
|
+
A pill-shaped tag chip. Background is primaryContainer color, text is onPrimaryContainer.
|
|
56
|
+
Tapping toggles selected/unselected (filled vs outlined). Optional remove button (×)
|
|
57
|
+
that fades in with 200ms when selected. Receives: label, isSelected, onToggle, onRemove (nullable).
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Shimmer loading placeholder
|
|
61
|
+
```
|
|
62
|
+
FLUTTER_VERSION: 3.27
|
|
63
|
+
DART_VERSION: 3.6
|
|
64
|
+
STATE_MANAGEMENT: setState
|
|
65
|
+
WIDGET_TYPE: stateful
|
|
66
|
+
DESCRIPTION:
|
|
67
|
+
A shimmer loading placeholder for a list card. Shows animated horizontal gradient
|
|
68
|
+
sweeping left-to-right repeatedly. Contains a circle placeholder (for avatar, 48dp)
|
|
69
|
+
and two rectangle placeholders (for title and subtitle lines). Uses surfaceVariant color.
|
|
70
|
+
No external packages — implement shimmer with AnimationController and LinearGradient.
|
|
71
|
+
```
|