specweave 1.0.239 → 1.0.241

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 (161) hide show
  1. package/CLAUDE.md +31 -30
  2. package/README.md +1 -1
  3. package/bin/specweave.js +16 -0
  4. package/dist/plugins/specweave-ado/lib/ado-permission-gate.d.ts.map +1 -1
  5. package/dist/plugins/specweave-ado/lib/ado-permission-gate.js +17 -2
  6. package/dist/plugins/specweave-ado/lib/ado-permission-gate.js.map +1 -1
  7. package/dist/plugins/specweave-github/lib/github-feature-sync.d.ts +7 -0
  8. package/dist/plugins/specweave-github/lib/github-feature-sync.d.ts.map +1 -1
  9. package/dist/plugins/specweave-github/lib/github-feature-sync.js +53 -0
  10. package/dist/plugins/specweave-github/lib/github-feature-sync.js.map +1 -1
  11. package/dist/plugins/specweave-jira/lib/jira-permission-gate.d.ts.map +1 -1
  12. package/dist/plugins/specweave-jira/lib/jira-permission-gate.js +17 -2
  13. package/dist/plugins/specweave-jira/lib/jira-permission-gate.js.map +1 -1
  14. package/dist/plugins/specweave-testing/lib/playwright-cli-detector.d.ts +1 -0
  15. package/dist/plugins/specweave-testing/lib/playwright-cli-detector.d.ts.map +1 -1
  16. package/dist/plugins/specweave-testing/lib/playwright-cli-detector.js +7 -3
  17. package/dist/plugins/specweave-testing/lib/playwright-cli-detector.js.map +1 -1
  18. package/dist/plugins/specweave-testing/lib/playwright-cli-runner.d.ts.map +1 -1
  19. package/dist/plugins/specweave-testing/lib/playwright-cli-runner.js +27 -19
  20. package/dist/plugins/specweave-testing/lib/playwright-cli-runner.js.map +1 -1
  21. package/dist/plugins/specweave-testing/lib/playwright-routing.d.ts +8 -0
  22. package/dist/plugins/specweave-testing/lib/playwright-routing.d.ts.map +1 -1
  23. package/dist/plugins/specweave-testing/lib/playwright-routing.js +10 -7
  24. package/dist/plugins/specweave-testing/lib/playwright-routing.js.map +1 -1
  25. package/dist/src/adapters/agents-md-generator.js +1 -1
  26. package/dist/src/adapters/agents-md-generator.js.map +1 -1
  27. package/dist/src/adapters/claude/README.md +1 -1
  28. package/dist/src/adapters/claude-md-generator.js +1 -1
  29. package/dist/src/adapters/claude-md-generator.js.map +1 -1
  30. package/dist/src/cli/commands/init.d.ts.map +1 -1
  31. package/dist/src/cli/commands/init.js +10 -1
  32. package/dist/src/cli/commands/init.js.map +1 -1
  33. package/dist/src/cli/commands/refresh-marketplace.d.ts.map +1 -1
  34. package/dist/src/cli/commands/refresh-marketplace.js +7 -67
  35. package/dist/src/cli/commands/refresh-marketplace.js.map +1 -1
  36. package/dist/src/cli/commands/team.d.ts +20 -0
  37. package/dist/src/cli/commands/team.d.ts.map +1 -0
  38. package/dist/src/cli/commands/team.js +101 -0
  39. package/dist/src/cli/commands/team.js.map +1 -0
  40. package/dist/src/cli/helpers/init/claude-settings-env.d.ts +16 -0
  41. package/dist/src/cli/helpers/init/claude-settings-env.d.ts.map +1 -0
  42. package/dist/src/cli/helpers/init/claude-settings-env.js +44 -0
  43. package/dist/src/cli/helpers/init/claude-settings-env.js.map +1 -0
  44. package/dist/src/cli/helpers/init/plugin-installer.d.ts.map +1 -1
  45. package/dist/src/cli/helpers/init/plugin-installer.js +9 -13
  46. package/dist/src/cli/helpers/init/plugin-installer.js.map +1 -1
  47. package/dist/src/cli/helpers/issue-tracker/index.d.ts.map +1 -1
  48. package/dist/src/cli/helpers/issue-tracker/index.js +12 -6
  49. package/dist/src/cli/helpers/issue-tracker/index.js.map +1 -1
  50. package/dist/src/cli/helpers/issue-tracker/types.d.ts +2 -0
  51. package/dist/src/cli/helpers/issue-tracker/types.d.ts.map +1 -1
  52. package/dist/src/cli/helpers/issue-tracker/types.js.map +1 -1
  53. package/dist/src/core/increment/discipline-checker.js +1 -1
  54. package/dist/src/core/increment/discipline-checker.js.map +1 -1
  55. package/dist/src/core/increment/status-commands.d.ts.map +1 -1
  56. package/dist/src/core/increment/status-commands.js +7 -0
  57. package/dist/src/core/increment/status-commands.js.map +1 -1
  58. package/dist/src/core/lazy-loading/llm-plugin-detector.d.ts +2 -2
  59. package/dist/src/core/lazy-loading/llm-plugin-detector.d.ts.map +1 -1
  60. package/dist/src/core/lazy-loading/llm-plugin-detector.js +63 -25
  61. package/dist/src/core/lazy-loading/llm-plugin-detector.js.map +1 -1
  62. package/dist/src/core/reflection/reflect-handler.js +2 -2
  63. package/dist/src/core/reflection/reflect-handler.js.map +1 -1
  64. package/dist/src/core/session/handoff-context.js +2 -2
  65. package/dist/src/core/session/handoff-context.js.map +1 -1
  66. package/dist/src/sync/ado-reconciler.d.ts.map +1 -1
  67. package/dist/src/sync/ado-reconciler.js +21 -2
  68. package/dist/src/sync/ado-reconciler.js.map +1 -1
  69. package/dist/src/sync/engine.d.ts.map +1 -1
  70. package/dist/src/sync/engine.js +2 -0
  71. package/dist/src/sync/engine.js.map +1 -1
  72. package/dist/src/sync/github-reconciler.d.ts.map +1 -1
  73. package/dist/src/sync/github-reconciler.js +52 -26
  74. package/dist/src/sync/github-reconciler.js.map +1 -1
  75. package/dist/src/sync/jira-reconciler.d.ts.map +1 -1
  76. package/dist/src/sync/jira-reconciler.js +16 -3
  77. package/dist/src/sync/jira-reconciler.js.map +1 -1
  78. package/dist/src/sync/providers/ado.d.ts.map +1 -1
  79. package/dist/src/sync/providers/ado.js +4 -2
  80. package/dist/src/sync/providers/ado.js.map +1 -1
  81. package/dist/src/sync/providers/github.d.ts.map +1 -1
  82. package/dist/src/sync/providers/github.js +11 -0
  83. package/dist/src/sync/providers/github.js.map +1 -1
  84. package/dist/src/sync/providers/jira.d.ts.map +1 -1
  85. package/dist/src/sync/providers/jira.js +14 -2
  86. package/dist/src/sync/providers/jira.js.map +1 -1
  87. package/dist/src/sync/sync-coordinator.d.ts.map +1 -1
  88. package/dist/src/sync/sync-coordinator.js +31 -6
  89. package/dist/src/sync/sync-coordinator.js.map +1 -1
  90. package/dist/src/utils/auto-install.js +4 -4
  91. package/dist/src/utils/auto-install.js.map +1 -1
  92. package/package.json +2 -2
  93. package/plugins/FINAL-AUDIT-RECOMMENDATIONS.md +3 -3
  94. package/plugins/SKILLS-VS-AGENTS.md +1 -1
  95. package/plugins/specweave/PLUGIN.md +0 -2
  96. package/plugins/specweave/commands/export-skills.md +1 -1
  97. package/plugins/specweave/commands/role-orchestrator.md +1 -1
  98. package/plugins/specweave/hooks/log-decision.sh +6 -0
  99. package/plugins/specweave/hooks/stop-auto-v5.sh +17 -1
  100. package/plugins/specweave/hooks/stop-reflect.sh +16 -2
  101. package/plugins/specweave/hooks/stop-sync.sh +17 -9
  102. package/plugins/specweave/hooks/user-prompt-submit.sh +119 -35
  103. package/plugins/specweave/lib/vendor/sync/github-reconciler.js +52 -26
  104. package/plugins/specweave/lib/vendor/sync/github-reconciler.js.map +1 -1
  105. package/plugins/specweave/scripts/read-grill-context.sh +149 -0
  106. package/plugins/specweave/skills/code-review/SKILL.md +608 -0
  107. package/plugins/specweave/skills/done/SKILL.md +1 -1
  108. package/plugins/specweave/skills/grill/SKILL.md +91 -0
  109. package/plugins/specweave/skills/performance/SKILL.md +6 -0
  110. package/plugins/specweave/skills/security/SKILL.md +7 -0
  111. package/plugins/specweave/skills/security-patterns/SKILL.md +6 -0
  112. package/plugins/specweave/skills/tdd-orchestrator/SKILL.md +1 -1
  113. package/plugins/specweave/skills/team-build/SKILL.md +1 -1
  114. package/plugins/specweave/skills/team-orchestrate/SKILL.md +1 -1
  115. package/plugins/specweave/skills/tech-lead/SKILL.md +7 -0
  116. package/plugins/specweave-ado/lib/ado-permission-gate.js +18 -2
  117. package/plugins/specweave-ado/lib/ado-permission-gate.ts +19 -2
  118. package/plugins/specweave-frontend/skills/frontend/SKILL.md +138 -2
  119. package/plugins/specweave-frontend/skills/i18n-expert/SKILL.md +989 -0
  120. package/plugins/specweave-github/hooks/github-auto-create-handler.sh +23 -1
  121. package/plugins/specweave-github/lib/github-feature-sync.js +41 -0
  122. package/plugins/specweave-github/lib/github-feature-sync.ts +62 -0
  123. package/plugins/specweave-infrastructure/PLUGIN.md +2 -1
  124. package/plugins/specweave-infrastructure/skills/gcp-deep-dive/SKILL.md +1172 -0
  125. package/plugins/specweave-infrastructure/skills/observability/SKILL.md +6 -0
  126. package/plugins/specweave-infrastructure/skills/opentelemetry/SKILL.md +6 -0
  127. package/plugins/specweave-jira/lib/jira-permission-gate.js +18 -2
  128. package/plugins/specweave-jira/lib/jira-permission-gate.ts +19 -2
  129. package/plugins/specweave-mobile/PLUGIN.md +1 -2
  130. package/plugins/specweave-mobile/README.md +13 -12
  131. package/plugins/specweave-mobile/skills/capacitor-ionic/SKILL.md +4 -18
  132. package/plugins/specweave-mobile/skills/deep-linking-push/SKILL.md +4 -22
  133. package/plugins/specweave-mobile/skills/expo/SKILL.md +4 -24
  134. package/plugins/specweave-mobile/skills/mobile-testing/SKILL.md +4 -22
  135. package/plugins/specweave-mobile/skills/react-native-expert/SKILL.md +404 -47
  136. package/plugins/specweave-testing/PLUGIN.md +3 -11
  137. package/plugins/specweave-testing/lib/playwright-cli-detector.js +8 -3
  138. package/plugins/specweave-testing/lib/playwright-cli-detector.ts +8 -3
  139. package/plugins/specweave-testing/lib/playwright-cli-runner.js +25 -20
  140. package/plugins/specweave-testing/lib/playwright-cli-runner.ts +24 -19
  141. package/plugins/specweave-testing/lib/playwright-routing.js +1 -6
  142. package/plugins/specweave-testing/lib/playwright-routing.ts +11 -8
  143. package/plugins/specweave-testing/skills/accessibility-testing/SKILL.md +998 -0
  144. package/plugins/specweave-testing/skills/e2e-testing/SKILL.md +29 -28
  145. package/plugins/specweave-testing/skills/mutation-testing/SKILL.md +769 -0
  146. package/plugins/specweave-testing/skills/performance-testing/SKILL.md +961 -0
  147. package/plugins/specweave-testing/skills/qa-engineer/SKILL.md +2 -0
  148. package/plugins/specweave/.specweave/logs/decisions.jsonl +0 -12
  149. package/plugins/specweave/.specweave/logs/reflect/reflect.log +0 -8
  150. package/plugins/specweave/.specweave/logs/stop-auto.log +0 -6
  151. package/plugins/specweave/.specweave/logs/stop-sync.log +0 -10
  152. package/plugins/specweave/.specweave/state/dashboard.json +0 -43
  153. package/plugins/specweave/skills/infrastructure/SKILL.md +0 -86
  154. package/plugins/specweave/skills/qa-lead/SKILL.md +0 -77
  155. package/plugins/specweave-mobile/skills/mobile-architect/SKILL.md +0 -30
  156. package/plugins/specweave-testing/commands/e2e-setup.md +0 -1103
  157. package/plugins/specweave-testing/commands/test-coverage.md +0 -983
  158. package/plugins/specweave-testing/commands/test-generate.md +0 -1160
  159. package/plugins/specweave-testing/commands/test-init.md +0 -413
  160. package/plugins/specweave-testing/commands/ui-automate.md +0 -182
  161. package/plugins/specweave-testing/commands/ui-inspect.md +0 -82
@@ -1,17 +1,98 @@
1
1
  ---
2
- description: React Native and Expo expert for environment setup, Metro bundler, native modules, device testing, performance optimization, and debugging. Use for RN setup, build issues, or mobile debugging.
2
+ description: React Native and Expo architect and expert. Architecture, setup, Metro bundler, native modules, New Architecture (Fabric, Turbo Modules, JSI), Expo Router, offline-first, performance, debugging. Use for mobile app architecture, RN setup, build issues, or debugging.
3
3
  allowed-tools: Read, Write, Edit, Bash, Glob, Grep
4
4
  model: opus
5
5
  context: fork
6
6
  ---
7
7
 
8
- # React Native Expert - Setup, Build, Debug, Performance
8
+ # React Native Expert - Architecture, Setup, Build, Debug, Performance
9
9
 
10
- Comprehensive React Native and Expo expertise covering environment setup, Metro bundler, native modules, device testing, performance optimization, and debugging.
10
+ Elite mobile application architect and hands-on expert specializing in **React Native** and **Expo**. Covers the full spectrum from system design and scalable architecture to environment setup, Metro bundler, native modules, device testing, performance optimization, and debugging. Deep expertise in the New Architecture (Fabric, Turbo Modules, JSI) and modern React concurrent features.
11
11
 
12
- ## Quick Setup Commands
12
+ ## Fetching Current Documentation
13
13
 
14
- ### Expo (Recommended)
14
+ **Before providing version-specific guidance, verify current versions.** Version numbers in static documentation become stale immediately. React Native releases every ~8 weeks. Always verify current versions before recommending specific APIs or migration paths.
15
+
16
+ For library documentation, use WebSearch or install Context7 manually: `claude plugin install context7@claude-plugins-official`
17
+
18
+ ---
19
+
20
+ ## Part 1: Architecture
21
+
22
+ ### Architecture Principles
23
+
24
+ 1. **Feature-based structure** over type-based (group by domain, not by file type)
25
+ 2. **Unidirectional data flow** with clear state boundaries
26
+ 3. **Platform abstraction** to isolate iOS/Android specifics
27
+ 4. **Offline-first** for mobile reliability
28
+ 5. **Lazy loading** screens and heavy modules for startup performance
29
+
30
+ ### Recommended Project Structure
31
+
32
+ ```
33
+ src/
34
+ ├── app/ # Expo Router screens (file-based routing)
35
+ │ ├── _layout.tsx
36
+ │ ├── (tabs)/
37
+ │ ├── (auth)/
38
+ │ └── [...missing].tsx
39
+ ├── features/ # Feature modules
40
+ │ ├── auth/
41
+ │ │ ├── components/
42
+ │ │ ├── hooks/
43
+ │ │ ├── services/
44
+ │ │ ├── stores/
45
+ │ │ └── types.ts
46
+ │ ├── feed/
47
+ │ └── profile/
48
+ ├── shared/ # Shared utilities
49
+ │ ├── components/
50
+ │ ├── hooks/
51
+ │ ├── services/
52
+ │ └── utils/
53
+ ├── providers/ # Context providers (theme, auth, query)
54
+ └── constants/
55
+ ```
56
+
57
+ ### State Management Selection Guide
58
+
59
+ | Solution | Use When | Persistence |
60
+ |----------|----------|-------------|
61
+ | Zustand | Most apps, simple global state | AsyncStorage via middleware |
62
+ | TanStack Query | Server state, caching, pagination | Built-in cache |
63
+ | Jotai | Fine-grained atomic state | AsyncStorage atoms |
64
+ | Legend State | High-frequency updates, real-time sync | Built-in persistence |
65
+
66
+ **Rule of thumb**: Use TanStack Query for server state + Zustand for client state. Avoid Redux unless team already uses it.
67
+
68
+ ### Offline-First Architecture
69
+
70
+ ```
71
+ ┌─────────────┐ ┌──────────────┐ ┌─────────┐
72
+ │ UI Layer │────▶│ Data Layer │────▶│ API │
73
+ │ (React) │◀────│ (Cache + │◀────│ (REST/ │
74
+ │ │ │ Queue) │ │ GQL) │
75
+ └─────────────┘ └──────────────┘ └─────────┘
76
+
77
+ ┌────▼────┐
78
+ │ SQLite │
79
+ │ or MMKV │
80
+ └─────────┘
81
+ ```
82
+
83
+ **Key patterns:**
84
+ - Read from local cache first, sync in background
85
+ - Queue writes when offline, replay on reconnect
86
+ - Use optimistic updates for perceived performance
87
+ - Conflict resolution: last-write-wins or CRDTs
88
+
89
+ ---
90
+
91
+ ## Part 2: Setup and Environment
92
+
93
+ ### Quick Setup Commands
94
+
95
+ #### Expo (Recommended)
15
96
 
16
97
  ```bash
17
98
  # Create new project
@@ -24,7 +105,7 @@ npx expo install expo-dev-client
24
105
  eas build --profile development --platform ios
25
106
  ```
26
107
 
27
- ### React Native CLI
108
+ #### React Native CLI
28
109
 
29
110
  ```bash
30
111
  # Create project (New Architecture enabled by default)
@@ -39,18 +120,46 @@ npm run ios
39
120
  npm run android
40
121
  ```
41
122
 
42
- ## Environment Requirements (2025)
123
+ ### Environment Requirements
43
124
 
44
125
  | Component | Minimum | Recommended |
45
126
  |-----------|---------|-------------|
46
127
  | Node.js | 20.x | 22 LTS |
47
- | React Native | 0.76+ | 0.83 |
48
- | Expo SDK | 52+ | 54 |
49
- | Xcode | 16.1 | 26 |
128
+ | React Native | 0.76+ | Latest stable |
129
+ | Expo SDK | 52+ | Latest stable |
130
+ | Xcode | 16.1 | Latest stable |
50
131
  | Android SDK | 34 | 35 |
51
132
  | CocoaPods | 1.14 | 1.15+ |
52
133
 
53
- ## Common Build Issues
134
+ **Always verify current versions before advising.**
135
+
136
+ ### Environment Variables
137
+
138
+ ```bash
139
+ # ~/.zshrc or ~/.bash_profile
140
+ export ANDROID_HOME=$HOME/Library/Android/sdk
141
+ export PATH=$PATH:$ANDROID_HOME/emulator
142
+ export PATH=$PATH:$ANDROID_HOME/platform-tools
143
+ export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin
144
+
145
+ # Reload
146
+ source ~/.zshrc
147
+ ```
148
+
149
+ ### Health Check
150
+
151
+ ```bash
152
+ node --version # 20+
153
+ xcodebuild -version # 16.1+
154
+ pod --version # 1.15+
155
+ adb --version
156
+ watchman version
157
+ eas --version # Expo
158
+ ```
159
+
160
+ ---
161
+
162
+ ## Part 3: Common Build Issues
54
163
 
55
164
  ### Metro Cache Issues
56
165
 
@@ -76,9 +185,33 @@ cd ios && rm -rf build Pods Podfile.lock && pod install && cd ..
76
185
  cd android && ./gradlew clean && cd ..
77
186
  ```
78
187
 
79
- ## Native Modules
188
+ ---
189
+
190
+ ## Part 4: New Architecture (Fabric, Turbo Modules, JSI)
80
191
 
81
- ### Creating Turbo Module
192
+ ### Fabric (New Rendering System)
193
+
194
+ Fabric replaces the old UIManager bridge with a synchronous, C++ rendering pipeline.
195
+
196
+ ```typescript
197
+ // Fabric is enabled by default in Expo SDK 52+
198
+ // In app.json / app.config.ts:
199
+ {
200
+ "expo": {
201
+ "newArchEnabled": true
202
+ }
203
+ }
204
+ ```
205
+
206
+ **Benefits of Fabric:**
207
+ - Synchronous layout calculations (no bridge delay)
208
+ - Concurrent rendering support (React 18 features)
209
+ - Shared C++ core between iOS and Android
210
+ - Better gesture handling and animations
211
+
212
+ ### Turbo Modules
213
+
214
+ TurboModules replace the old Native Modules system with lazy-loaded, type-safe native interfaces.
82
215
 
83
216
  ```typescript
84
217
  // specs/NativeCalculator.ts
@@ -87,11 +220,36 @@ import { TurboModuleRegistry } from 'react-native';
87
220
 
88
221
  export interface Spec extends TurboModule {
89
222
  add(a: number, b: number): number;
223
+ getDeviceModel(): string;
224
+ getBatteryLevel(): Promise<number>;
90
225
  }
91
226
 
92
227
  export default TurboModuleRegistry.getEnforcing<Spec>('NativeCalculator');
93
228
  ```
94
229
 
230
+ **Key advantages over old Native Modules:**
231
+ - Lazy initialization (loaded only when first accessed)
232
+ - Type-safe bridge via codegen
233
+ - Synchronous method calls possible via JSI
234
+
235
+ ### JSI (JavaScript Interface)
236
+
237
+ JSI provides direct communication between JS and native code without JSON serialization.
238
+
239
+ ```cpp
240
+ // C++ JSI host object example
241
+ class DeviceInfoHostObject : public jsi::HostObject {
242
+ public:
243
+ jsi::Value get(jsi::Runtime& rt, const jsi::PropNameID& name) override {
244
+ auto propName = name.utf8(rt);
245
+ if (propName == "model") {
246
+ return jsi::String::createFromUtf8(rt, getDeviceModel());
247
+ }
248
+ return jsi::Value::undefined();
249
+ }
250
+ };
251
+ ```
252
+
95
253
  ### Linking Native Code
96
254
 
97
255
  ```bash
@@ -100,7 +258,9 @@ cd ios && pod install
100
258
  cd android && ./gradlew build
101
259
  ```
102
260
 
103
- ## Performance Optimization
261
+ ---
262
+
263
+ ## Part 5: Performance Optimization
104
264
 
105
265
  ### Enable Hermes
106
266
 
@@ -108,7 +268,35 @@ cd android && ./gradlew build
108
268
  // android/app/build.gradle
109
269
  hermesEnabled = true
110
270
 
111
- // ios: Already default with New Architecture
271
+ // iOS: Already default with New Architecture
272
+ ```
273
+
274
+ ### Optimized List Rendering
275
+
276
+ ```typescript
277
+ import { FlashList } from '@shopify/flash-list';
278
+
279
+ <FlashList
280
+ data={items}
281
+ renderItem={({ item }) => <ItemCard item={item} />}
282
+ estimatedItemSize={80}
283
+ keyExtractor={(item) => item.id}
284
+ />
285
+ ```
286
+
287
+ ### Image Optimization
288
+
289
+ ```typescript
290
+ // Expo Image (recommended)
291
+ import { Image } from 'expo-image';
292
+
293
+ <Image
294
+ source={{ uri: imageUrl }}
295
+ placeholder={{ blurhash: 'LGF5]+Yk^6#M@-5c,1J5@[or[Q6.' }}
296
+ contentFit="cover"
297
+ transition={200}
298
+ cachePolicy="memory-disk"
299
+ />
112
300
  ```
113
301
 
114
302
  ### Performance Monitoring
@@ -123,19 +311,28 @@ new PerformanceObserver((list) => {
123
311
  }).observe({ entryTypes: ['measure'] });
124
312
  ```
125
313
 
126
- ### Image Optimization
127
-
128
- ```typescript
129
- // Use FastImage for better caching
130
- import FastImage from 'react-native-fast-image';
314
+ ### Bundle Size Analysis
131
315
 
132
- <FastImage
133
- source={{ uri: 'https://example.com/image.jpg' }}
134
- resizeMode={FastImage.resizeMode.cover}
135
- />
316
+ ```bash
317
+ # Analyze bundle with expo-atlas
318
+ EXPO_ATLAS=1 npx expo export --platform ios
319
+ npx expo-atlas path/to/atlas-file
136
320
  ```
137
321
 
138
- ## Device Testing
322
+ ### Performance Checklist
323
+
324
+ - [ ] Use FlashList over FlatList for long lists
325
+ - [ ] Memoize expensive computations with useMemo/React.memo
326
+ - [ ] Use expo-image instead of Image for caching and blurhash
327
+ - [ ] Profile with React DevTools Profiler
328
+ - [ ] Enable Hermes engine
329
+ - [ ] Avoid inline object/function creation in render
330
+ - [ ] Use useCallback for event handlers passed to children
331
+ - [ ] Lazy-load heavy screens with React.lazy + Suspense
332
+
333
+ ---
334
+
335
+ ## Part 6: Device Testing
139
336
 
140
337
  ### iOS Simulator
141
338
 
@@ -163,13 +360,15 @@ emulator -avd Pixel_8_API_35
163
360
  npx react-native run-android --deviceId <device-id>
164
361
  ```
165
362
 
166
- ## Debugging
363
+ ---
167
364
 
168
- ### Flipper (Deprecated)
365
+ ## Part 7: Debugging
366
+
367
+ ### Chrome DevTools / New Debugger
169
368
 
170
369
  ```bash
171
- # Use Chrome DevTools instead (RN 0.73+)
172
- # Press 'j' in Metro to open debugger
370
+ # RN 0.73+: Press 'j' in Metro to open debugger
371
+ # Replaces deprecated Flipper
173
372
  ```
174
373
 
175
374
  ### React DevTools
@@ -193,30 +392,188 @@ npx react-native start --reset-cache
193
392
  cd android && ./gradlew clean && cd ..
194
393
  ```
195
394
 
196
- ## Environment Variables
395
+ ### Network Debugging
197
396
 
198
- ```bash
199
- # ~/.zshrc or ~/.bash_profile
200
- export ANDROID_HOME=$HOME/Library/Android/sdk
201
- export PATH=$PATH:$ANDROID_HOME/emulator
202
- export PATH=$PATH:$ANDROID_HOME/platform-tools
203
- export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin
397
+ ```typescript
398
+ // In development, use React Native Debugger or Flipper Network plugin
399
+ // For production, use a logging service (Sentry, LogRocket)
400
+
401
+ // Quick debug proxy
402
+ if (__DEV__) {
403
+ // XMLHttpRequest interceptor for logging
404
+ const originalXHROpen = XMLHttpRequest.prototype.open;
405
+ XMLHttpRequest.prototype.open = function(...args) {
406
+ console.log('XHR:', args[0], args[1]);
407
+ return originalXHROpen.apply(this, args);
408
+ };
409
+ }
410
+ ```
411
+
412
+ ---
413
+
414
+ ## Part 8: Navigation with Expo Router
415
+
416
+ ### Directory Structure
204
417
 
205
- # Reload
206
- source ~/.zshrc
418
+ ```
419
+ app/
420
+ _layout.tsx # Root layout (providers, auth)
421
+ index.tsx # Home screen (/)
422
+ (tabs)/
423
+ _layout.tsx # Tab navigator
424
+ home.tsx # /home tab
425
+ profile.tsx # /profile tab
426
+ (auth)/
427
+ _layout.tsx # Auth group layout
428
+ login.tsx # /login
429
+ register.tsx # /register
430
+ settings/
431
+ _layout.tsx # Stack navigator for settings
432
+ index.tsx # /settings
433
+ [id].tsx # /settings/:id (dynamic route)
434
+ [...missing].tsx # 404 catch-all
207
435
  ```
208
436
 
209
- ## Health Check
437
+ ### Root Layout with Providers
210
438
 
211
- ```bash
212
- node --version # 20+
213
- xcodebuild -version # 16.1+
214
- pod --version # 1.15+
215
- adb --version
216
- watchman version
217
- eas --version # Expo
439
+ ```typescript
440
+ // app/_layout.tsx
441
+ import { Stack } from 'expo-router';
442
+ import { QueryClientProvider, QueryClient } from '@tanstack/react-query';
443
+ import { ThemeProvider } from '../providers/ThemeProvider';
444
+ import { AuthProvider } from '../providers/AuthProvider';
445
+
446
+ const queryClient = new QueryClient();
447
+
448
+ export default function RootLayout() {
449
+ return (
450
+ <QueryClientProvider client={queryClient}>
451
+ <AuthProvider>
452
+ <ThemeProvider>
453
+ <Stack screenOptions={{ headerShown: false }}>
454
+ <Stack.Screen name="(tabs)" />
455
+ <Stack.Screen name="(auth)" />
456
+ <Stack.Screen name="settings" options={{ presentation: 'modal' }} />
457
+ </Stack>
458
+ </ThemeProvider>
459
+ </AuthProvider>
460
+ </QueryClientProvider>
461
+ );
462
+ }
218
463
  ```
219
464
 
465
+ ### Navigation Patterns
466
+
467
+ ```typescript
468
+ import { router, useLocalSearchParams, Link } from 'expo-router';
469
+
470
+ // Imperative navigation
471
+ router.push('/settings/123');
472
+ router.replace('/home');
473
+ router.back();
474
+ router.navigate('/profile');
475
+
476
+ // Typed params
477
+ const { id } = useLocalSearchParams<{ id: string }>();
478
+
479
+ // Declarative link
480
+ <Link href="/settings/456" asChild>
481
+ <Pressable><Text>Go to Settings</Text></Pressable>
482
+ </Link>
483
+ ```
484
+
485
+ ---
486
+
487
+ ## Part 9: State Management Patterns
488
+
489
+ ### Zustand (Recommended for Most Apps)
490
+
491
+ ```typescript
492
+ import { create } from 'zustand';
493
+ import { persist, createJSONStorage } from 'zustand/middleware';
494
+ import AsyncStorage from '@react-native-async-storage/async-storage';
495
+
496
+ interface AuthStore {
497
+ token: string | null;
498
+ user: User | null;
499
+ login: (token: string, user: User) => void;
500
+ logout: () => void;
501
+ }
502
+
503
+ export const useAuthStore = create<AuthStore>()(
504
+ persist(
505
+ (set) => ({
506
+ token: null,
507
+ user: null,
508
+ login: (token, user) => set({ token, user }),
509
+ logout: () => set({ token: null, user: null }),
510
+ }),
511
+ {
512
+ name: 'auth-storage',
513
+ storage: createJSONStorage(() => AsyncStorage),
514
+ }
515
+ )
516
+ );
517
+ ```
518
+
519
+ ### Jotai (Atomic State)
520
+
521
+ ```typescript
522
+ import { atom, useAtom } from 'jotai';
523
+ import { atomWithStorage, createJSONStorage } from 'jotai/utils';
524
+ import AsyncStorage from '@react-native-async-storage/async-storage';
525
+
526
+ const storage = createJSONStorage<string>(() => AsyncStorage);
527
+ const themeAtom = atomWithStorage<'light' | 'dark'>('theme', 'light', storage);
528
+
529
+ const userAtom = atom<User | null>(null);
530
+ const isLoggedInAtom = atom((get) => get(userAtom) !== null);
531
+ ```
532
+
533
+ ---
534
+
535
+ ## Part 10: Testing
536
+
537
+ ### Unit and Component Testing
538
+
539
+ ```typescript
540
+ // Jest + React Native Testing Library
541
+ import { render, fireEvent, waitFor } from '@testing-library/react-native';
542
+ import { LoginScreen } from '../screens/LoginScreen';
543
+
544
+ describe('LoginScreen', () => {
545
+ it('shows error for invalid email', async () => {
546
+ const { getByPlaceholderText, getByText } = render(<LoginScreen />);
547
+ fireEvent.changeText(getByPlaceholderText('Email'), 'invalid');
548
+ fireEvent.press(getByText('Login'));
549
+ await waitFor(() => {
550
+ expect(getByText('Invalid email address')).toBeTruthy();
551
+ });
552
+ });
553
+ });
554
+ ```
555
+
556
+ ### E2E Testing with Detox
557
+
558
+ ```javascript
559
+ // e2e/login.test.ts
560
+ describe('Login Flow', () => {
561
+ beforeAll(async () => { await device.launchApp(); });
562
+ beforeEach(async () => { await device.reloadReactNative(); });
563
+
564
+ it('should login successfully', async () => {
565
+ await element(by.id('email-input')).typeText('user@example.com');
566
+ await element(by.id('password-input')).typeText('password123');
567
+ await element(by.id('login-button')).tap();
568
+ await expect(element(by.id('home-screen'))).toBeVisible();
569
+ });
570
+ });
571
+ ```
572
+
573
+ ---
574
+
220
575
  ## Related Skills
221
576
 
222
- - `mobile-architect` - Architecture decisions
577
+ - `expo` - Expo managed workflow, EAS Build/Submit, OTA updates, config plugins
578
+ - `mobile-testing` - Comprehensive testing strategies (XCTest, Espresso, Detox, Maestro)
579
+ - `deep-linking-push` - Deep linking and push notification details
@@ -15,17 +15,9 @@ Comprehensive testing infrastructure expert covering unit testing (Vitest/Jest),
15
15
  | qa-engineer | Expert QA engineer for test strategy and automation across unit, integration, E2E, accessibility, and performance testing |
16
16
  | e2e-testing | End-to-end testing expert for Playwright, Cypress, visual regression (Percy, Chromatic), and UI automation with debugging capabilities |
17
17
  | unit-testing | Unit testing and TDD expert for Vitest/Jest with red-green-refactor workflow, mocking strategies, coverage analysis, and ESM mocking patterns |
18
-
19
- ## Commands
20
-
21
- | Command | Description |
22
- |---------|-------------|
23
- | /sw-testing:test-init | Initialize comprehensive testing infrastructure with Vitest, Playwright, and testing best practices |
24
- | /sw-testing:test-generate | Generate test files from source code with coverage analysis and test templates |
25
- | /sw-testing:test-coverage | Analyze test coverage and identify gaps with coverage thresholds |
26
- | /sw-testing:e2e-setup | Set up end-to-end testing with Playwright or Cypress configuration |
27
- | /sw-testing:ui-automate | Automate UI testing with visual regression and accessibility checks |
28
- | /sw-testing:ui-inspect | Inspect UI elements and generate test locators for robust selectors |
18
+ | mutation-testing | Mutation testing expert using Stryker Mutator for TypeScript/JavaScript — setup, score analysis, survived mutant triage, and CI integration |
19
+ | performance-testing | Performance testing expert for k6, Artillery, Lighthouse CI, Core Web Vitals, and database performance benchmarking |
20
+ | accessibility-testing | Accessibility testing expert for axe-core, pa11y, WCAG compliance, screen reader testing, and keyboard navigation |
29
21
 
30
22
  ## Installation
31
23
 
@@ -1,14 +1,18 @@
1
- import { execSync } from "child_process";
1
+ import { execFileSync } from "child_process";
2
2
  let cachedResult = null;
3
+ function clearCache() {
4
+ cachedResult = null;
5
+ }
3
6
  function detectPlaywrightCli(options = {}) {
4
7
  const { useCache = false } = options;
5
8
  if (useCache && cachedResult) {
6
9
  return cachedResult;
7
10
  }
11
+ const whichCmd = process.platform === "win32" ? "where" : "which";
8
12
  let path;
9
13
  let version;
10
14
  try {
11
- path = execSync("which playwright-cli", {
15
+ path = execFileSync(whichCmd, ["playwright-cli"], {
12
16
  encoding: "utf-8",
13
17
  timeout: 5e3
14
18
  }).trim();
@@ -18,7 +22,7 @@ function detectPlaywrightCli(options = {}) {
18
22
  return result2;
19
23
  }
20
24
  try {
21
- version = execSync("playwright-cli --version", {
25
+ version = execFileSync("playwright-cli", ["--version"], {
22
26
  encoding: "utf-8",
23
27
  timeout: 5e3
24
28
  }).trim();
@@ -29,5 +33,6 @@ function detectPlaywrightCli(options = {}) {
29
33
  return result;
30
34
  }
31
35
  export {
36
+ clearCache,
32
37
  detectPlaywrightCli
33
38
  };
@@ -1,4 +1,4 @@
1
- import { execSync } from 'child_process';
1
+ import { execFileSync } from 'child_process';
2
2
 
3
3
  export interface CliDetectionResult {
4
4
  installed: boolean;
@@ -12,6 +12,10 @@ export interface DetectOptions {
12
12
 
13
13
  let cachedResult: CliDetectionResult | null = null;
14
14
 
15
+ export function clearCache(): void {
16
+ cachedResult = null;
17
+ }
18
+
15
19
  export function detectPlaywrightCli(options: DetectOptions = {}): CliDetectionResult {
16
20
  const { useCache = false } = options;
17
21
 
@@ -19,11 +23,12 @@ export function detectPlaywrightCli(options: DetectOptions = {}): CliDetectionRe
19
23
  return cachedResult;
20
24
  }
21
25
 
26
+ const whichCmd = process.platform === 'win32' ? 'where' : 'which';
22
27
  let path: string | undefined;
23
28
  let version: string | undefined;
24
29
 
25
30
  try {
26
- path = execSync('which playwright-cli', {
31
+ path = execFileSync(whichCmd, ['playwright-cli'], {
27
32
  encoding: 'utf-8',
28
33
  timeout: 5_000,
29
34
  }).trim();
@@ -34,7 +39,7 @@ export function detectPlaywrightCli(options: DetectOptions = {}): CliDetectionRe
34
39
  }
35
40
 
36
41
  try {
37
- version = execSync('playwright-cli --version', {
42
+ version = execFileSync('playwright-cli', ['--version'], {
38
43
  encoding: 'utf-8',
39
44
  timeout: 5_000,
40
45
  }).trim();