@buivietphi/skill-mobile-mt 2.0.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +96 -40
- package/README.md +77 -40
- package/SKILL.md +762 -54
- package/package.json +1 -1
- package/shared/bug-detection.md +411 -27
- package/shared/code-generation-templates.md +656 -0
- package/shared/code-review.md +899 -37
- package/shared/complex-ui-patterns.md +526 -0
- package/shared/data-flow-patterns.md +422 -0
- package/shared/debugging-intelligence.md +787 -0
- package/shared/error-handling.md +394 -0
- package/shared/i18n-localization.md +426 -0
- package/shared/intent-analysis.md +473 -0
- package/shared/navigation-patterns.md +375 -0
- package/shared/prompt-engineering.md +176 -20
- package/shared/spec-to-code.md +293 -0
- package/shared/storage-patterns.md +312 -0
- package/shared/testing-patterns.md +428 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@buivietphi/skill-mobile-mt",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Master Senior Mobile Engineer skill for AI agents. Pre-built patterns from 30+ production repos. React Native, Flutter, iOS, Android. Supports Claude, Cline, Cursor, Windsurf, Copilot, Codex, Gemini, Kimi, Kilo Code, Kiro, Antigravity.",
|
|
5
5
|
"author": "buivietphi",
|
|
6
6
|
"license": "MIT",
|
package/shared/bug-detection.md
CHANGED
|
@@ -1,10 +1,388 @@
|
|
|
1
|
-
# Bug Detection — Auto Scanner
|
|
1
|
+
# Bug Detection — Intelligent Auto Scanner
|
|
2
2
|
|
|
3
3
|
> Always loaded. All platforms.
|
|
4
|
+
> This file governs HOW the AI approaches every bug, error, crash, and issue.
|
|
4
5
|
|
|
5
6
|
---
|
|
6
7
|
|
|
7
|
-
##
|
|
8
|
+
## Platform Focus Rule
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
⛔ FOCUS on the DETECTED platform. Only cross-platform when the bug actually touches native code.
|
|
12
|
+
|
|
13
|
+
REACT NATIVE / EXPO:
|
|
14
|
+
→ Search: src/ (JS/TS) FIRST → only check android/ ios/ if native module involved
|
|
15
|
+
→ Scan: RN-specific patterns (useEffect, FlatList, bridge, Metro)
|
|
16
|
+
→ Go native ONLY IF: error from Logcat/Xcode (not Metro), native module crash, linking issue
|
|
17
|
+
|
|
18
|
+
FLUTTER:
|
|
19
|
+
→ Search: lib/ (Dart) FIRST → only check android/ ios/ if platform channel involved
|
|
20
|
+
→ Scan: Flutter-specific patterns (mounted, dispose, BuildContext, Widget tree)
|
|
21
|
+
→ Go native ONLY IF: error from native layer, MethodChannel crash, plugin issue
|
|
22
|
+
|
|
23
|
+
ANDROID NATIVE (Java/Kotlin):
|
|
24
|
+
→ Search: app/src/ FIRST → SKIP RN and Flutter patterns entirely
|
|
25
|
+
→ Scan: Android-specific (lifecycle, ViewModel, coroutines, Fragment, Compose)
|
|
26
|
+
|
|
27
|
+
iOS NATIVE (Swift/ObjC):
|
|
28
|
+
→ Search: *.swift FIRST → SKIP RN and Flutter patterns entirely
|
|
29
|
+
→ Scan: iOS-specific (optionals, @MainActor, Combine, Task, Codable)
|
|
30
|
+
|
|
31
|
+
FOR BUGS: if the bug trace crosses platform boundaries (e.g., RN JS error caused by
|
|
32
|
+
native module) → THEN investigate the native side too. Otherwise stay in platform.
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## ⛔ STEP 0: Classify Error Type FIRST
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
BEFORE doing anything — classify what the user gave you:
|
|
41
|
+
|
|
42
|
+
USER INPUT → TYPE → SEARCH STRATEGY
|
|
43
|
+
───────────────────────────────────────────────────────────────────────────
|
|
44
|
+
Paste stack trace / crash log → RUNTIME CRASH → Parse trace → find YOUR files → Grep function in src/
|
|
45
|
+
"Build fail / not compile" → BUILD ERROR → Config files FIRST (tsconfig/gradle/Podfile/pubspec) → then deps
|
|
46
|
+
"Type error / TS error" → TYPE MISMATCH → Find interface/type definition → find caller → fix mismatch
|
|
47
|
+
"API error / 401 / 500 / timeout" → NETWORK ERROR → Find API service file → check endpoint + headers + auth + .env
|
|
48
|
+
"Screen blank / white / not render" → RENDER ERROR → Find component → check props + state + conditionals + data
|
|
49
|
+
"Navigation fail / route not found" → NAVIGATION ERROR → Find navigator/router config → check route names + params
|
|
50
|
+
"Slow / lag / freeze / ANR" → PERFORMANCE → Profile first → read shared/performance-prediction.md
|
|
51
|
+
"Check issue / investigate / review"→ INVESTIGATION → Read → search → analyze → REPORT (don't fix yet!)
|
|
52
|
+
"Native module error / link fail" → NATIVE ERROR → Check pod/gradle linking → then JS/Dart bridge → rebuild
|
|
53
|
+
"State wrong / data stale / race" → STATE ERROR → Find store/state → trace mutations → check async timing
|
|
54
|
+
"Memory leak / OOM" → MEMORY ERROR → Find useEffect/listeners/subscriptions without cleanup
|
|
55
|
+
|
|
56
|
+
⛔ WRONG: Skip classification → guess fix from error message
|
|
57
|
+
✅ RIGHT: Classify → pick search strategy → search project → then analyze
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## ⛔ STEP 1: Search Project BEFORE Diagnosing
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
⛔ NON-NEGOTIABLE: You MUST search project source code BEFORE suggesting ANYTHING.
|
|
66
|
+
|
|
67
|
+
1. EXTRACT from error message / user description:
|
|
68
|
+
→ File name or path mentioned in stack trace
|
|
69
|
+
→ Function name / class name / component name / module name
|
|
70
|
+
→ Line number (if available)
|
|
71
|
+
→ Package name (if dependency error)
|
|
72
|
+
→ HTTP status code / error code (if API error)
|
|
73
|
+
|
|
74
|
+
2. SEARCH PROJECT (Grep + Glob) — in this EXACT order:
|
|
75
|
+
→ Grep "[keyword]" src/ ← ALWAYS start here
|
|
76
|
+
→ Grep "[keyword]" lib/ app/ ← if src/ has no results
|
|
77
|
+
→ Glob "**/*[ComponentName]*" ← find the actual file
|
|
78
|
+
→ Glob "**/*[screenName]*" ← try screen name
|
|
79
|
+
→ Read the TOP 3-5 matched files ← understand the real code
|
|
80
|
+
|
|
81
|
+
3. ONLY THEN proceed to analysis
|
|
82
|
+
|
|
83
|
+
⛔ If you have NOT run Grep/Glob yet → GO BACK AND DO IT NOW
|
|
84
|
+
⛔ NEVER say "the error is probably..." without having searched first
|
|
85
|
+
|
|
86
|
+
SEARCH PRIORITY ORDER:
|
|
87
|
+
src/ → lib/ → app/ → components/ → screens/ → services/ → utils/
|
|
88
|
+
→ hooks/ → store/ → api/ → config/ → package.json → node_modules/ (LAST resort)
|
|
89
|
+
|
|
90
|
+
EXCEPTION — BUILD ERRORS search order is different:
|
|
91
|
+
package.json / pubspec.yaml → tsconfig.json / build.gradle / Podfile
|
|
92
|
+
→ config files → THEN src/
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## ⛔ STEP 2: Filter Noise from Logs
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
When user pastes a long error log, FILTER before analyzing:
|
|
101
|
+
|
|
102
|
+
IGNORE (noise — skip these lines):
|
|
103
|
+
✗ node_modules/* paths (framework internals, not your bug)
|
|
104
|
+
✗ React internals (__callReactNativeMicrotasks, MessageQueue, BatchedBridge)
|
|
105
|
+
✗ Engine frames (JavaScriptCore, Hermes, V8, ART, libc++)
|
|
106
|
+
✗ "Warning:" lines (unless directly related to the crash)
|
|
107
|
+
✗ "at Object.<anonymous>" without your file path
|
|
108
|
+
✗ "at Module._compile" / "at Function.Module._resolveFilename" (Node internals)
|
|
109
|
+
✗ Repeated/duplicate stack frames
|
|
110
|
+
✗ "console.log" output lines (unless user points to them)
|
|
111
|
+
|
|
112
|
+
FOCUS (signal — these lines matter):
|
|
113
|
+
✓ Lines with YOUR file paths (src/, app/, lib/, screens/, components/)
|
|
114
|
+
✓ "Error:", "TypeError:", "ReferenceError:", "SyntaxError:", "Unhandled"
|
|
115
|
+
✓ LAST "Caused by:" line (= actual root cause in Java/Android/Kotlin)
|
|
116
|
+
✓ FIRST frame with YOUR code in stack trace (= closest to crash)
|
|
117
|
+
✓ "undefined is not an object" + property name (= null pointer access)
|
|
118
|
+
✓ Error codes: ENOENT, ECONNREFUSED, ETIMEDOUT, E_MISSING_*
|
|
119
|
+
✓ HTTP status codes: 400, 401, 403, 404, 500, 502, 503
|
|
120
|
+
|
|
121
|
+
TECHNIQUE: Scan log → mark signal lines → ignore everything else → THEN analyze
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## ⛔ STEP 3: Parse Stack Trace by Platform
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
REACT NATIVE (Metro / Hermes / JSC):
|
|
130
|
+
→ Line 1 after "Error:" or "TypeError:" = THE error description
|
|
131
|
+
→ Find FIRST "at" line with YOUR path (not node_modules/) = crash location
|
|
132
|
+
→ Read call chain bottom-to-top = how you got there
|
|
133
|
+
→ If "Component Stack:" present = which component tree caused it
|
|
134
|
+
→ Red Screen title = searchable error keyword → Grep it in src/
|
|
135
|
+
|
|
136
|
+
FLUTTER (Dart):
|
|
137
|
+
→ "The following [ExceptionType] was thrown" = error classification
|
|
138
|
+
→ "#0" frame = function closest to the crash
|
|
139
|
+
→ Find frames with YOUR package name (not package:flutter/)
|
|
140
|
+
→ "When the exception was thrown, this was the stack:" = full call chain
|
|
141
|
+
→ "RenderBox was not laid out" = layout issue → find the widget
|
|
142
|
+
|
|
143
|
+
iOS (Xcode Console / Crash Log):
|
|
144
|
+
→ "*** Terminating app due to uncaught exception" = crash start
|
|
145
|
+
→ "reason:" = human-readable cause
|
|
146
|
+
→ Find YOUR binary/module name in thread stack (not UIKit/Foundation)
|
|
147
|
+
→ Thread marked "CRASHED" or "*" = the crashing thread
|
|
148
|
+
→ "EXC_BAD_ACCESS" = null pointer / deallocated memory
|
|
149
|
+
→ "Signal: SIGABRT" = assertion failure → check the reason string
|
|
150
|
+
|
|
151
|
+
ANDROID (Logcat / ADB):
|
|
152
|
+
→ Filter by "E/" (Error level) or "FATAL EXCEPTION"
|
|
153
|
+
→ READ LAST "Caused by:" LINE = actual root cause (not the first one!)
|
|
154
|
+
→ Lines with YOUR package name (com.yourapp.*) = your code
|
|
155
|
+
→ "java.lang.NullPointerException" → find the null variable
|
|
156
|
+
→ "android.view.InflateException" → layout XML issue
|
|
157
|
+
→ "java.lang.OutOfMemoryError" → bitmap/image loading issue
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## ⛔ STEP 4: Pick the Right Flow — 4 Different Modes
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
FIRST: Detect which mode the user is in:
|
|
166
|
+
|
|
167
|
+
User has error log / stack trace → MODE A: Error Analysis
|
|
168
|
+
User says "fix this" / "debug this" → MODE B: Fix Bug
|
|
169
|
+
User says "check issue" / "investigate" with specific issue → MODE C: Investigate
|
|
170
|
+
User describes symptoms vaguely / "check giùm" / "xem thử" /
|
|
171
|
+
"sao nó lạ" / "not sure why" / "take a look" / pastes code
|
|
172
|
+
without error / describes behavior → MODE D: Diagnostic Scan
|
|
173
|
+
|
|
174
|
+
⛔ If you can't tell which mode → DEFAULT TO MODE D (Diagnostic Scan)
|
|
175
|
+
⛔ NEVER default to Mode B (Fix Bug) — don't fix what you haven't scanned
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### MODE A: Error Analysis (user has error log)
|
|
179
|
+
```
|
|
180
|
+
┌─────────────────────────────────────────────────────────┐
|
|
181
|
+
│ 1. Filter noise from log (Step 2 above) │
|
|
182
|
+
│ 2. Extract signal lines (YOUR paths, Error:, Caused by:)│
|
|
183
|
+
│ 3. Classify error type (Step 0 above) │
|
|
184
|
+
│ 4. Search project src/ for extracted keywords │
|
|
185
|
+
│ 5. Read matched files → trace root cause │
|
|
186
|
+
│ 6. Explain what's happening + propose fix with citation │
|
|
187
|
+
└─────────────────────────────────────────────────────────┘
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### MODE B: Fix Bug (user knows the bug, wants a fix)
|
|
191
|
+
```
|
|
192
|
+
⛔ NO FIXES WITHOUT ROOT CAUSE INVESTIGATION FIRST
|
|
193
|
+
⛔ 1 HYPOTHESIS → 1 MINIMAL CHANGE → VERIFY → if wrong, NEW hypothesis
|
|
194
|
+
|
|
195
|
+
PHASE 0: CHECK RECENT CHANGES (git-aware — do this FIRST)
|
|
196
|
+
┌─────────────────────────────────────────────────────────┐
|
|
197
|
+
│ ⚠️ PRE-CHECK: Is this a git project? │
|
|
198
|
+
│ → Run: git rev-parse --is-inside-work-tree 2>/dev/null│
|
|
199
|
+
│ → If NOT a git repo → SKIP Phase 0 → go to Phase 1 │
|
|
200
|
+
│ → If git repo with no commits → SKIP Phase 0 │
|
|
201
|
+
│ → If git repo with history → proceed below │
|
|
202
|
+
│ │
|
|
203
|
+
│ ⛔ BEFORE deep-diving into code, check what changed: │
|
|
204
|
+
│ │
|
|
205
|
+
│ 1. git log --oneline -10 │
|
|
206
|
+
│ → What were the last 10 commits? │
|
|
207
|
+
│ → Does any commit message relate to the broken area? │
|
|
208
|
+
│ │
|
|
209
|
+
│ 2. git diff HEAD~3 --name-only │
|
|
210
|
+
│ → What files changed in last 3 commits? │
|
|
211
|
+
│ → Is the broken file among them? │
|
|
212
|
+
│ │
|
|
213
|
+
│ 3. git diff HEAD~3 -- [broken_file] │
|
|
214
|
+
│ → What EXACTLY changed in the broken file recently? │
|
|
215
|
+
│ → Was the bug INTRODUCED by a recent change? │
|
|
216
|
+
│ │
|
|
217
|
+
│ 4. git log --oneline --all -- [broken_file] │
|
|
218
|
+
│ → Full history of changes to this file │
|
|
219
|
+
│ → When was the last time someone touched it? │
|
|
220
|
+
│ │
|
|
221
|
+
│ WHY: 80%+ of bugs are caused by RECENT CHANGES. │
|
|
222
|
+
│ If the bug appeared after a specific commit, you already │
|
|
223
|
+
│ know where to look — skip the rest of Phase 1. │
|
|
224
|
+
│ │
|
|
225
|
+
│ If git shows the file hasn't changed recently → │
|
|
226
|
+
│ the bug is environmental/data-driven → proceed Phase 1. │
|
|
227
|
+
│ │
|
|
228
|
+
│ SKIP PHASE 0 WHEN: │
|
|
229
|
+
│ → Project has NO git (not initialized) │
|
|
230
|
+
│ → git init done but no commits yet │
|
|
231
|
+
│ → Brand new project (no meaningful history) │
|
|
232
|
+
│ → User says "this never worked" (not a regression) │
|
|
233
|
+
│ → Build error from fresh install (dependency issue) │
|
|
234
|
+
└─────────────────────────────────────────────────────────┘
|
|
235
|
+
|
|
236
|
+
PHASE 1: ROOT CAUSE INVESTIGATION (mandatory — NO shortcuts)
|
|
237
|
+
┌─────────────────────────────────────────────────────────┐
|
|
238
|
+
│ 1. Classify error type (Step 0) │
|
|
239
|
+
│ 2. Search project src/ (Step 1) — MANDATORY │
|
|
240
|
+
│ 3. Read matched files → trace execution path │
|
|
241
|
+
│ 4. Classify reproduction: │
|
|
242
|
+
│ → ALWAYS reproduces = deterministic → trace step by step│
|
|
243
|
+
│ → SOMETIMES reproduces = race/timing → check async flow│
|
|
244
|
+
│ → ONLY on [platform] = platform-specific → check native│
|
|
245
|
+
│ → ONLY after [action] = state-dependent → trace state │
|
|
246
|
+
│ 5. ROOT CAUSE: cite exact file:line + WHY it fails │
|
|
247
|
+
│ ⛔ "I think..." is NOT a root cause │
|
|
248
|
+
│ ✅ "file:line does X, but Y is null because Z" │
|
|
249
|
+
└─────────────────────────────────────────────────────────┘
|
|
250
|
+
|
|
251
|
+
PHASE 2: PATTERN ANALYSIS (find working example FIRST)
|
|
252
|
+
┌─────────────────────────────────────────────────────────┐
|
|
253
|
+
│ 1. Search SAME codebase for similar working code: │
|
|
254
|
+
│ → Grep for similar pattern that WORKS in project │
|
|
255
|
+
│ → Find a screen/service/hook that does the SAME thing│
|
|
256
|
+
│ but doesn't have this bug │
|
|
257
|
+
│ 2. Compare broken code vs working code: │
|
|
258
|
+
│ → List EVERY difference │
|
|
259
|
+
│ → The bug is in the differences │
|
|
260
|
+
│ 3. If no working example exists → skip to Phase 3 │
|
|
261
|
+
└─────────────────────────────────────────────────────────┘
|
|
262
|
+
|
|
263
|
+
PHASE 3: SINGLE HYPOTHESIS + MINIMAL FIX
|
|
264
|
+
┌─────────────────────────────────────────────────────────┐
|
|
265
|
+
│ 1. Form ONE hypothesis based on root cause │
|
|
266
|
+
│ 2. Make the SMALLEST possible change to test it │
|
|
267
|
+
│ ⛔ NEVER stack multiple fixes at once │
|
|
268
|
+
│ ⛔ NEVER "fix it and also refactor nearby code" │
|
|
269
|
+
│ ✅ 1 change → verify → if wrong, revert → new idea │
|
|
270
|
+
│ 3. Verify the fix: │
|
|
271
|
+
│ → Does it fix ALL symptoms? (not just one) │
|
|
272
|
+
│ → Does it explain intermittent behavior? │
|
|
273
|
+
│ → Does it work on both platforms? │
|
|
274
|
+
│ 4. Grep for side effects (other files using this) │
|
|
275
|
+
└─────────────────────────────────────────────────────────┘
|
|
276
|
+
|
|
277
|
+
PHASE 4: DEFENSE IN DEPTH (after fix is verified)
|
|
278
|
+
┌─────────────────────────────────────────────────────────┐
|
|
279
|
+
│ 1. Validate at EVERY layer data passes through: │
|
|
280
|
+
│ → Input validation (caller side) │
|
|
281
|
+
│ → Function guard (callee side) │
|
|
282
|
+
│ → State check (store/reducer/bloc) │
|
|
283
|
+
│ → UI render guard (component level) │
|
|
284
|
+
│ 2. Make the bug STRUCTURALLY IMPOSSIBLE to recur: │
|
|
285
|
+
│ → Add type guard / null check / validation │
|
|
286
|
+
│ → Not just "fix this one case" but prevent the class │
|
|
287
|
+
│ 3. Cite: "Fix in [file:line] — [cause] — [why works]" │
|
|
288
|
+
└─────────────────────────────────────────────────────────┘
|
|
289
|
+
|
|
290
|
+
🚩 RED FLAGS — if you catch yourself doing these, STOP:
|
|
291
|
+
┌─────────────────────────────────────────────────────────┐
|
|
292
|
+
│ "Should work now" → RUN IT. Don't claim. │
|
|
293
|
+
│ "I'm confident this fixes" → Confidence ≠ evidence. │
|
|
294
|
+
│ "Let me also clean up..." → STOP. Fix bug only. │
|
|
295
|
+
│ "Probably a race condition"→ PROVE IT with code trace. │
|
|
296
|
+
│ "Try changing X to Y" → Did you READ the file? │
|
|
297
|
+
│ Stacking 3+ changes at once→ Revert. 1 change at a time.│
|
|
298
|
+
│ Same fix attempt 3+ times → STOP. Question architecture.│
|
|
299
|
+
└─────────────────────────────────────────────────────────┘
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### MODE C: Investigate (user has a specific issue to check)
|
|
303
|
+
```
|
|
304
|
+
┌─────────────────────────────────────────────────────────┐
|
|
305
|
+
│ 1. Read issue description fully (don't skim) │
|
|
306
|
+
│ 2. Extract: affected feature, expected vs actual │
|
|
307
|
+
│ 3. Search project for the affected code area │
|
|
308
|
+
│ 4. Read the code → understand current implementation │
|
|
309
|
+
│ 5. REPORT findings — explain what's happening and WHY │
|
|
310
|
+
│ 6. ⛔ DO NOT FIX unless user explicitly asks │
|
|
311
|
+
│ │
|
|
312
|
+
│ Output format: │
|
|
313
|
+
│ "I found [component] at [file:line]. │
|
|
314
|
+
│ Current behavior: [what code does]. │
|
|
315
|
+
│ The issue is: [root cause]. │
|
|
316
|
+
│ Want me to fix it?" │
|
|
317
|
+
└─────────────────────────────────────────────────────────┘
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### MODE D: Diagnostic Scan (user unsure / vague / "check this for me")
|
|
321
|
+
```
|
|
322
|
+
⚡ THIS IS THE MOST IMPORTANT MODE — handles the most common real scenario:
|
|
323
|
+
User doesn't know what's wrong, just feels something is off,
|
|
324
|
+
or wants AI to proactively check their code.
|
|
325
|
+
|
|
326
|
+
┌─────────────────────────────────────────────────────────┐
|
|
327
|
+
│ 1. EXTRACT AREA from what user said/showed: │
|
|
328
|
+
│ → What screen / feature / module did they mention? │
|
|
329
|
+
│ → Did they paste code? → that IS the area │
|
|
330
|
+
│ → Did they describe behavior? → extract the feature │
|
|
331
|
+
│ → Did they say "this file" / "this screen"? │
|
|
332
|
+
│ → use the file they're looking at │
|
|
333
|
+
│ → Still unclear? → ASK: "Which screen or feature │
|
|
334
|
+
│ should I check?" │
|
|
335
|
+
│ │
|
|
336
|
+
│ 2. SEARCH PROJECT for that area (broad search): │
|
|
337
|
+
│ → Grep "[feature name]" src/ │
|
|
338
|
+
│ → Glob "**/*[ScreenName]*" "**/*[featureName]*" │
|
|
339
|
+
│ → Read ALL matched files (not just 1 — scan widely) │
|
|
340
|
+
│ → Also read related: imports, hooks, services, store │
|
|
341
|
+
│ │
|
|
342
|
+
│ 3. RUN FULL SCAN CHECKLIST on code you just read: │
|
|
343
|
+
│ → Walk through Step 5 checklist below SYSTEMATICALLY │
|
|
344
|
+
│ → For EACH file, check: │
|
|
345
|
+
│ □ Crash risks (null access, missing try/catch) │
|
|
346
|
+
│ □ Memory leaks (useEffect cleanup, listeners) │
|
|
347
|
+
│ □ Race conditions (async without guard) │
|
|
348
|
+
│ □ Security (tokens, secrets, unvalidated input) │
|
|
349
|
+
│ □ Performance (inline functions, missing memo) │
|
|
350
|
+
│ □ UX (missing states, accessibility) │
|
|
351
|
+
│ → Check data flow: API call → state → render │
|
|
352
|
+
│ → Check edge cases: empty data, error response, │
|
|
353
|
+
│ network offline, slow response │
|
|
354
|
+
│ │
|
|
355
|
+
│ 4. REPORT (structured — ALWAYS do this): │
|
|
356
|
+
│ ┌───────────────────────────────────────────────┐ │
|
|
357
|
+
│ │ Scanned: [N files] in [area/feature name] │ │
|
|
358
|
+
│ │ │ │
|
|
359
|
+
│ │ 🔴 Issues found: │ │
|
|
360
|
+
│ │ 1. [SEVERITY] [file:line] — [description] │ │
|
|
361
|
+
│ │ 2. [SEVERITY] [file:line] — [description] │ │
|
|
362
|
+
│ │ │ │
|
|
363
|
+
│ │ 🟡 Suspicious (might be intentional): │ │
|
|
364
|
+
│ │ 1. [file:line] — [what looks off] │ │
|
|
365
|
+
│ │ │ │
|
|
366
|
+
│ │ ✅ Looks good: │ │
|
|
367
|
+
│ │ - [aspect that's well-implemented] │ │
|
|
368
|
+
│ │ │ │
|
|
369
|
+
│ │ Want me to fix issue #1? Or investigate │ │
|
|
370
|
+
│ │ [suspicious area] deeper? │ │
|
|
371
|
+
│ └───────────────────────────────────────────────┘ │
|
|
372
|
+
│ │
|
|
373
|
+
│ 5. WAIT for user decision — don't auto-fix │
|
|
374
|
+
│ │
|
|
375
|
+
│ ⛔ NEVER say "I don't see any issues" without having │
|
|
376
|
+
│ actually searched and read the project files │
|
|
377
|
+
│ ⛔ NEVER skip the scan — even if code "looks fine" │
|
|
378
|
+
│ at first glance, run the full checklist │
|
|
379
|
+
│ ⛔ NEVER suggest fixes before showing the scan report │
|
|
380
|
+
└─────────────────────────────────────────────────────────┘
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
---
|
|
384
|
+
|
|
385
|
+
## STEP 5: Scan Checklist (by severity)
|
|
8
386
|
|
|
9
387
|
### 1. Crash Risks (CRITICAL)
|
|
10
388
|
```
|
|
@@ -13,59 +391,65 @@
|
|
|
13
391
|
├── Unhandled null on API response
|
|
14
392
|
├── Missing try/catch on async ops
|
|
15
393
|
├── Missing error boundaries (RN)
|
|
16
|
-
├── Infinite recursion
|
|
394
|
+
├── Infinite recursion / render loop
|
|
17
395
|
└── Division by zero
|
|
18
396
|
```
|
|
19
397
|
|
|
20
398
|
### 2. Memory Leaks (HIGH)
|
|
21
399
|
```
|
|
22
400
|
RN: useEffect without cleanup, listeners not removed, timers not cleared
|
|
23
|
-
Flutter: StreamSubscription/Controller not disposed
|
|
24
|
-
iOS: [weak self] missing, observers not removed
|
|
25
|
-
Android: Context leak, BroadcastReceiver not unregistered
|
|
401
|
+
Flutter: StreamSubscription/Controller not disposed, TextEditingController leak
|
|
402
|
+
iOS: [weak self] missing in closures, NotificationCenter observers not removed
|
|
403
|
+
Android: Context leak in static ref, BroadcastReceiver not unregistered, Cursor not closed
|
|
26
404
|
```
|
|
27
405
|
|
|
28
406
|
### 3. Race Conditions (HIGH)
|
|
29
407
|
```
|
|
30
408
|
├── Button tappable during async op → add isSubmitting flag
|
|
31
|
-
├── setState after unmount → track mounted state
|
|
32
|
-
├── Multiple
|
|
33
|
-
|
|
409
|
+
├── setState after unmount → track mounted state / AbortController
|
|
410
|
+
├── Multiple 401 responses → queue token refresh (single retry)
|
|
411
|
+
├── Optimistic update without rollback → save previous state
|
|
412
|
+
└── Concurrent API calls modifying same state → mutex / queue
|
|
34
413
|
```
|
|
35
414
|
|
|
36
415
|
### 4. Security (HIGH)
|
|
37
416
|
```
|
|
38
|
-
├── Hardcoded secrets → env / secure config
|
|
417
|
+
├── Hardcoded API keys / secrets → .env / secure config
|
|
39
418
|
├── Tokens in AsyncStorage/SharedPrefs → SecureStore/Keychain
|
|
40
|
-
├── Sensitive data in
|
|
41
|
-
├── Deep links unvalidated → validate
|
|
42
|
-
└── Debug mode in release → strip
|
|
419
|
+
├── Sensitive data in console.log → strip before logging
|
|
420
|
+
├── Deep links with unvalidated params → validate + sanitize
|
|
421
|
+
└── Debug mode flags in release build → strip via build config
|
|
43
422
|
```
|
|
44
423
|
|
|
45
424
|
### 5. Performance (MEDIUM)
|
|
46
425
|
```
|
|
47
|
-
├── ScrollView for
|
|
48
|
-
├── Inline functions in render → useCallback/
|
|
49
|
-
├──
|
|
50
|
-
├── Large images unoptimized → resize, cache
|
|
51
|
-
├── Main thread blocking → background
|
|
52
|
-
└── Missing pagination → add cursor/offset
|
|
426
|
+
├── ScrollView for 50+ items → FlatList/ListView.builder/LazyColumn
|
|
427
|
+
├── Inline functions in render → useCallback/useMemo/const
|
|
428
|
+
├── Array index as key → stable unique ID
|
|
429
|
+
├── Large images unoptimized → resize, compress, cache, lazy load
|
|
430
|
+
├── Main thread blocking → offload to background
|
|
431
|
+
└── Missing pagination → add cursor/offset pagination
|
|
53
432
|
```
|
|
54
433
|
|
|
55
434
|
### 6. UX (MEDIUM)
|
|
56
435
|
```
|
|
57
|
-
├── Touch targets < 44pt/48dp
|
|
58
|
-
├── Missing loading/error/empty states
|
|
59
|
-
├── No keyboard dismiss
|
|
60
|
-
├── Missing safe area handling
|
|
61
|
-
└── No accessibility labels
|
|
436
|
+
├── Touch targets < 44pt (iOS) / 48dp (Android)
|
|
437
|
+
├── Missing loading / error / empty states
|
|
438
|
+
├── No keyboard dismiss on outside tap
|
|
439
|
+
├── Missing safe area handling (notch/island)
|
|
440
|
+
└── No accessibility labels (a11y)
|
|
62
441
|
```
|
|
63
442
|
|
|
443
|
+
---
|
|
444
|
+
|
|
64
445
|
## Report Format
|
|
65
446
|
|
|
66
447
|
```
|
|
67
448
|
🐛 [SEVERITY] — [file:line]
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
449
|
+
Type: [error classification from Step 0]
|
|
450
|
+
Issue: [description based on actual code read]
|
|
451
|
+
Cause: [root cause from project search, NOT generic guess]
|
|
452
|
+
Impact: [what breaks for the user]
|
|
453
|
+
Fix: [specific code change with before → after]
|
|
454
|
+
Source: [file:line where fix applies]
|
|
71
455
|
```
|