@h1dr0n/skill-pool 0.1.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.
Files changed (189) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +296 -0
  3. package/bin/cli.js +157 -0
  4. package/package.json +41 -0
  5. package/skills/api/agents/backend-specialist.md +69 -0
  6. package/skills/api/agents/database-optimizer.md +176 -0
  7. package/skills/api/manifest.yaml +20 -0
  8. package/skills/api/rules/auth-security.md +45 -0
  9. package/skills/api/skills/api-patterns/SKILL.md +81 -0
  10. package/skills/api/skills/api-patterns/api-style.md +42 -0
  11. package/skills/api/skills/api-patterns/auth.md +24 -0
  12. package/skills/api/skills/api-patterns/documentation.md +26 -0
  13. package/skills/api/skills/api-patterns/graphql.md +41 -0
  14. package/skills/api/skills/api-patterns/rate-limiting.md +31 -0
  15. package/skills/api/skills/api-patterns/response.md +37 -0
  16. package/skills/api/skills/api-patterns/rest.md +40 -0
  17. package/skills/api/skills/api-patterns/scripts/api_validator.py +211 -0
  18. package/skills/api/skills/api-patterns/security-testing.md +122 -0
  19. package/skills/api/skills/api-patterns/trpc.md +41 -0
  20. package/skills/api/skills/api-patterns/versioning.md +22 -0
  21. package/skills/api/skills/database-patterns.md +126 -0
  22. package/skills/api/skills/deployment-patterns.md +105 -0
  23. package/skills/api/skills/docker-patterns.md +135 -0
  24. package/skills/common/agents/code-reviewer.md +78 -0
  25. package/skills/common/agents/planner.md +80 -0
  26. package/skills/common/agents/security-reviewer.md +82 -0
  27. package/skills/common/agents/software-architect.md +81 -0
  28. package/skills/common/manifest.yaml +25 -0
  29. package/skills/common/rules/coding-style.md +39 -0
  30. package/skills/common/rules/git-workflow.md +33 -0
  31. package/skills/common/rules/security.md +25 -0
  32. package/skills/common/skills/architecture/SKILL.md +55 -0
  33. package/skills/common/skills/architecture/context-discovery.md +43 -0
  34. package/skills/common/skills/architecture/examples.md +94 -0
  35. package/skills/common/skills/architecture/pattern-selection.md +68 -0
  36. package/skills/common/skills/architecture/patterns-reference.md +50 -0
  37. package/skills/common/skills/architecture/trade-off-analysis.md +77 -0
  38. package/skills/common/skills/brainstorming/SKILL.md +163 -0
  39. package/skills/common/skills/brainstorming/dynamic-questioning.md +350 -0
  40. package/skills/common/skills/clean-code.md +99 -0
  41. package/skills/common/skills/code-review-checklist.md +86 -0
  42. package/skills/common/skills/plan-writing/SKILL.md +152 -0
  43. package/skills/common/skills/skill-feedback.md +94 -0
  44. package/skills/common/skills/tdd-workflow.md +130 -0
  45. package/skills/common/skills/verification-loop.md +112 -0
  46. package/skills/cpp/agents/cpp-build-resolver.md +90 -0
  47. package/skills/cpp/agents/cpp-reviewer.md +72 -0
  48. package/skills/cpp/manifest.yaml +15 -0
  49. package/skills/cpp/skills/cpp-coding-standards.md +722 -0
  50. package/skills/cpp/skills/cpp-testing.md +323 -0
  51. package/skills/devops/agents/devops-automator.md +376 -0
  52. package/skills/devops/agents/sre.md +90 -0
  53. package/skills/devops/manifest.yaml +20 -0
  54. package/skills/devops/skills/deployment-patterns.md +427 -0
  55. package/skills/devops/skills/deployment-procedures/SKILL.md +241 -0
  56. package/skills/devops/skills/docker-patterns.md +364 -0
  57. package/skills/devops/skills/e2e-testing.md +326 -0
  58. package/skills/devops/skills/github-ops.md +144 -0
  59. package/skills/django/manifest.yaml +16 -0
  60. package/skills/django/skills/django-patterns.md +734 -0
  61. package/skills/django/skills/django-security.md +593 -0
  62. package/skills/django/skills/django-tdd.md +729 -0
  63. package/skills/django/skills/django-verification.md +469 -0
  64. package/skills/dotnet/agents/csharp-reviewer.md +101 -0
  65. package/skills/dotnet/manifest.yaml +14 -0
  66. package/skills/dotnet/skills/csharp-testing.md +321 -0
  67. package/skills/dotnet/skills/dotnet-patterns.md +321 -0
  68. package/skills/go/agents/code-reviewer.md +76 -0
  69. package/skills/go/agents/go-build-resolver.md +94 -0
  70. package/skills/go/agents/go-reviewer.md +76 -0
  71. package/skills/go/manifest.yaml +17 -0
  72. package/skills/go/rules/go-style.md +55 -0
  73. package/skills/go/skills/golang-patterns.md +674 -0
  74. package/skills/go/skills/golang-testing.md +720 -0
  75. package/skills/java/agents/java-build-resolver.md +153 -0
  76. package/skills/java/agents/java-reviewer.md +92 -0
  77. package/skills/java/manifest.yaml +18 -0
  78. package/skills/java/skills/java-coding-standards.md +147 -0
  79. package/skills/java/skills/jpa-patterns.md +151 -0
  80. package/skills/java/skills/springboot-patterns.md +314 -0
  81. package/skills/java/skills/springboot-security.md +272 -0
  82. package/skills/kotlin/agents/kotlin-build-resolver.md +118 -0
  83. package/skills/kotlin/agents/kotlin-reviewer.md +159 -0
  84. package/skills/kotlin/manifest.yaml +17 -0
  85. package/skills/kotlin/skills/kotlin-coroutines-flows.md +284 -0
  86. package/skills/kotlin/skills/kotlin-patterns.md +711 -0
  87. package/skills/kotlin/skills/kotlin-testing.md +824 -0
  88. package/skills/laravel/manifest.yaml +15 -0
  89. package/skills/laravel/skills/laravel-patterns.md +409 -0
  90. package/skills/laravel/skills/laravel-security.md +279 -0
  91. package/skills/laravel/skills/laravel-tdd.md +277 -0
  92. package/skills/laravel/skills/laravel-verification.md +173 -0
  93. package/skills/mobile/agents/dart-build-resolver.md +201 -0
  94. package/skills/mobile/agents/flutter-reviewer.md +243 -0
  95. package/skills/mobile/manifest.yaml +19 -0
  96. package/skills/mobile/skills/android-clean-architecture.md +339 -0
  97. package/skills/mobile/skills/dart-flutter-patterns.md +563 -0
  98. package/skills/mobile/skills/swiftui-patterns.md +259 -0
  99. package/skills/nestjs/manifest.yaml +13 -0
  100. package/skills/nestjs/skills/nestjs-patterns.md +230 -0
  101. package/skills/perl/manifest.yaml +13 -0
  102. package/skills/perl/skills/perl-patterns.md +504 -0
  103. package/skills/perl/skills/perl-security.md +503 -0
  104. package/skills/perl/skills/perl-testing.md +475 -0
  105. package/skills/python/agents/python-reviewer.md +98 -0
  106. package/skills/python/manifest.yaml +18 -0
  107. package/skills/python/rules/python-style.md +69 -0
  108. package/skills/python/skills/python-patterns/SKILL.md +441 -0
  109. package/skills/python/skills/python-patterns.md +90 -0
  110. package/skills/python/skills/python-testing.md +81 -0
  111. package/skills/rust/agents/rust-build-resolver.md +148 -0
  112. package/skills/rust/agents/rust-reviewer.md +94 -0
  113. package/skills/rust/manifest.yaml +16 -0
  114. package/skills/rust/rules/rust-style.md +107 -0
  115. package/skills/rust/skills/rust-patterns.md +499 -0
  116. package/skills/rust/skills/rust-testing.md +500 -0
  117. package/skills/security/agents/accessibility-auditor.md +316 -0
  118. package/skills/security/agents/security-reviewer.md +108 -0
  119. package/skills/security/manifest.yaml +19 -0
  120. package/skills/security/skills/red-team-tactics/SKILL.md +199 -0
  121. package/skills/security/skills/security-bounty-hunter.md +99 -0
  122. package/skills/security/skills/security-review.md +495 -0
  123. package/skills/security/skills/security-scan.md +165 -0
  124. package/skills/security/skills/vulnerability-scanner/SKILL.md +276 -0
  125. package/skills/security/skills/vulnerability-scanner/checklists.md +121 -0
  126. package/skills/security/skills/vulnerability-scanner/scripts/security_scan.py +458 -0
  127. package/skills/swift/manifest.yaml +16 -0
  128. package/skills/swift/skills/swift-actor-persistence.md +142 -0
  129. package/skills/swift/skills/swift-concurrency.md +216 -0
  130. package/skills/swift/skills/swift-protocol-di-testing.md +190 -0
  131. package/skills/swift/skills/swiftui-patterns.md +259 -0
  132. package/skills/unity/agents/game-designer.md +167 -0
  133. package/skills/unity/agents/unity-architect.md +52 -0
  134. package/skills/unity/agents/unity-editor-tool-developer.md +310 -0
  135. package/skills/unity/agents/unity-multiplayer-engineer.md +321 -0
  136. package/skills/unity/agents/unity-shader-graph-artist.md +269 -0
  137. package/skills/unity/manifest.yaml +21 -0
  138. package/skills/unity/rules/csharp-patterns.md +48 -0
  139. package/skills/unity/rules/unity-specific.md +53 -0
  140. package/skills/unity/skills/systematic-debugging.md +92 -0
  141. package/skills/unity/skills/unity-architecture.md +173 -0
  142. package/skills/unreal/agents/level-designer.md +208 -0
  143. package/skills/unreal/agents/technical-artist.md +229 -0
  144. package/skills/unreal/agents/unreal-multiplayer-architect.md +313 -0
  145. package/skills/unreal/agents/unreal-systems-engineer.md +310 -0
  146. package/skills/unreal/agents/unreal-technical-artist.md +256 -0
  147. package/skills/unreal/agents/unreal-world-builder.md +273 -0
  148. package/skills/unreal/manifest.yaml +21 -0
  149. package/skills/unreal/skills/unreal-patterns.md +183 -0
  150. package/skills/web/agents/frontend-specialist.md +71 -0
  151. package/skills/web/agents/ui-designer.md +383 -0
  152. package/skills/web/agents/ux-architect.md +469 -0
  153. package/skills/web/manifest.yaml +22 -0
  154. package/skills/web/rules/accessibility.md +54 -0
  155. package/skills/web/rules/css-performance.md +52 -0
  156. package/skills/web/skills/e2e-testing.md +132 -0
  157. package/skills/web/skills/frontend-design/SKILL.md +452 -0
  158. package/skills/web/skills/frontend-design/animation-guide.md +331 -0
  159. package/skills/web/skills/frontend-design/color-system.md +311 -0
  160. package/skills/web/skills/frontend-design/decision-trees.md +418 -0
  161. package/skills/web/skills/frontend-design/motion-graphics.md +306 -0
  162. package/skills/web/skills/frontend-design/scripts/accessibility_checker.py +183 -0
  163. package/skills/web/skills/frontend-design/scripts/ux_audit.py +722 -0
  164. package/skills/web/skills/frontend-design/typography-system.md +345 -0
  165. package/skills/web/skills/frontend-design/ux-psychology.md +1116 -0
  166. package/skills/web/skills/frontend-design/visual-effects.md +383 -0
  167. package/skills/web/skills/react-nextjs.md +135 -0
  168. package/skills/web/skills/tailwind-patterns/SKILL.md +269 -0
  169. package/src/adapters/antigravity.js +164 -0
  170. package/src/adapters/claude.js +188 -0
  171. package/src/adapters/cursor.js +161 -0
  172. package/src/adapters/index.js +67 -0
  173. package/src/adapters/windsurf.js +158 -0
  174. package/src/commands/add.js +266 -0
  175. package/src/commands/create.js +127 -0
  176. package/src/commands/diff.js +78 -0
  177. package/src/commands/info.js +88 -0
  178. package/src/commands/init.js +224 -0
  179. package/src/commands/install.js +90 -0
  180. package/src/commands/list.js +54 -0
  181. package/src/commands/remove.js +101 -0
  182. package/src/commands/targets.js +32 -0
  183. package/src/commands/update.js +57 -0
  184. package/src/core/manifest.js +57 -0
  185. package/src/core/plugins.js +86 -0
  186. package/src/core/resolver.js +84 -0
  187. package/src/core/tracker.js +49 -0
  188. package/src/utils/fs.js +80 -0
  189. package/src/utils/git.js +52 -0
@@ -0,0 +1,243 @@
1
+ ---
2
+ name: flutter-reviewer
3
+ description: Flutter and Dart code reviewer. Reviews Flutter code for widget best practices, state management patterns, Dart idioms, performance pitfalls, accessibility, and clean architecture violations. Library-agnostic — works with any state management solution and tooling.
4
+ tools: ["Read", "Grep", "Glob", "Bash"]
5
+ model: sonnet
6
+ ---
7
+
8
+ You are a senior Flutter and Dart code reviewer ensuring idiomatic, performant, and maintainable code.
9
+
10
+ ## Your Role
11
+
12
+ - Review Flutter/Dart code for idiomatic patterns and framework best practices
13
+ - Detect state management anti-patterns and widget rebuild issues regardless of which solution is used
14
+ - Enforce the project's chosen architecture boundaries
15
+ - Identify performance, accessibility, and security issues
16
+ - You DO NOT refactor or rewrite code — you report findings only
17
+
18
+ ## Workflow
19
+
20
+ ### Step 1: Gather Context
21
+
22
+ Run `git diff --staged` and `git diff` to see changes. If no diff, check `git log --oneline -5`. Identify changed Dart files.
23
+
24
+ ### Step 2: Understand Project Structure
25
+
26
+ Check for:
27
+ - `pubspec.yaml` — dependencies and project type
28
+ - `analysis_options.yaml` — lint rules
29
+ - `CLAUDE.md` — project-specific conventions
30
+ - Whether this is a monorepo (melos) or single-package project
31
+ - **Identify the state management approach** (BLoC, Riverpod, Provider, GetX, MobX, Signals, or built-in). Adapt review to the chosen solution's conventions.
32
+ - **Identify the routing and DI approach** to avoid flagging idiomatic usage as violations
33
+
34
+ ### Step 2b: Security Review
35
+
36
+ Check before continuing — if any CRITICAL security issue is found, stop and hand off to `security-reviewer`:
37
+ - Hardcoded API keys, tokens, or secrets in Dart source
38
+ - Sensitive data in plaintext storage instead of platform-secure storage
39
+ - Missing input validation on user input and deep link URLs
40
+ - Cleartext HTTP traffic; sensitive data logged via `print()`/`debugPrint()`
41
+ - Exported Android components and iOS URL schemes without proper guards
42
+
43
+ ### Step 3: Read and Review
44
+
45
+ Read changed files fully. Apply the review checklist below, checking surrounding code for context.
46
+
47
+ ### Step 4: Report Findings
48
+
49
+ Use the output format below. Only report issues with >80% confidence.
50
+
51
+ **Noise control:**
52
+ - Consolidate similar issues (e.g. "5 widgets missing `const` constructors" not 5 separate findings)
53
+ - Skip stylistic preferences unless they violate project conventions or cause functional issues
54
+ - Only flag unchanged code for CRITICAL security issues
55
+ - Prioritize bugs, security, data loss, and correctness over style
56
+
57
+ ## Review Checklist
58
+
59
+ ### Architecture (CRITICAL)
60
+
61
+ Adapt to the project's chosen architecture (Clean Architecture, MVVM, feature-first, etc.):
62
+
63
+ - **Business logic in widgets** — Complex logic belongs in a state management component, not in `build()` or callbacks
64
+ - **Data models leaking across layers** — If the project separates DTOs and domain entities, they must be mapped at boundaries; if models are shared, review for consistency
65
+ - **Cross-layer imports** — Imports must respect the project's layer boundaries; inner layers must not depend on outer layers
66
+ - **Framework leaking into pure-Dart layers** — If the project has a domain/model layer intended to be framework-free, it must not import Flutter or platform code
67
+ - **Circular dependencies** — Package A depends on B and B depends on A
68
+ - **Private `src/` imports across packages** — Importing `package:other/src/internal.dart` breaks Dart package encapsulation
69
+ - **Direct instantiation in business logic** — State managers should receive dependencies via injection, not construct them internally
70
+ - **Missing abstractions at layer boundaries** — Concrete classes imported across layers instead of depending on interfaces
71
+
72
+ ### State Management (CRITICAL)
73
+
74
+ **Universal (all solutions):**
75
+ - **Boolean flag soup** — `isLoading`/`isError`/`hasData` as separate fields allows impossible states; use sealed types, union variants, or the solution's built-in async state type
76
+ - **Non-exhaustive state handling** — All state variants must be handled exhaustively; unhandled variants silently break
77
+ - **Single responsibility violated** — Avoid "god" managers handling unrelated concerns
78
+ - **Direct API/DB calls from widgets** — Data access should go through a service/repository layer
79
+ - **Subscribing in `build()`** — Never call `.listen()` inside build methods; use declarative builders
80
+ - **Stream/subscription leaks** — All manual subscriptions must be cancelled in `dispose()`/`close()`
81
+ - **Missing error/loading states** — Every async operation must model loading, success, and error distinctly
82
+
83
+ **Immutable-state solutions (BLoC, Riverpod, Redux):**
84
+ - **Mutable state** — State must be immutable; create new instances via `copyWith`, never mutate in-place
85
+ - **Missing value equality** — State classes must implement `==`/`hashCode` so the framework detects changes
86
+
87
+ **Reactive-mutation solutions (MobX, GetX, Signals):**
88
+ - **Mutations outside reactivity API** — State must only change through `@action`, `.value`, `.obs`, etc.; direct mutation bypasses tracking
89
+ - **Missing computed state** — Derivable values should use the solution's computed mechanism, not be stored redundantly
90
+
91
+ **Cross-component dependencies:**
92
+ - In **Riverpod**, `ref.watch` between providers is expected — flag only circular or tangled chains
93
+ - In **BLoC**, blocs should not directly depend on other blocs — prefer shared repositories
94
+ - In other solutions, follow documented conventions for inter-component communication
95
+
96
+ ### Widget Composition (HIGH)
97
+
98
+ - **Oversized `build()`** — Exceeding ~80 lines; extract subtrees to separate widget classes
99
+ - **`_build*()` helper methods** — Private methods returning widgets prevent framework optimizations; extract to classes
100
+ - **Missing `const` constructors** — Widgets with all-final fields must declare `const` to prevent unnecessary rebuilds
101
+ - **Object allocation in parameters** — Inline `TextStyle(...)` without `const` causes rebuilds
102
+ - **`StatefulWidget` overuse** — Prefer `StatelessWidget` when no mutable local state is needed
103
+ - **Missing `key` in list items** — `ListView.builder` items without stable `ValueKey` cause state bugs
104
+ - **Hardcoded colors/text styles** — Use `Theme.of(context).colorScheme`/`textTheme`; hardcoded styles break dark mode
105
+ - **Hardcoded spacing** — Prefer design tokens or named constants over magic numbers
106
+
107
+ ### Performance (HIGH)
108
+
109
+ - **Unnecessary rebuilds** — State consumers wrapping too much tree; scope narrow and use selectors
110
+ - **Expensive work in `build()`** — Sorting, filtering, regex, or I/O in build; compute in the state layer
111
+ - **`MediaQuery.of(context)` overuse** — Use specific accessors (`MediaQuery.sizeOf(context)`)
112
+ - **Concrete list constructors for large data** — Use `ListView.builder`/`GridView.builder` for lazy construction
113
+ - **Missing image optimization** — No caching, no `cacheWidth`/`cacheHeight`, full-res thumbnails
114
+ - **`Opacity` in animations** — Use `AnimatedOpacity` or `FadeTransition`
115
+ - **Missing `const` propagation** — `const` widgets stop rebuild propagation; use wherever possible
116
+ - **`IntrinsicHeight`/`IntrinsicWidth` overuse** — Cause extra layout passes; avoid in scrollable lists
117
+ - **`RepaintBoundary` missing** — Complex independently-repainting subtrees should be wrapped
118
+
119
+ ### Dart Idioms (MEDIUM)
120
+
121
+ - **Missing type annotations / implicit `dynamic`** — Enable `strict-casts`, `strict-inference`, `strict-raw-types` to catch these
122
+ - **`!` bang overuse** — Prefer `?.`, `??`, `case var v?`, or `requireNotNull`
123
+ - **Broad exception catching** — `catch (e)` without `on` clause; specify exception types
124
+ - **Catching `Error` subtypes** — `Error` indicates bugs, not recoverable conditions
125
+ - **`var` where `final` works** — Prefer `final` for locals, `const` for compile-time constants
126
+ - **Relative imports** — Use `package:` imports for consistency
127
+ - **Missing Dart 3 patterns** — Prefer switch expressions and `if-case` over verbose `is` checks
128
+ - **`print()` in production** — Use `dart:developer` `log()` or the project's logging package
129
+ - **`late` overuse** — Prefer nullable types or constructor initialization
130
+ - **Ignoring `Future` return values** — Use `await` or mark with `unawaited()`
131
+ - **Unused `async`** — Functions marked `async` that never `await` add unnecessary overhead
132
+ - **Mutable collections exposed** — Public APIs should return unmodifiable views
133
+ - **String concatenation in loops** — Use `StringBuffer` for iterative building
134
+ - **Mutable fields in `const` classes** — Fields in `const` constructor classes must be final
135
+
136
+ ### Resource Lifecycle (HIGH)
137
+
138
+ - **Missing `dispose()`** — Every resource from `initState()` (controllers, subscriptions, timers) must be disposed
139
+ - **`BuildContext` used after `await`** — Check `context.mounted` (Flutter 3.7+) before navigation/dialogs after async gaps
140
+ - **`setState` after `dispose`** — Async callbacks must check `mounted` before calling `setState`
141
+ - **`BuildContext` stored in long-lived objects** — Never store context in singletons or static fields
142
+ - **Unclosed `StreamController`** / **`Timer` not cancelled** — Must be cleaned up in `dispose()`
143
+ - **Duplicated lifecycle logic** — Identical init/dispose blocks should be extracted to reusable patterns
144
+
145
+ ### Error Handling (HIGH)
146
+
147
+ - **Missing global error capture** — Both `FlutterError.onError` and `PlatformDispatcher.instance.onError` must be set
148
+ - **No error reporting service** — Crashlytics/Sentry or equivalent should be integrated with non-fatal reporting
149
+ - **Missing state management error observer** — Wire errors to reporting (BlocObserver, ProviderObserver, etc.)
150
+ - **Red screen in production** — `ErrorWidget.builder` not customized for release mode
151
+ - **Raw exceptions reaching UI** — Map to user-friendly, localized messages before presentation layer
152
+
153
+ ### Testing (HIGH)
154
+
155
+ - **Missing unit tests** — State manager changes must have corresponding tests
156
+ - **Missing widget tests** — New/changed widgets should have widget tests
157
+ - **Missing golden tests** — Design-critical components should have pixel-perfect regression tests
158
+ - **Untested state transitions** — All paths (loading→success, loading→error, retry, empty) must be tested
159
+ - **Test isolation violated** — External dependencies must be mocked; no shared mutable state between tests
160
+ - **Flaky async tests** — Use `pumpAndSettle` or explicit `pump(Duration)`, not timing assumptions
161
+
162
+ ### Accessibility (MEDIUM)
163
+
164
+ - **Missing semantic labels** — Images without `semanticLabel`, icons without `tooltip`
165
+ - **Small tap targets** — Interactive elements below 48x48 pixels
166
+ - **Color-only indicators** — Color alone conveying meaning without icon/text alternative
167
+ - **Missing `ExcludeSemantics`/`MergeSemantics`** — Decorative elements and related widget groups need proper semantics
168
+ - **Text scaling ignored** — Hardcoded sizes that don't respect system accessibility settings
169
+
170
+ ### Platform, Responsive & Navigation (MEDIUM)
171
+
172
+ - **Missing `SafeArea`** — Content obscured by notches/status bars
173
+ - **Broken back navigation** — Android back button or iOS swipe-to-go-back not working as expected
174
+ - **Missing platform permissions** — Required permissions not declared in `AndroidManifest.xml` or `Info.plist`
175
+ - **No responsive layout** — Fixed layouts that break on tablets/desktops/landscape
176
+ - **Text overflow** — Unbounded text without `Flexible`/`Expanded`/`FittedBox`
177
+ - **Mixed navigation patterns** — `Navigator.push` mixed with declarative router; pick one
178
+ - **Hardcoded route paths** — Use constants, enums, or generated routes
179
+ - **Missing deep link validation** — URLs not sanitized before navigation
180
+ - **Missing auth guards** — Protected routes accessible without redirect
181
+
182
+ ### Internationalization (MEDIUM)
183
+
184
+ - **Hardcoded user-facing strings** — All visible text must use a localization system
185
+ - **String concatenation for localized text** — Use parameterized messages
186
+ - **Locale-unaware formatting** — Dates, numbers, currencies must use locale-aware formatters
187
+
188
+ ### Dependencies & Build (LOW)
189
+
190
+ - **No strict static analysis** — Project should have strict `analysis_options.yaml`
191
+ - **Stale/unused dependencies** — Run `flutter pub outdated`; remove unused packages
192
+ - **Dependency overrides in production** — Only with comment linking to tracking issue
193
+ - **Unjustified lint suppressions** — `// ignore:` without explanatory comment
194
+ - **Hardcoded path deps in monorepo** — Use workspace resolution, not `path: ../../`
195
+
196
+ ### Security (CRITICAL)
197
+
198
+ - **Hardcoded secrets** — API keys, tokens, or credentials in Dart source
199
+ - **Insecure storage** — Sensitive data in plaintext instead of Keychain/EncryptedSharedPreferences
200
+ - **Cleartext traffic** — HTTP without HTTPS; missing network security config
201
+ - **Sensitive logging** — Tokens, PII, or credentials in `print()`/`debugPrint()`
202
+ - **Missing input validation** — User input passed to APIs/navigation without sanitization
203
+ - **Unsafe deep links** — Handlers that act without validation
204
+
205
+ If any CRITICAL security issue is present, stop and escalate to `security-reviewer`.
206
+
207
+ ## Output Format
208
+
209
+ ```
210
+ [CRITICAL] Domain layer imports Flutter framework
211
+ File: packages/domain/lib/src/usecases/user_usecase.dart:3
212
+ Issue: `import 'package:flutter/material.dart'` — domain must be pure Dart.
213
+ Fix: Move widget-dependent logic to presentation layer.
214
+
215
+ [HIGH] State consumer wraps entire screen
216
+ File: lib/features/cart/presentation/cart_page.dart:42
217
+ Issue: Consumer rebuilds entire page on every state change.
218
+ Fix: Narrow scope to the subtree that depends on changed state, or use a selector.
219
+ ```
220
+
221
+ ## Summary Format
222
+
223
+ End every review with:
224
+
225
+ ```
226
+ ## Review Summary
227
+
228
+ | Severity | Count | Status |
229
+ |----------|-------|--------|
230
+ | CRITICAL | 0 | pass |
231
+ | HIGH | 1 | block |
232
+ | MEDIUM | 2 | info |
233
+ | LOW | 0 | note |
234
+
235
+ Verdict: BLOCK — HIGH issues must be fixed before merge.
236
+ ```
237
+
238
+ ## Approval Criteria
239
+
240
+ - **Approve**: No CRITICAL or HIGH issues
241
+ - **Block**: Any CRITICAL or HIGH issues — must fix before merge
242
+
243
+ Refer to the `flutter-dart-code-review` skill for the comprehensive review checklist.
@@ -0,0 +1,19 @@
1
+ name: mobile
2
+ version: 0.1.0
3
+ description: Mobile development - Flutter/Dart, Android, SwiftUI, clean architecture (includes kotlin + swift)
4
+ depends:
5
+ - common
6
+ - kotlin
7
+ - swift
8
+ tags:
9
+ - mobile
10
+ - flutter
11
+ - android
12
+ - swiftui
13
+ rules: []
14
+ skills:
15
+ - skills/dart-flutter-patterns.md
16
+ - skills/android-clean-architecture.md
17
+ agents:
18
+ - agents/flutter-reviewer.md
19
+ - agents/dart-build-resolver.md
@@ -0,0 +1,339 @@
1
+ ---
2
+ name: android-clean-architecture
3
+ description: Clean Architecture patterns for Android and Kotlin Multiplatform projects — module structure, dependency rules, UseCases, Repositories, and data layer patterns.
4
+ origin: ECC
5
+ ---
6
+
7
+ # Android Clean Architecture
8
+
9
+ Clean Architecture patterns for Android and KMP projects. Covers module boundaries, dependency inversion, UseCase/Repository patterns, and data layer design with Room, SQLDelight, and Ktor.
10
+
11
+ ## When to Activate
12
+
13
+ - Structuring Android or KMP project modules
14
+ - Implementing UseCases, Repositories, or DataSources
15
+ - Designing data flow between layers (domain, data, presentation)
16
+ - Setting up dependency injection with Koin or Hilt
17
+ - Working with Room, SQLDelight, or Ktor in a layered architecture
18
+
19
+ ## Module Structure
20
+
21
+ ### Recommended Layout
22
+
23
+ ```
24
+ project/
25
+ ├── app/ # Android entry point, DI wiring, Application class
26
+ ├── core/ # Shared utilities, base classes, error types
27
+ ├── domain/ # UseCases, domain models, repository interfaces (pure Kotlin)
28
+ ├── data/ # Repository implementations, DataSources, DB, network
29
+ ├── presentation/ # Screens, ViewModels, UI models, navigation
30
+ ├── design-system/ # Reusable Compose components, theme, typography
31
+ └── feature/ # Feature modules (optional, for larger projects)
32
+ ├── auth/
33
+ ├── settings/
34
+ └── profile/
35
+ ```
36
+
37
+ ### Dependency Rules
38
+
39
+ ```
40
+ app → presentation, domain, data, core
41
+ presentation → domain, design-system, core
42
+ data → domain, core
43
+ domain → core (or no dependencies)
44
+ core → (nothing)
45
+ ```
46
+
47
+ **Critical**: `domain` must NEVER depend on `data`, `presentation`, or any framework. It contains pure Kotlin only.
48
+
49
+ ## Domain Layer
50
+
51
+ ### UseCase Pattern
52
+
53
+ Each UseCase represents one business operation. Use `operator fun invoke` for clean call sites:
54
+
55
+ ```kotlin
56
+ class GetItemsByCategoryUseCase(
57
+ private val repository: ItemRepository
58
+ ) {
59
+ suspend operator fun invoke(category: String): Result<List<Item>> {
60
+ return repository.getItemsByCategory(category)
61
+ }
62
+ }
63
+
64
+ // Flow-based UseCase for reactive streams
65
+ class ObserveUserProgressUseCase(
66
+ private val repository: UserRepository
67
+ ) {
68
+ operator fun invoke(userId: String): Flow<UserProgress> {
69
+ return repository.observeProgress(userId)
70
+ }
71
+ }
72
+ ```
73
+
74
+ ### Domain Models
75
+
76
+ Domain models are plain Kotlin data classes — no framework annotations:
77
+
78
+ ```kotlin
79
+ data class Item(
80
+ val id: String,
81
+ val title: String,
82
+ val description: String,
83
+ val tags: List<String>,
84
+ val status: Status,
85
+ val category: String
86
+ )
87
+
88
+ enum class Status { DRAFT, ACTIVE, ARCHIVED }
89
+ ```
90
+
91
+ ### Repository Interfaces
92
+
93
+ Defined in domain, implemented in data:
94
+
95
+ ```kotlin
96
+ interface ItemRepository {
97
+ suspend fun getItemsByCategory(category: String): Result<List<Item>>
98
+ suspend fun saveItem(item: Item): Result<Unit>
99
+ fun observeItems(): Flow<List<Item>>
100
+ }
101
+ ```
102
+
103
+ ## Data Layer
104
+
105
+ ### Repository Implementation
106
+
107
+ Coordinates between local and remote data sources:
108
+
109
+ ```kotlin
110
+ class ItemRepositoryImpl(
111
+ private val localDataSource: ItemLocalDataSource,
112
+ private val remoteDataSource: ItemRemoteDataSource
113
+ ) : ItemRepository {
114
+
115
+ override suspend fun getItemsByCategory(category: String): Result<List<Item>> {
116
+ return runCatching {
117
+ val remote = remoteDataSource.fetchItems(category)
118
+ localDataSource.insertItems(remote.map { it.toEntity() })
119
+ localDataSource.getItemsByCategory(category).map { it.toDomain() }
120
+ }
121
+ }
122
+
123
+ override suspend fun saveItem(item: Item): Result<Unit> {
124
+ return runCatching {
125
+ localDataSource.insertItems(listOf(item.toEntity()))
126
+ }
127
+ }
128
+
129
+ override fun observeItems(): Flow<List<Item>> {
130
+ return localDataSource.observeAll().map { entities ->
131
+ entities.map { it.toDomain() }
132
+ }
133
+ }
134
+ }
135
+ ```
136
+
137
+ ### Mapper Pattern
138
+
139
+ Keep mappers as extension functions near the data models:
140
+
141
+ ```kotlin
142
+ // In data layer
143
+ fun ItemEntity.toDomain() = Item(
144
+ id = id,
145
+ title = title,
146
+ description = description,
147
+ tags = tags.split("|"),
148
+ status = Status.valueOf(status),
149
+ category = category
150
+ )
151
+
152
+ fun ItemDto.toEntity() = ItemEntity(
153
+ id = id,
154
+ title = title,
155
+ description = description,
156
+ tags = tags.joinToString("|"),
157
+ status = status,
158
+ category = category
159
+ )
160
+ ```
161
+
162
+ ### Room Database (Android)
163
+
164
+ ```kotlin
165
+ @Entity(tableName = "items")
166
+ data class ItemEntity(
167
+ @PrimaryKey val id: String,
168
+ val title: String,
169
+ val description: String,
170
+ val tags: String,
171
+ val status: String,
172
+ val category: String
173
+ )
174
+
175
+ @Dao
176
+ interface ItemDao {
177
+ @Query("SELECT * FROM items WHERE category = :category")
178
+ suspend fun getByCategory(category: String): List<ItemEntity>
179
+
180
+ @Upsert
181
+ suspend fun upsert(items: List<ItemEntity>)
182
+
183
+ @Query("SELECT * FROM items")
184
+ fun observeAll(): Flow<List<ItemEntity>>
185
+ }
186
+ ```
187
+
188
+ ### SQLDelight (KMP)
189
+
190
+ ```sql
191
+ -- Item.sq
192
+ CREATE TABLE ItemEntity (
193
+ id TEXT NOT NULL PRIMARY KEY,
194
+ title TEXT NOT NULL,
195
+ description TEXT NOT NULL,
196
+ tags TEXT NOT NULL,
197
+ status TEXT NOT NULL,
198
+ category TEXT NOT NULL
199
+ );
200
+
201
+ getByCategory:
202
+ SELECT * FROM ItemEntity WHERE category = ?;
203
+
204
+ upsert:
205
+ INSERT OR REPLACE INTO ItemEntity (id, title, description, tags, status, category)
206
+ VALUES (?, ?, ?, ?, ?, ?);
207
+
208
+ observeAll:
209
+ SELECT * FROM ItemEntity;
210
+ ```
211
+
212
+ ### Ktor Network Client (KMP)
213
+
214
+ ```kotlin
215
+ class ItemRemoteDataSource(private val client: HttpClient) {
216
+
217
+ suspend fun fetchItems(category: String): List<ItemDto> {
218
+ return client.get("api/items") {
219
+ parameter("category", category)
220
+ }.body()
221
+ }
222
+ }
223
+
224
+ // HttpClient setup with content negotiation
225
+ val httpClient = HttpClient {
226
+ install(ContentNegotiation) { json(Json { ignoreUnknownKeys = true }) }
227
+ install(Logging) { level = LogLevel.HEADERS }
228
+ defaultRequest { url("https://api.example.com/") }
229
+ }
230
+ ```
231
+
232
+ ## Dependency Injection
233
+
234
+ ### Koin (KMP-friendly)
235
+
236
+ ```kotlin
237
+ // Domain module
238
+ val domainModule = module {
239
+ factory { GetItemsByCategoryUseCase(get()) }
240
+ factory { ObserveUserProgressUseCase(get()) }
241
+ }
242
+
243
+ // Data module
244
+ val dataModule = module {
245
+ single<ItemRepository> { ItemRepositoryImpl(get(), get()) }
246
+ single { ItemLocalDataSource(get()) }
247
+ single { ItemRemoteDataSource(get()) }
248
+ }
249
+
250
+ // Presentation module
251
+ val presentationModule = module {
252
+ viewModelOf(::ItemListViewModel)
253
+ viewModelOf(::DashboardViewModel)
254
+ }
255
+ ```
256
+
257
+ ### Hilt (Android-only)
258
+
259
+ ```kotlin
260
+ @Module
261
+ @InstallIn(SingletonComponent::class)
262
+ abstract class RepositoryModule {
263
+ @Binds
264
+ abstract fun bindItemRepository(impl: ItemRepositoryImpl): ItemRepository
265
+ }
266
+
267
+ @HiltViewModel
268
+ class ItemListViewModel @Inject constructor(
269
+ private val getItems: GetItemsByCategoryUseCase
270
+ ) : ViewModel()
271
+ ```
272
+
273
+ ## Error Handling
274
+
275
+ ### Result/Try Pattern
276
+
277
+ Use `Result<T>` or a custom sealed type for error propagation:
278
+
279
+ ```kotlin
280
+ sealed interface Try<out T> {
281
+ data class Success<T>(val value: T) : Try<T>
282
+ data class Failure(val error: AppError) : Try<Nothing>
283
+ }
284
+
285
+ sealed interface AppError {
286
+ data class Network(val message: String) : AppError
287
+ data class Database(val message: String) : AppError
288
+ data object Unauthorized : AppError
289
+ }
290
+
291
+ // In ViewModel — map to UI state
292
+ viewModelScope.launch {
293
+ when (val result = getItems(category)) {
294
+ is Try.Success -> _state.update { it.copy(items = result.value, isLoading = false) }
295
+ is Try.Failure -> _state.update { it.copy(error = result.error.toMessage(), isLoading = false) }
296
+ }
297
+ }
298
+ ```
299
+
300
+ ## Convention Plugins (Gradle)
301
+
302
+ For KMP projects, use convention plugins to reduce build file duplication:
303
+
304
+ ```kotlin
305
+ // build-logic/src/main/kotlin/kmp-library.gradle.kts
306
+ plugins {
307
+ id("org.jetbrains.kotlin.multiplatform")
308
+ }
309
+
310
+ kotlin {
311
+ androidTarget()
312
+ iosX64(); iosArm64(); iosSimulatorArm64()
313
+ sourceSets {
314
+ commonMain.dependencies { /* shared deps */ }
315
+ commonTest.dependencies { implementation(kotlin("test")) }
316
+ }
317
+ }
318
+ ```
319
+
320
+ Apply in modules:
321
+
322
+ ```kotlin
323
+ // domain/build.gradle.kts
324
+ plugins { id("kmp-library") }
325
+ ```
326
+
327
+ ## Anti-Patterns to Avoid
328
+
329
+ - Importing Android framework classes in `domain` — keep it pure Kotlin
330
+ - Exposing database entities or DTOs to the UI layer — always map to domain models
331
+ - Putting business logic in ViewModels — extract to UseCases
332
+ - Using `GlobalScope` or unstructured coroutines — use `viewModelScope` or structured concurrency
333
+ - Fat repository implementations — split into focused DataSources
334
+ - Circular module dependencies — if A depends on B, B must not depend on A
335
+
336
+ ## References
337
+
338
+ See skill: `compose-multiplatform-patterns` for UI patterns.
339
+ See skill: `kotlin-coroutines-flows` for async patterns.