@buivietphi/skill-mobile-mt 1.0.1 → 1.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.

Potentially problematic release.


This version of @buivietphi/skill-mobile-mt might be problematic. Click here for more details.

package/AGENTS.md CHANGED
@@ -53,6 +53,7 @@ skill-mobile-mt/
53
53
  ├── platform-excellence.md ← iOS 18+ vs Android 15+ UX (1,500 tokens)
54
54
  ├── version-management.md ← SDK compat matrix + release testing (3,500 tokens)
55
55
  ├── observability.md ← Sessions as 4th pillar (3,000 tokens)
56
+ ├── architecture-intelligence.md ← Patterns from 30+ production repos (4,500 tokens)
56
57
  ├── common-pitfalls.md ← Known issue patterns (1,160 tokens)
57
58
  ├── release-checklist.md ← App Store/Play Store checklist (587 tokens)
58
59
 
package/SKILL.md CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: skill-mobile-mt
3
- description: "Master Senior Mobile Engineer. Use when: building mobile features, fixing mobile bugs, reviewing mobile code, mobile architecture, React Native, Flutter, iOS Swift, Android Kotlin, mobile performance, mobile security audit, mobile code review, app release. Two modes: (1) default = pre-built production patterns, (2) 'project' = reads current project and adapts."
4
- version: "1.0.0"
3
+ description: "Master Senior Mobile Engineer. Patterns from 30+ production repos (200k+ GitHub stars: Ignite, Expensify, Mattermost, Immich, AppFlowy, Now in Android, TCA). Use when: building mobile features, fixing mobile bugs, reviewing mobile code, mobile architecture, React Native, Flutter, iOS Swift, Android Kotlin, mobile performance, mobile security audit, mobile code review, app release. Two modes: (1) default = pre-built production patterns, (2) 'project' = reads current project and adapts."
4
+ version: "1.1.0"
5
5
  author: buivietphi
6
6
  priority: high
7
7
  user-invocable: true
@@ -72,7 +72,9 @@ USER REQUEST → ACTION (Read tool required)
72
72
 
73
73
  "Add X to existing Y" → MODIFY existing files, don't create new structure
74
74
 
75
- "Setup project / architecture" → Read platform file first (see Smart Loading below)
75
+ "Setup project / architecture" → Read: shared/architecture-intelligence.md
76
+ then: Read platform file (see Smart Loading below)
77
+ then: suggest structure based on project size + stack
76
78
 
77
79
  "Fix / debug X" → Read: shared/bug-detection.md
78
80
  then: read code → find root cause → fix → verify
package/bin/install.mjs CHANGED
@@ -34,7 +34,7 @@ const SUBFOLDERS = {
34
34
  'flutter': ['flutter.md'],
35
35
  'ios': ['ios-native.md'],
36
36
  'android': ['android-native.md'],
37
- 'shared': ['code-review.md', 'bug-detection.md', 'prompt-engineering.md', 'release-checklist.md', 'common-pitfalls.md', 'error-recovery.md', 'document-analysis.md', 'anti-patterns.md', 'performance-prediction.md', 'platform-excellence.md', 'version-management.md', 'observability.md', 'claude-md-template.md', 'agent-rules-template.md'],
37
+ 'shared': ['code-review.md', 'bug-detection.md', 'prompt-engineering.md', 'release-checklist.md', 'common-pitfalls.md', 'error-recovery.md', 'document-analysis.md', 'anti-patterns.md', 'performance-prediction.md', 'platform-excellence.md', 'version-management.md', 'observability.md', 'architecture-intelligence.md', 'claude-md-template.md', 'agent-rules-template.md'],
38
38
  };
39
39
 
40
40
  const AGENTS = {
@@ -56,7 +56,7 @@ const fail = m => log(` ${c.red}✗${c.reset} ${m}`);
56
56
 
57
57
  function banner() {
58
58
  log(`\n${c.bold}${c.cyan} ┌──────────────────────────────────────────────┐`);
59
- log(` │ 📱 @buivietphi/skill-mobile-mt v1.0.1 │`);
59
+ log(` │ 📱 @buivietphi/skill-mobile-mt v1.1.0 │`);
60
60
  log(` │ Master Senior Mobile Engineer │`);
61
61
  log(` │ │`);
62
62
  log(` │ Claude · Codex · Gemini · Kimi │`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@buivietphi/skill-mobile-mt",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "description": "Master Senior Mobile Engineer skill for AI agents. Pre-built patterns from 18 production apps + local project adaptation. React Native, Flutter, iOS, Android. Supports Claude, Gemini, Kimi, Cursor, Copilot, Antigravity.",
5
5
  "author": "buivietphi",
6
6
  "license": "MIT",
@@ -0,0 +1,416 @@
1
+ # Architecture Intelligence — Patterns from 30+ Production Repos
2
+
3
+ > On-demand. Load when: "architecture", "structure", "setup project", "best practices", "how to organize"
4
+ > Source: Analyzed 30+ open-source production mobile apps (total 200k+ GitHub stars)
5
+
6
+ ---
7
+
8
+ ## Reference Repos (by platform)
9
+
10
+ | Platform | Repo | Stars | Key Pattern |
11
+ |----------|------|-------|-------------|
12
+ | **RN** | Ignite (infinitered) | 19.7k | MST + MMKV + generators |
13
+ | **RN** | Obytes Template | 4k | Zustand + TanStack Query + Expo Router |
14
+ | **RN** | Expensify/App | 4.7k | Onyx custom state + centralized constants |
15
+ | **RN** | Mattermost Mobile | 2.6k | WatermelonDB + offline-first + WebSocket |
16
+ | **RN** | Artsy Eigen | 3.8k | Relay/GraphQL + Scene pattern |
17
+ | **Flutter** | Immich | 93.5k | Riverpod + drift + auto_route + clean arch |
18
+ | **Flutter** | AppFlowy | 68.2k | BLoC + GetIt + startup/ pattern |
19
+ | **Flutter** | Spotube | 44.6k | Riverpod + Hooks + custom hooks folder |
20
+ | **Flutter** | Hiddify | 26.7k | Riverpod + go_router + bootstrap.dart |
21
+ | **Flutter** | Ente Photos | 24.8k | Melos monorepo + gateway pattern |
22
+ | **iOS** | TCA (Point-Free) | 14.4k | Unidirectional + TestStore + @Dependency |
23
+ | **iOS** | Clean Arch SwiftUI | 6.5k | Redux state + @Environment DI |
24
+ | **iOS** | Modern Clean Arch | 4.1k | Tuist + 5-layer DDD + MVVM+TCA coexist |
25
+ | **Android** | Now in Android | 20.7k | Official Google arch + no-mock testing |
26
+ | **Android** | Android Showcase | 6.7k | Konsist validation + Koin DI |
27
+ | **Android** | Mihon | 18.8k | Plugin/extension arch + MVI |
28
+
29
+ ---
30
+
31
+ ## Cross-Platform Architecture Patterns
32
+
33
+ ### 1. Dual State Management (Client + Server)
34
+
35
+ **The pattern:** Separate client state (UI, forms) from server state (API cache).
36
+
37
+ | Platform | Client State | Server State |
38
+ |----------|-------------|--------------|
39
+ | React Native | Zustand / MST | TanStack Query |
40
+ | Flutter | Riverpod | Riverpod + drift |
41
+ | iOS | @Observable / TCA | URLSession cache |
42
+ | Android | ViewModel + Flow | Repository + Room |
43
+
44
+ ```typescript
45
+ // RN: Zustand for client + TanStack Query for server
46
+ const useAuthStore = create((set) => ({
47
+ token: null,
48
+ setToken: (t) => set({ token: t }),
49
+ }));
50
+
51
+ const { data, isLoading } = useQuery({
52
+ queryKey: ['products'],
53
+ queryFn: () => api.getProducts(),
54
+ staleTime: 5 * 60 * 1000,
55
+ });
56
+ ```
57
+
58
+ ```dart
59
+ // Flutter: Riverpod for both, but separated
60
+ @riverpod
61
+ class AuthNotifier extends _$AuthNotifier { ... } // client
62
+
63
+ @riverpod
64
+ Future<List<Product>> products(Ref ref) async { ... } // server
65
+ ```
66
+
67
+ ### 2. Feature-Based Module Organization
68
+
69
+ **Every top repo (100%) uses feature-based organization, NOT type-based.**
70
+
71
+ ```
72
+ // ✅ CORRECT: Feature-based (Immich, Obytes, Hiddify, Now in Android)
73
+ src/features/
74
+ auth/
75
+ domain/ # entities, use cases, repo interfaces
76
+ data/ # repo impl, API, DTOs, mappers
77
+ presentation/ # screens, widgets, viewmodels
78
+
79
+ // ❌ WRONG: Type-based (no production app uses this)
80
+ src/
81
+ models/
82
+ services/
83
+ screens/
84
+ widgets/
85
+ ```
86
+
87
+ ### 3. Centralized Constants Pattern (Expensify)
88
+
89
+ ```typescript
90
+ // src/ROUTES.ts — Prevents string duplication
91
+ const ROUTES = {
92
+ HOME: 'home',
93
+ SETTINGS: 'settings',
94
+ PROFILE: 'profile/:id',
95
+ } as const;
96
+
97
+ // src/SCREENS.ts — Screen component names
98
+ const SCREENS = {
99
+ HOME: 'HomeScreen',
100
+ SETTINGS: 'SettingsScreen',
101
+ } as const;
102
+ ```
103
+
104
+ ### 4. Bootstrap / Startup Pattern (Hiddify, AppFlowy)
105
+
106
+ ```dart
107
+ // bootstrap.dart — Clean app initialization
108
+ Future<void> bootstrap() async {
109
+ WidgetsFlutterBinding.ensureInitialized();
110
+
111
+ // 1. Core services
112
+ await Firebase.initializeApp();
113
+ await Hive.initFlutter();
114
+
115
+ // 2. DI registration
116
+ setupServiceLocator();
117
+
118
+ // 3. Run app
119
+ runApp(
120
+ ProviderScope(
121
+ observers: [RiverpodObserver()],
122
+ child: const App(),
123
+ ),
124
+ );
125
+ }
126
+
127
+ // main.dart
128
+ void main() => bootstrap();
129
+
130
+ // main_prod.dart — Production flavor
131
+ void main() {
132
+ const env = Environment.production;
133
+ bootstrap(env: env);
134
+ }
135
+ ```
136
+
137
+ ### 5. Draft Pairs for Forms (Expensify)
138
+
139
+ ```typescript
140
+ // Every form has FORM + FORM_DRAFT for unsaved changes
141
+ const ONYX_KEYS = {
142
+ WORKSPACE_SETTINGS_FORM: 'workspaceSettingsForm',
143
+ WORKSPACE_SETTINGS_FORM_DRAFT: 'workspaceSettingsFormDraft',
144
+ } as const;
145
+
146
+ // Save draft on every keystroke → restore on crash/back
147
+ // Only commit FORM when user explicitly saves
148
+ ```
149
+
150
+ ### 6. Database Subscription Pattern (Mattermost)
151
+
152
+ ```
153
+ database/
154
+ models/ # WatermelonDB model definitions
155
+ schema/ # DB structure + versioning
156
+ migration/ # Schema migrations
157
+ operator/ # Complex query logic (keeps models clean)
158
+ subscription/ # Reactive UI updates from DB changes
159
+ exceptions/ # Custom error classes
160
+ manager/ # DB lifecycle (create, reset, destroy)
161
+ ```
162
+
163
+ ### 7. Functional Error Handling (Flutter — dartz)
164
+
165
+ ```dart
166
+ // Instead of try/catch everywhere, use Either<Failure, Success>
167
+ Future<Either<AppException, User>> getUser(String id) async {
168
+ try {
169
+ final response = await dio.get('/users/$id');
170
+ return Right(User.fromJson(response.data));
171
+ } on DioException catch (e) {
172
+ return Left(NetworkException(e.message));
173
+ }
174
+ }
175
+
176
+ // Usage — forces caller to handle both cases
177
+ final result = await getUser('123');
178
+ result.fold(
179
+ (failure) => showError(failure.message),
180
+ (user) => showProfile(user),
181
+ );
182
+ ```
183
+
184
+ ### 8. Architecture Validation (Android Showcase — Konsist)
185
+
186
+ ```kotlin
187
+ // Programmatically enforce architecture rules
188
+ @Test
189
+ fun `domain layer should not depend on data layer`() {
190
+ Konsist.scopeFromModule("feature-album/domain")
191
+ .classes()
192
+ .assertFalse { it.hasImport { import -> import.hasNameContaining("data") } }
193
+ }
194
+
195
+ @Test
196
+ fun `use cases should have 'UseCase' suffix`() {
197
+ Konsist.scopeFromModule("feature-album/domain")
198
+ .classes()
199
+ .withNameContaining("UseCase")
200
+ .assertTrue { it.hasPublicFunction("invoke") }
201
+ }
202
+ ```
203
+
204
+ ---
205
+
206
+ ## Platform-Specific Intelligence
207
+
208
+ ### React Native — Must-Know Patterns
209
+
210
+ | Pattern | Old Way | New Way (2024-2025) | Source |
211
+ |---------|---------|---------------------|--------|
212
+ | Storage | AsyncStorage | MMKV (60x faster) | Ignite, Obytes |
213
+ | Routing | React Navigation | Expo Router (file-based) | Obytes |
214
+ | Server state | Redux + thunk | TanStack Query | Obytes, TCM |
215
+ | Client state | Redux | Zustand | Obytes |
216
+ | E2E testing | Detox | Maestro | Ignite, Obytes |
217
+ | Forms | Formik + Yup | TanStack Form + Zod | Obytes |
218
+ | Styling | StyleSheet | NativeWind (TailwindCSS) | Obytes |
219
+ | Animations | Animated API | Reanimated 3 | All |
220
+ | Images | Image | expo-image / FastImage | All |
221
+
222
+ ### Flutter — Must-Know Patterns
223
+
224
+ | Pattern | Old Way | New Way (2024-2025) | Source |
225
+ |---------|---------|---------------------|--------|
226
+ | State | setState / Provider | Riverpod + code-gen | Immich, Hiddify, Spotube |
227
+ | State (alt) | BLoC manual | BLoC + freezed | AppFlowy |
228
+ | Navigation | Navigator 2.0 | auto_route / go_router | Immich / Hiddify |
229
+ | Database | sqflite | drift (type-safe ORM) | Immich, Spotube |
230
+ | Models | manual fromJson | freezed + json_serializable | All |
231
+ | i18n | .arb files | slang (type-safe, generated) | Hiddify |
232
+ | HTTP | http package | dio + smart_retry | Hiddify |
233
+ | HTTP (perf) | dio on all | cronet (Android) + cupertino_http (iOS) | Immich |
234
+ | Monorepo | N/A | Melos | Ente |
235
+ | DI | manual | Riverpod providers / GetIt | Immich / AppFlowy |
236
+
237
+ ### iOS Swift — Must-Know Patterns
238
+
239
+ | Pattern | Traditional | Modern (2024-2025) | Source |
240
+ |---------|-------------|---------------------|--------|
241
+ | Architecture | MVVM manual | TCA (macro-driven) | Point-Free |
242
+ | DI | Swinject | @Dependency (Point-Free) / @Environment | TCA / nalexn |
243
+ | Testing | XCTest + mocks | TestStore (deterministic) | TCA |
244
+ | Navigation | NavigationView | NavigationStack + Coordinator | sergdort |
245
+ | Modularization | One target | Tuist multi-module | sergdort |
246
+ | Data binding | Combine | @Observable macro | iOS 17+ |
247
+ | SwiftUI testing | None | ViewInspector | nalexn |
248
+ | Concurrency | GCD / Combine | async/await + actors | All |
249
+
250
+ ### Android Kotlin — Must-Know Patterns
251
+
252
+ | Pattern | Traditional | Modern (2024-2025) | Source |
253
+ |---------|-------------|---------------------|--------|
254
+ | UI | XML Views | Jetpack Compose | All |
255
+ | Architecture | MVVM | MVVM + UDF (Now in Android) | Google |
256
+ | DI | Dagger 2 | Hilt | Now in Android |
257
+ | DI (lightweight) | N/A | Koin | Android Showcase |
258
+ | Testing | Mockito | No-mock test doubles | Now in Android |
259
+ | Arch validation | Manual review | Konsist | Android Showcase |
260
+ | Performance | ProGuard | Baseline Profiles + R8 | Now in Android |
261
+ | Navigation | Fragment nav | Compose Navigation (type-safe) | All |
262
+ | Build config | build.gradle | Convention Plugins | Now in Android |
263
+ | Screenshot test | None | Roborazzi | Now in Android |
264
+
265
+ ---
266
+
267
+ ## Production Folder Structure Templates
268
+
269
+ ### React Native (Expo Router — based on Obytes)
270
+
271
+ ```
272
+ src/
273
+ app/ # Expo Router file-based routes
274
+ (app)/ # Authenticated group
275
+ _layout.tsx
276
+ (tabs)/ # Tab navigator
277
+ login.tsx
278
+ onboarding.tsx
279
+ _layout.tsx # Root layout
280
+ features/ # Feature modules
281
+ auth/
282
+ hooks/
283
+ components/
284
+ services/
285
+ types.ts
286
+ products/
287
+ hooks/
288
+ components/
289
+ services/
290
+ components/
291
+ ui/ # Design system (Button, Input, Card)
292
+ lib/
293
+ api/ # Axios + TanStack Query setup
294
+ auth/ # Token management (Zustand + MMKV)
295
+ hooks/ # Shared hooks
296
+ i18n/ # Internationalization
297
+ storage.ts # MMKV wrapper
298
+ utils.ts # Utilities
299
+ translations/ # Language files
300
+ ```
301
+
302
+ ### Flutter (Riverpod + Clean — based on Immich)
303
+
304
+ ```
305
+ lib/
306
+ main.dart
307
+ bootstrap.dart # App initialization
308
+ app/
309
+ app.dart # MaterialApp.router
310
+ router.dart # auto_route / go_router config
311
+ theme/
312
+ features/
313
+ auth/
314
+ domain/ # Entities, use cases, repo interfaces
315
+ data/ # Repo impl, datasources, DTOs
316
+ presentation/ # Screens + widgets
317
+ providers/ # Riverpod providers
318
+ [feature]/
319
+ shared/
320
+ widgets/ # Reusable UI
321
+ extensions/ # Dart extensions
322
+ constants/ # App-wide constants
323
+ interfaces/ # Abstract contracts
324
+ models/ # Shared DTOs
325
+ utils/ # Utilities
326
+ l10n/ # Localization
327
+ ```
328
+
329
+ ### iOS SwiftUI (TCA — based on Point-Free + sergdort)
330
+
331
+ ```
332
+ App/
333
+ AppDelegate.swift
334
+ AppModule.swift # Composition root
335
+ Features/
336
+ Auth/
337
+ AuthFeature.swift # @Reducer
338
+ AuthView.swift # SwiftUI View
339
+ AuthClient.swift # @Dependency
340
+ Home/
341
+ HomeFeature.swift
342
+ HomeView.swift
343
+ Settings/
344
+ Shared/
345
+ Models/
346
+ Extensions/
347
+ UI/ # Shared SwiftUI components
348
+ Clients/ # API, Storage, Keychain
349
+ Platform/
350
+ Networking/
351
+ Persistence/
352
+ Tests/
353
+ AuthFeatureTests.swift # TestStore tests
354
+ ```
355
+
356
+ ### Android Kotlin (Now in Android — based on Google reference)
357
+
358
+ ```
359
+ app/ # Main application
360
+ core/
361
+ common/ # Shared utilities
362
+ data/ # Repository implementations
363
+ database/ # Room database
364
+ datastore/ # Proto DataStore
365
+ network/ # Retrofit + OkHttp
366
+ model/ # Core models
367
+ ui/ # Shared Compose components
368
+ testing/ # Test utilities
369
+ feature/
370
+ auth/
371
+ src/main/
372
+ AuthScreen.kt # Compose UI
373
+ AuthViewModel.kt # ViewModel
374
+ AuthUiState.kt # UI state sealed class
375
+ navigation/ # Feature nav graph
376
+ home/
377
+ settings/
378
+ build-logic/ # Convention plugins
379
+ convention/
380
+ AndroidApplicationConventionPlugin.kt
381
+ AndroidFeatureConventionPlugin.kt
382
+ ```
383
+
384
+ ---
385
+
386
+ ## Decision Matrix — When to Use What
387
+
388
+ ### State Management
389
+
390
+ | Condition | RN | Flutter | iOS | Android |
391
+ |-----------|-----|---------|-----|---------|
392
+ | Simple app (<10 screens) | Zustand | Riverpod | @Observable | ViewModel + StateFlow |
393
+ | Complex app (10-50 screens) | Zustand + TanStack Query | Riverpod + freezed | TCA | MVVM + Hilt + Flow |
394
+ | Enterprise (50+ screens) | Onyx (custom) / Redux Toolkit | BLoC + GetIt | TCA + Tuist | MVVM + Hilt + Convention Plugins |
395
+ | Offline-first | TanStack Query + WatermelonDB | Riverpod + drift | TCA + SwiftData | Room + WorkManager |
396
+
397
+ ### Navigation
398
+
399
+ | Condition | RN | Flutter | iOS | Android |
400
+ |-----------|-----|---------|-----|---------|
401
+ | Expo project | Expo Router | — | — | — |
402
+ | RN CLI project | React Navigation | — | — | — |
403
+ | Type-safe routes | — | auto_route | NavigationStack | Compose Navigation |
404
+ | Declarative | Expo Router | go_router | NavigationStack | Compose Navigation |
405
+ | Deep linking | Expo Linking | app_links | Universal Links | App Links |
406
+
407
+ ### Testing
408
+
409
+ | What | RN | Flutter | iOS | Android |
410
+ |------|-----|---------|-----|---------|
411
+ | Unit | Jest | test + mocktail | XCTest / TestStore | JUnit + no-mock doubles |
412
+ | Widget/Component | React Testing Library | widget test | ViewInspector | Compose Testing |
413
+ | E2E | Maestro | integration_test | XCUITest | Macrobenchmark |
414
+ | Screenshot | — | golden_toolkit | — | Roborazzi |
415
+ | Architecture | Dependency Cruiser | — | — | Konsist |
416
+ | Performance | Reassure | DevTools | Instruments | Baseline Profiles |