@rune-kit/rune 2.2.0 → 2.2.1

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 (144) hide show
  1. package/README.md +40 -34
  2. package/compiler/__tests__/pack-split.test.js +145 -0
  3. package/compiler/bin/rune.js +0 -5
  4. package/compiler/doctor.js +42 -0
  5. package/compiler/emitter.js +27 -4
  6. package/compiler/parser.js +41 -3
  7. package/compiler/transformer.js +10 -6
  8. package/compiler/transforms/compliance.js +40 -0
  9. package/extensions/ai-ml/PACK.md +38 -474
  10. package/extensions/ai-ml/skills/ai-agents.md +172 -0
  11. package/extensions/ai-ml/skills/code-sandbox.md +187 -0
  12. package/extensions/ai-ml/skills/deep-research.md +146 -0
  13. package/extensions/ai-ml/skills/embedding-search.md +66 -0
  14. package/extensions/ai-ml/skills/fine-tuning-guide.md +74 -0
  15. package/extensions/ai-ml/skills/llm-architect.md +125 -0
  16. package/extensions/ai-ml/skills/llm-integration.md +64 -0
  17. package/extensions/ai-ml/skills/prompt-patterns.md +72 -0
  18. package/extensions/ai-ml/skills/rag-patterns.md +66 -0
  19. package/extensions/ai-ml/skills/web-extraction.md +114 -0
  20. package/extensions/analytics/PACK.md +19 -484
  21. package/extensions/analytics/skills/ab-testing.md +72 -0
  22. package/extensions/analytics/skills/dashboard-patterns.md +83 -0
  23. package/extensions/analytics/skills/data-validation.md +68 -0
  24. package/extensions/analytics/skills/funnel-analysis.md +81 -0
  25. package/extensions/analytics/skills/sql-patterns.md +57 -0
  26. package/extensions/analytics/skills/statistical-analysis.md +79 -0
  27. package/extensions/analytics/skills/tracking-setup.md +71 -0
  28. package/extensions/backend/PACK.md +44 -618
  29. package/extensions/backend/skills/api-patterns.md +84 -0
  30. package/extensions/backend/skills/async-pipeline.md +193 -0
  31. package/extensions/backend/skills/auth-patterns.md +97 -0
  32. package/extensions/backend/skills/background-jobs.md +133 -0
  33. package/extensions/backend/skills/caching-patterns.md +108 -0
  34. package/extensions/backend/skills/cli-generation.md +133 -0
  35. package/extensions/backend/skills/database-patterns.md +87 -0
  36. package/extensions/backend/skills/middleware-patterns.md +104 -0
  37. package/extensions/chrome-ext/PACK.md +19 -921
  38. package/extensions/chrome-ext/skills/cws-preflight.md +143 -0
  39. package/extensions/chrome-ext/skills/cws-publish.md +104 -0
  40. package/extensions/chrome-ext/skills/ext-ai-integration.md +251 -0
  41. package/extensions/chrome-ext/skills/ext-messaging.md +139 -0
  42. package/extensions/chrome-ext/skills/ext-storage.md +133 -0
  43. package/extensions/chrome-ext/skills/mv3-scaffold.md +164 -0
  44. package/extensions/content/PACK.md +43 -335
  45. package/extensions/content/skills/blog-patterns.md +88 -0
  46. package/extensions/content/skills/cms-integration.md +131 -0
  47. package/extensions/content/skills/content-scoring.md +107 -0
  48. package/extensions/content/skills/i18n.md +83 -0
  49. package/extensions/content/skills/mdx-authoring.md +137 -0
  50. package/extensions/content/skills/reference.md +1014 -0
  51. package/extensions/content/skills/seo-patterns.md +67 -0
  52. package/extensions/content/skills/video-repurpose.md +153 -0
  53. package/extensions/devops/PACK.md +38 -457
  54. package/extensions/devops/skills/chaos-testing.md +67 -0
  55. package/extensions/devops/skills/ci-cd.md +75 -0
  56. package/extensions/devops/skills/docker.md +58 -0
  57. package/extensions/devops/skills/edge-serverless.md +163 -0
  58. package/extensions/devops/skills/infra-as-code.md +158 -0
  59. package/extensions/devops/skills/kubernetes.md +110 -0
  60. package/extensions/devops/skills/monitoring.md +57 -0
  61. package/extensions/devops/skills/server-setup.md +64 -0
  62. package/extensions/devops/skills/ssl-domain.md +42 -0
  63. package/extensions/ecommerce/PACK.md +62 -226
  64. package/extensions/ecommerce/skills/cart-system.md +79 -0
  65. package/extensions/ecommerce/skills/inventory-mgmt.md +102 -0
  66. package/extensions/ecommerce/skills/order-management.md +126 -0
  67. package/extensions/ecommerce/skills/payment-integration.md +472 -0
  68. package/extensions/ecommerce/skills/shopify-dev.md +69 -0
  69. package/extensions/ecommerce/skills/subscription-billing.md +93 -0
  70. package/extensions/ecommerce/skills/tax-compliance.md +117 -0
  71. package/extensions/gamedev/PACK.md +66 -317
  72. package/extensions/gamedev/skills/asset-pipeline.md +74 -0
  73. package/extensions/gamedev/skills/audio-system.md +129 -0
  74. package/extensions/gamedev/skills/camera-system.md +87 -0
  75. package/extensions/gamedev/skills/ecs.md +98 -0
  76. package/extensions/gamedev/skills/game-loops.md +72 -0
  77. package/extensions/gamedev/skills/input-system.md +199 -0
  78. package/extensions/gamedev/skills/multiplayer.md +180 -0
  79. package/extensions/gamedev/skills/particles.md +105 -0
  80. package/extensions/gamedev/skills/physics-engine.md +89 -0
  81. package/extensions/gamedev/skills/scene-management.md +146 -0
  82. package/extensions/gamedev/skills/threejs-patterns.md +90 -0
  83. package/extensions/gamedev/skills/webgl.md +71 -0
  84. package/extensions/mobile/PACK.md +56 -223
  85. package/extensions/mobile/skills/app-store-connect.md +152 -0
  86. package/extensions/mobile/skills/app-store-prep.md +66 -0
  87. package/extensions/mobile/skills/deep-linking.md +109 -0
  88. package/extensions/mobile/skills/flutter.md +60 -0
  89. package/extensions/mobile/skills/ios-build-pipeline.md +142 -0
  90. package/extensions/mobile/skills/native-bridge.md +66 -0
  91. package/extensions/mobile/skills/ota-updates.md +97 -0
  92. package/extensions/mobile/skills/push-notifications.md +111 -0
  93. package/extensions/mobile/skills/react-native.md +82 -0
  94. package/extensions/saas/PACK.md +26 -720
  95. package/extensions/saas/skills/billing-integration.md +121 -0
  96. package/extensions/saas/skills/feature-flags.md +130 -0
  97. package/extensions/saas/skills/multi-tenant.md +103 -0
  98. package/extensions/saas/skills/onboarding-flow.md +139 -0
  99. package/extensions/saas/skills/subscription-flow.md +95 -0
  100. package/extensions/saas/skills/team-management.md +144 -0
  101. package/extensions/security/PACK.md +10 -448
  102. package/extensions/security/skills/api-security.md +140 -0
  103. package/extensions/security/skills/compliance.md +68 -0
  104. package/extensions/security/skills/owasp-audit.md +64 -0
  105. package/extensions/security/skills/pentest-patterns.md +77 -0
  106. package/extensions/security/skills/secret-mgmt.md +65 -0
  107. package/extensions/security/skills/supply-chain.md +65 -0
  108. package/extensions/trading/PACK.md +18 -535
  109. package/extensions/trading/skills/chart-components.md +55 -0
  110. package/extensions/trading/skills/experiment-loop.md +125 -0
  111. package/extensions/trading/skills/fintech-patterns.md +47 -0
  112. package/extensions/trading/skills/indicator-library.md +58 -0
  113. package/extensions/trading/skills/quant-analysis.md +111 -0
  114. package/extensions/trading/skills/realtime-data.md +58 -0
  115. package/extensions/trading/skills/trade-logic.md +104 -0
  116. package/extensions/ui/PACK.md +34 -853
  117. package/extensions/ui/skills/a11y-audit.md +91 -0
  118. package/extensions/ui/skills/animation-patterns.md +106 -0
  119. package/extensions/ui/skills/component-patterns.md +75 -0
  120. package/extensions/ui/skills/design-decision.md +98 -0
  121. package/extensions/ui/skills/design-system.md +68 -0
  122. package/extensions/ui/skills/landing-patterns.md +155 -0
  123. package/extensions/ui/skills/palette-picker.md +162 -0
  124. package/extensions/ui/skills/react-health.md +90 -0
  125. package/extensions/ui/skills/type-system.md +125 -0
  126. package/extensions/ui/skills/web-vitals.md +153 -0
  127. package/extensions/zalo/PACK.md +117 -0
  128. package/extensions/zalo/skills/zalo-oa-mcp.md +317 -0
  129. package/extensions/zalo/skills/zalo-oa-messaging.md +429 -0
  130. package/extensions/zalo/skills/zalo-oa-setup.md +236 -0
  131. package/extensions/zalo/skills/zalo-oa-webhook.md +189 -0
  132. package/extensions/zalo/skills/zalo-personal-messaging.md +194 -0
  133. package/extensions/zalo/skills/zalo-personal-setup.md +153 -0
  134. package/extensions/zalo/skills/zalo-rate-guard.md +219 -0
  135. package/package.json +1 -1
  136. package/skills/brainstorm/SKILL.md +63 -1
  137. package/skills/cook/SKILL.md +84 -5
  138. package/skills/mcp-builder/SKILL.md +48 -1
  139. package/skills/review/SKILL.md +42 -5
  140. package/skills/review-intake/SKILL.md +17 -1
  141. package/skills/skill-router/SKILL.md +89 -7
  142. package/skills/team/SKILL.md +24 -1
  143. package/skills/test/SKILL.md +18 -0
  144. package/skills/verification/SKILL.md +40 -1
@@ -1,273 +1,106 @@
1
1
  ---
2
2
  name: "@rune/mobile"
3
- description: Mobile development patterns — React Native, Flutter, app store preparation, and native bridge integration.
3
+ description: Mobile development patterns — React Native, Flutter, deep linking, push notifications, OTA updates, app store preparation, native bridge integration, iOS build pipeline, and App Store Connect automation.
4
4
  metadata:
5
5
  author: runedev
6
- version: "0.1.0"
6
+ version: "0.3.0"
7
7
  layer: L4
8
8
  price: "$15"
9
9
  target: Mobile developers
10
+ format: split
10
11
  ---
11
12
 
12
13
  # @rune/mobile
13
14
 
14
15
  ## Purpose
15
16
 
16
- Mobile development has platform-specific pitfalls that web developers hit repeatedly: navigation stacks that leak memory, FlatList rendering that drops frames, state management that triggers unnecessary re-renders, native module bridges that crash on type mismatches, and app store rejections for metadata violations. This pack provides patterns for both React Native and Flutter — detect the framework, audit the codebase for mobile-specific anti-patterns, and emit fixes that pass platform review.
17
+ Mobile development has platform-specific pitfalls that web developers hit repeatedly: navigation stacks that leak memory, FlatList rendering that drops frames, New Architecture migration that silently breaks third-party libraries, deep links that work in dev but fail in production, push notifications that never arrive on iOS, OTA updates that crash on bytecode mismatch, and app store rejections for missing privacy manifests. This pack provides patterns for React Native and Flutter — detect the framework, audit for mobile-specific anti-patterns, and emit fixes that pass platform review.
17
18
 
18
19
  ## Triggers
19
20
 
20
21
  - Auto-trigger: when `react-native`, `expo`, `flutter`, `android/`, `ios/`, `app.json` (Expo) detected
21
22
  - `/rune react-native` — audit React Native architecture and performance
22
23
  - `/rune flutter` — audit Flutter architecture and state management
24
+ - `/rune deep-linking` — set up or audit deep linking (Universal Links, App Links)
25
+ - `/rune push-notifications` — set up or audit push notification pipeline
26
+ - `/rune ota-updates` — set up or audit OTA update strategy
23
27
  - `/rune app-store-prep` — prepare app store submission
24
28
  - `/rune native-bridge` — audit or create native module bridges
29
+ - `/rune ios-build` — end-to-end iOS build, sign, archive, upload pipeline
30
+ - `/rune app-store-connect` — App Store Connect API operations (versions, screenshots, localization, IAPs)
25
31
  - Called by `cook` (L1) when mobile task detected
26
32
  - Called by `team` (L1) when porting web to mobile
27
33
 
28
34
  ## Skills Included
29
35
 
30
- ### react-native
36
+ | Skill | Model | Description |
37
+ |-------|-------|-------------|
38
+ | react-native | sonnet | New Architecture migration, navigation, state management, performance optimization |
39
+ | flutter | sonnet | Widget composition, Riverpod/BLoC state, platform channels, adaptive layouts |
40
+ | deep-linking | sonnet | Universal Links (iOS), App Links (Android), auth + deep link race condition |
41
+ | push-notifications | sonnet | FCM v1, APNs, Expo Notifications, permission handling, delivery debugging |
42
+ | ota-updates | sonnet | EAS Update, runtime version management, rollback, bytecode compatibility |
43
+ | app-store-prep | sonnet | Screenshots, metadata, privacy manifests, submission checklist |
44
+ | native-bridge | sonnet | Expo Modules API, TurboModules, Swift/Kotlin interop, background tasks |
45
+ | ios-build-pipeline | sonnet | Certificate generation, provisioning, Xcode archive, IPA export, TestFlight upload |
46
+ | app-store-connect | sonnet | Version management, localization, screenshot upload, IAP, review submission |
31
47
 
32
- React Native patterns — navigation, state management, native modules, performance optimization, Expo vs bare workflow decisions.
33
-
34
- #### Workflow
35
-
36
- **Step 1 — Detect React Native setup**
37
- Use Grep to find framework markers: `react-native` in package.json, `expo` config, navigation library (`@react-navigation`, `expo-router`), state management (`zustand`, `redux`, `jotai`), and native module usage. Read `app.json`/`app.config.js` for Expo configuration.
38
-
39
- **Step 2 — Audit performance patterns**
40
- Check for: FlatList without `keyExtractor` or with inline `renderItem` (re-renders), images without caching (`FastImage` or `expo-image`), heavy re-renders from context (missing `useMemo`/`useCallback`), navigation listeners not cleaned up, large JS bundle without lazy loading (`React.lazy` + `Suspense`).
41
-
42
- **Step 3 — Emit optimized patterns**
43
- For each issue, emit the fix: memoized FlatList item components, proper image caching setup, navigation with typed routes, optimized state selectors, and Hermes engine configuration.
44
-
45
- #### Example
46
-
47
- ```tsx
48
- // BEFORE: FlatList anti-patterns — re-renders every item on any state change
49
- <FlatList
50
- data={items}
51
- renderItem={({ item }) => <ItemCard item={item} onPress={() => nav.navigate('Detail', { id: item.id })} />}
52
- />
53
-
54
- // AFTER: memoized components, stable callbacks, proper key extraction
55
- const MemoizedCard = React.memo(({ item, onPress }) => (
56
- <ItemCard item={item} onPress={onPress} />
57
- ));
58
-
59
- const renderItem = useCallback(({ item }) => (
60
- <MemoizedCard item={item} onPress={() => nav.navigate('Detail', { id: item.id })} />
61
- ), [nav]);
62
-
63
- <FlatList
64
- data={items}
65
- renderItem={renderItem}
66
- keyExtractor={item => item.id}
67
- getItemLayout={(_, index) => ({ length: ITEM_HEIGHT, offset: ITEM_HEIGHT * index, index })}
68
- maxToRenderPerBatch={10}
69
- windowSize={5}
70
- />
71
- ```
72
-
73
- ---
74
-
75
- ### flutter
76
-
77
- Flutter patterns — widget composition, state management (Riverpod, BLoC), platform channels, adaptive layouts.
78
-
79
- #### Workflow
80
-
81
- **Step 1 — Detect Flutter architecture**
82
- Use Grep to find state management (`riverpod`, `flutter_bloc`, `provider`, `get_it`), routing (`go_router`, `auto_route`), and platform channel usage. Read `pubspec.yaml` for dependencies and `lib/` structure for architecture pattern (feature-first, layer-first).
83
-
84
- **Step 2 — Audit widget tree and state**
85
- Check for: `setState` in complex widgets (should use state management), deeply nested widget trees (extract widgets), `BuildContext` passed through many layers (use InheritedWidget or Riverpod), missing `const` constructors (unnecessary rebuilds), platform-specific code without adaptive checks.
86
-
87
- **Step 3 — Emit refactored patterns**
88
- For each issue, emit: extracted widget with const constructor, Riverpod provider for state, proper error handling with `AsyncValue`, and adaptive layout using `LayoutBuilder` + breakpoints.
89
-
90
- #### Example
91
-
92
- ```dart
93
- // BEFORE: setState in complex widget, no separation
94
- class HomeScreen extends StatefulWidget { ... }
95
- class _HomeScreenState extends State<HomeScreen> {
96
- List<Item> items = [];
97
- bool loading = true;
98
-
99
- @override
100
- void initState() {
101
- super.initState();
102
- fetchItems().then((data) => setState(() { items = data; loading = false; }));
103
- }
104
- }
105
-
106
- // AFTER: Riverpod with AsyncValue, separated concerns
107
- @riverpod
108
- Future<List<Item>> items(Ref ref) async {
109
- final repo = ref.watch(itemRepositoryProvider);
110
- return repo.fetchAll();
111
- }
112
-
113
- class HomeScreen extends ConsumerWidget {
114
- const HomeScreen({super.key});
115
-
116
- @override
117
- Widget build(BuildContext context, WidgetRef ref) {
118
- final itemsAsync = ref.watch(itemsProvider);
119
- return itemsAsync.when(
120
- data: (items) => ItemList(items: items),
121
- loading: () => const ShimmerList(),
122
- error: (err, stack) => ErrorView(message: err.toString(), onRetry: () => ref.invalidate(itemsProvider)),
123
- );
124
- }
125
- }
126
- ```
127
-
128
- ---
129
-
130
- ### app-store-prep
131
-
132
- App store submission preparation — screenshots, metadata, privacy policy, review guidelines compliance, TestFlight/internal testing.
133
-
134
- #### Workflow
135
-
136
- **Step 1 — Audit submission readiness**
137
- Check for: app icon (1024x1024 for iOS, adaptive for Android), splash screen, privacy policy URL in app config, required permissions with usage descriptions (`NSCameraUsageDescription`, etc.), minimum SDK versions, and build configuration (release signing).
138
-
139
- **Step 2 — Generate metadata**
140
- From README and app config, generate: app title (30 chars max), subtitle (30 chars), description (4000 chars), keywords (100 chars), category selection, age rating questionnaire answers, and screenshot specifications per device size.
141
-
142
- **Step 3 — Emit submission checklist**
143
- Output a structured checklist covering both platforms: Apple App Store (TestFlight build, privacy declarations, review notes) and Google Play (internal testing track, data safety form, content rating questionnaire).
144
-
145
- #### Example
146
-
147
- ```markdown
148
- ## App Store Submission Checklist
149
-
150
- ### iOS (Apple App Store Connect)
151
- - [ ] App icon: 1024x1024 PNG, no alpha, no rounded corners
152
- - [ ] Screenshots: 6.7" (1290x2796), 6.5" (1242x2688), 5.5" (1242x2208)
153
- - [ ] Privacy policy URL: https://example.com/privacy
154
- - [ ] NSCameraUsageDescription: "Used to scan QR codes for quick login"
155
- - [ ] NSLocationWhenInUseUsageDescription: "Used to show nearby stores"
156
- - [ ] TestFlight build uploaded and tested
157
- - [ ] Export compliance: Uses HTTPS only (no custom encryption) → select "No"
158
-
159
- ### Android (Google Play Console)
160
- - [ ] Adaptive icon: foreground (108dp) + background layer
161
- - [ ] Feature graphic: 1024x500 PNG
162
- - [ ] Data safety form: camera (optional), location (optional)
163
- - [ ] Content rating: IARC questionnaire completed
164
- - [ ] Internal testing track: at least 1 build tested
165
- - [ ] Signing: upload key + app signing by Google Play enabled
166
- ```
167
-
168
- ---
169
-
170
- ### native-bridge
171
-
172
- Native bridge patterns — platform-specific code, native module creation, Swift/Kotlin interop, background tasks.
173
-
174
- #### Workflow
175
-
176
- **Step 1 — Detect bridge requirements**
177
- Use Grep to find platform-specific code: `Platform.OS`, `Platform.select`, `NativeModules`, `MethodChannel`, Turbo Modules (`TurboModule`), or Expo modules (`expo-modules-core`). Read existing native code in `ios/` and `android/` directories.
178
-
179
- **Step 2 — Audit bridge safety**
180
- Check for: type mismatches between JS/Dart and native (string expected, int sent), missing error handling on native side, synchronous bridge calls blocking UI thread, missing null checks on platform-specific returns, and hardcoded platform assumptions.
181
-
182
- **Step 3 — Emit type-safe bridge**
183
- For React Native: emit Turbo Module with codegen types or Expo Module with TypeScript interface. For Flutter: emit MethodChannel with proper error handling, type-safe serialization, and platform-specific implementations for both iOS (Swift) and Android (Kotlin).
184
-
185
- #### Example
186
-
187
- ```typescript
188
- // React Native — Expo Module (type-safe, modern approach)
189
- // modules/haptics/index.ts
190
- import { NativeModule, requireNativeModule } from 'expo-modules-core';
191
-
192
- interface HapticsModule extends NativeModule {
193
- impact(style: 'light' | 'medium' | 'heavy'): void;
194
- notification(type: 'success' | 'warning' | 'error'): void;
195
- }
196
-
197
- const HapticsNative = requireNativeModule<HapticsModule>('Haptics');
198
-
199
- export function impact(style: 'light' | 'medium' | 'heavy' = 'medium') {
200
- HapticsNative.impact(style);
201
- }
202
-
203
- // modules/haptics/ios/HapticsModule.swift
204
- import ExpoModulesCore
205
- import UIKit
206
-
207
- public class HapticsModule: Module {
208
- public func definition() -> ModuleDefinition {
209
- Name("Haptics")
210
- Function("impact") { (style: String) in
211
- let generator: UIImpactFeedbackGenerator
212
- switch style {
213
- case "light": generator = UIImpactFeedbackGenerator(style: .light)
214
- case "heavy": generator = UIImpactFeedbackGenerator(style: .heavy)
215
- default: generator = UIImpactFeedbackGenerator(style: .medium)
216
- }
217
- generator.impactOccurred()
218
- }
219
- }
220
- }
221
- ```
222
-
223
- ---
48
+ Skill files: `skills/<skill-name>.md`
224
49
 
225
50
  ## Connections
226
51
 
227
52
  ```
228
53
  Calls → browser-pilot (L3): device testing and screenshot automation
229
54
  Calls → asset-creator (L3): generate app icons and splash screens
55
+ Calls → sentinel (L2): audit push notification security, deep link validation
56
+ Calls → verification (L3): run mobile-specific checks (build, lint, type-check)
57
+ Calls → @rune/ui (L4): design system tokens, palette, typography for mobile UI consistency
58
+ Calls → @rune/backend (L4): API patterns for mobile backend integration (auth, push server)
59
+ Calls → @rune/security (L4): code signing audit, API key management, certificate validation
230
60
  Called By ← cook (L1): when mobile task detected
231
61
  Called By ← team (L1): when porting web to mobile
232
62
  Called By ← launch (L1): app store submission flow
63
+ Called By ← deploy (L2): mobile-specific deployment (EAS Build, Fastlane)
64
+ Inter-skill: ios-build-pipeline → app-store-prep (pipeline feeds into submission checklist)
65
+ Inter-skill: app-store-connect → app-store-prep (API automation completes manual checklist items)
66
+ Inter-skill: ios-build-pipeline → app-store-connect (upload build → attach to version → submit)
233
67
  ```
234
68
 
235
69
  ## Tech Stack Support
236
70
 
237
- | Framework | State Management | Navigation | Build |
238
- |-----------|-----------------|------------|-------|
239
- | React Native (bare) | Zustand / Redux | React Navigation v7 | Metro + Gradle/Xcode |
240
- | Expo (managed) | Zustand | Expo Router v4 | EAS Build |
241
- | Flutter | Riverpod / BLoC | GoRouter | Flutter CLI |
71
+ | Framework | State Management | Navigation | Build | OTA |
72
+ |-----------|-----------------|------------|-------|-----|
73
+ | React Native (bare) | Zustand / Redux | React Navigation v7 | Metro + Gradle/Xcode | CodePush |
74
+ | Expo (managed) | Zustand | Expo Router v4 | EAS Build | EAS Update |
75
+ | Flutter | Riverpod / BLoC | GoRouter | Flutter CLI | Shorebird |
76
+ | Native iOS (Swift) | SwiftUI @Observable | NavigationStack | xcodebuild | — |
242
77
 
243
- ## Constraints
78
+ ## Sharp Edges
244
79
 
245
- 1. MUST test on both iOS and Android — never assume cross-platform behavior is identical.
246
- 2. MUST NOT ship with debug configurations (Flipper, dev menu, debug signing) in production builds.
247
- 3. MUST include usage descriptions for every permission requested — empty descriptions cause instant rejection.
248
- 4. MUST use platform-adaptive components (Material on Android, Cupertino on iOS) or declare a unified design system.
249
- 5. MUST handle offline gracefully — mobile apps lose connectivity; show cached data or clear offline state.
80
+ Critical failures to know before using this pack:
250
81
 
251
- ## Sharp Edges
82
+ - **New Architecture** silently breaks legacy `NativeModules.X` and `setNativeProps` — audit all native deps against `reactnative.directory` before upgrading
83
+ - **OTA bytecode mismatch** crashes on launch — never deploy OTA update across React Native version boundaries; use `fingerprintExperimental` runtime version
84
+ - **Universal Links** silently break when AASA endpoint redirects (HTTP→HTTPS) — serve at exact path, verify with `curl -I`
85
+ - **Firebase Dynamic Links** shut down August 2025 — all `page.link` URLs dead; migrate to Branch.io or standard App Links
86
+ - **PrivacyInfo.xcprivacy** absence triggers auto-rejection on App Store (mandatory since April 2025)
87
+ - **FCM Legacy API** fully shut down June 2024 — must use FCM v1 with service account JSON
88
+ - **OpenSSL 3.x** `.p12` export silently fails without `-legacy` flag on macOS 14+
89
+ - **ASC API rate limit**: 200 req/min; JWT expires in 20 min — implement auto-refresh and exponential backoff
252
90
 
253
- | Failure Mode | Severity | Mitigation |
254
- |---|---|---|
255
- | FlatList optimization causes blank cells on fast scroll (windowSize too small) | HIGH | Default windowSize=5, test with 1000+ items before declaring optimized |
256
- | Native bridge type mismatch crashes app instead of returning error | CRITICAL | Always wrap native calls in try-catch; validate types before bridge call |
257
- | Expo managed workflow limits native module access | MEDIUM | Detect Expo vs bare in Step 1; suggest `expo prebuild` for native module needs |
258
- | App store rejection for missing privacy declaration | HIGH | Cross-reference every permission in Info.plist/AndroidManifest with usage description |
259
- | Flutter hot reload masks state bugs that appear in release mode | MEDIUM | Test with `flutter run --release` before declaring state management correct |
260
- | Screenshots generated at wrong device size fail store review | LOW | Use exact pixel dimensions from current App Store/Play Store requirements |
91
+ Full sharp edges table: see individual skill files.
261
92
 
262
93
  ## Done When
263
94
 
264
- - React Native/Flutter codebase audited for performance anti-patterns with specific fixes
265
- - FlatList/ListView optimized with memoization, key extraction, and window sizing
266
- - State management uses proper patterns (no `setState` in complex widgets)
267
- - App store metadata generated with correct dimensions, descriptions, and permissions
268
- - Native bridge typed and error-handled for both platforms
269
- - Structured report emitted for each skill invoked
95
+ - React Native/Flutter codebase audited for New Architecture compatibility with migration plan
96
+ - Deep links working on both platforms with authentication integration and real device verification
97
+ - Push notifications delivering reliably via FCM v1 with proper permission handling
98
+ - OTA update strategy configured with runtime version management and rollback procedure
99
+ - App store metadata generated with correct dimensions, privacy manifest, and platform-specific requirements
100
+ - Native bridges typed and error-handled for both platforms using modern APIs
101
+ - iOS build pipeline producing signed IPA with idempotent signing state
102
+ - App Store Connect operations automated — version, localization, screenshots, IAP, submission
270
103
 
271
104
  ## Cost Profile
272
105
 
273
- ~8,000–16,000 tokens per full pack run (all 4 skills). Individual skill: ~2,000–4,000 tokens. Sonnet default. Use haiku for config detection; escalate to sonnet for code generation and platform-specific patterns.
106
+ ~16,000–32,000 tokens per full pack run (all 9 skills). Individual skill: ~2,000–5,000 tokens. Sonnet default. Use haiku for config detection; escalate to sonnet for code generation, build pipeline, and ASC API patterns.
@@ -0,0 +1,152 @@
1
+ ---
2
+ name: "app-store-connect"
3
+ pack: "@rune/mobile"
4
+ description: "App Store Connect API automation — version management, localized store listings, screenshot upload, IAP/subscription creation, review submission, customer review monitoring."
5
+ model: sonnet
6
+ tools: [Read, Edit, Write, Grep, Glob, Bash]
7
+ ---
8
+
9
+ # app-store-connect
10
+
11
+ App Store Connect API automation — version management, localized store listings, screenshot upload, IAP/subscription creation, review submission, customer review monitoring.
12
+
13
+ #### Workflow
14
+
15
+ **Step 1 — Authenticate with ASC API**
16
+ App Store Connect uses JWT (ES256) with 20-minute expiry:
17
+ ```typescript
18
+ import jwt from 'jsonwebtoken';
19
+ import fs from 'fs';
20
+
21
+ function generateASCToken(keyId: string, issuerId: string, privateKeyPath: string): string {
22
+ const privateKey = fs.readFileSync(privateKeyPath, 'utf8');
23
+ return jwt.sign({}, privateKey, {
24
+ algorithm: 'ES256',
25
+ expiresIn: '20m',
26
+ issuer: issuerId,
27
+ header: {
28
+ alg: 'ES256',
29
+ kid: keyId,
30
+ typ: 'JWT',
31
+ },
32
+ audience: 'appstoreconnect-v1',
33
+ });
34
+ }
35
+ ```
36
+ Sharp edge: Token expires in 20 min — must auto-refresh when within 60s of expiry. Rate limit: 200 requests/minute, 429 response requires exponential backoff.
37
+
38
+ **Step 2 — Version management**
39
+ Create new App Store version:
40
+ ```
41
+ POST /v1/appStoreVersions
42
+ {
43
+ "data": {
44
+ "type": "appStoreVersions",
45
+ "attributes": {
46
+ "platform": "IOS",
47
+ "versionString": "1.2.0"
48
+ },
49
+ "relationships": {
50
+ "app": { "data": { "type": "apps", "id": "<app-id>" } }
51
+ }
52
+ }
53
+ }
54
+ ```
55
+ - Only ONE editable version allowed per platform at a time
56
+ - Cannot create version if existing version is "Pending Developer Release"
57
+ - Version string must be higher than current live version (semver)
58
+
59
+ **Step 3 — Localized store listing**
60
+ For each locale (`en-US`, `ja`, `de-DE`, etc.):
61
+ - `description` (4000 chars max)
62
+ - `keywords` (100 chars max, comma-separated)
63
+ - `whatsNew` (4000 chars, release notes)
64
+ - `promotionalText` (170 chars, can be updated without new version)
65
+
66
+ **Step 4 — Screenshot upload (chunked reservation)**
67
+ ASC uses a 3-step upload process:
68
+ 1. Reserve upload: `POST /v1/appScreenshots` with `fileName`, `fileSize` → get `uploadOperations` array
69
+ 2. Upload chunks: PUT each chunk to the returned URLs with correct `Content-Length` and offset headers
70
+ 3. Commit: `PATCH /v1/appScreenshots/{id}` with `uploaded: true` and SHA-256 `sourceFileChecksum`
71
+
72
+ Sharp edges:
73
+ - Chunk size dictated by API response, NOT configurable client-side
74
+ - Must send ALL chunks before commit or upload silently fails
75
+ - Screenshot dimensions must EXACTLY match device class (e.g., 1320×2868 for 6.9")
76
+ - Maximum 10 screenshots per locale per device class
77
+
78
+ **Step 5 — In-App Purchase & subscription management**
79
+ Create IAP:
80
+ ```
81
+ POST /v1/inAppPurchases
82
+ { "type": "inAppPurchases", "attributes": { "name": "Pro Upgrade", "productId": "com.example.pro", "inAppPurchaseType": "NON_CONSUMABLE" } }
83
+ ```
84
+ For subscriptions: create subscription group first, then subscription within group, then set pricing per territory. Territory pricing requires concurrent requests with retry — ASC rate limits per-territory pricing endpoints aggressively.
85
+
86
+ **Step 6 — Submission readiness check**
87
+ Before submitting for review, verify completeness:
88
+ - [ ] App Store version exists with build attached
89
+ - [ ] All required locales have description, keywords, screenshots
90
+ - [ ] Screenshots uploaded for ALL required device classes (6.9", 6.7", 6.5")
91
+ - [ ] Age rating questionnaire completed
92
+ - [ ] App review contact info set (first name, last name, phone, email)
93
+ - [ ] Privacy policy URL set
94
+ - [ ] Export compliance answered
95
+ - [ ] Content rights declaration completed (if app has third-party content)
96
+
97
+ **Step 7 — Submit and monitor**
98
+ ```
99
+ POST /v1/appStoreVersionSubmissions
100
+ { "data": { "relationships": { "appStoreVersion": { "data": { "type": "appStoreVersions", "id": "<version-id>" } } } } }
101
+ ```
102
+ Poll `GET /v1/appStoreVersions/{id}` for `appStoreState` transitions: `WAITING_FOR_REVIEW` → `IN_REVIEW` → `READY_FOR_SALE` (or `REJECTED`). On rejection: fetch `appStoreVersionSubmissions` for reviewer notes.
103
+
104
+ #### Example
105
+
106
+ ```typescript
107
+ // Complete ASC API client pattern
108
+ interface ASCClient {
109
+ // Auth
110
+ refreshToken(): string;
111
+
112
+ // Apps
113
+ listApps(): Promise<ASCApp[]>;
114
+ getApp(id: string): Promise<ASCApp>;
115
+
116
+ // Versions
117
+ createVersion(appId: string, version: string): Promise<ASCVersion>;
118
+ attachBuild(versionId: string, buildId: string): Promise<void>;
119
+
120
+ // Localization
121
+ updateLocalization(versionId: string, locale: string, data: LocalizationData): Promise<void>;
122
+
123
+ // Screenshots (3-step)
124
+ reserveScreenshot(setId: string, fileName: string, fileSize: number): Promise<UploadOps>;
125
+ uploadChunks(ops: UploadOps, fileBuffer: Buffer): Promise<void>;
126
+ commitScreenshot(screenshotId: string, checksum: string): Promise<void>;
127
+
128
+ // IAP
129
+ createIAP(appId: string, name: string, productId: string, type: IAPType): Promise<ASCIAP>;
130
+
131
+ // Submission
132
+ checkReadiness(versionId: string): Promise<ReadinessReport>;
133
+ submitForReview(versionId: string): Promise<void>;
134
+ pollReviewStatus(versionId: string, intervalMs?: number): AsyncGenerator<ReviewStatus>;
135
+
136
+ // Reviews
137
+ listCustomerReviews(appId: string): Promise<CustomerReview[]>;
138
+ respondToReview(reviewId: string, body: string): Promise<void>;
139
+ }
140
+
141
+ // Pagination helper — ASC uses cursor-based pagination via `next` links
142
+ async function* paginate<T>(client: ASCClient, url: string): AsyncGenerator<T> {
143
+ let nextUrl: string | null = url;
144
+ while (nextUrl) {
145
+ const response = await client.request(nextUrl);
146
+ for (const item of response.data) {
147
+ yield item as T;
148
+ }
149
+ nextUrl = response.links?.next ?? null;
150
+ }
151
+ }
152
+ ```
@@ -0,0 +1,66 @@
1
+ ---
2
+ name: "app-store-prep"
3
+ pack: "@rune/mobile"
4
+ description: "App store submission preparation — screenshots, metadata, privacy manifests, review guidelines compliance, TestFlight/internal testing."
5
+ model: sonnet
6
+ tools: [Read, Edit, Write, Grep, Glob, Bash]
7
+ ---
8
+
9
+ # app-store-prep
10
+
11
+ App store submission preparation — screenshots, metadata, privacy manifests, review guidelines compliance, TestFlight/internal testing.
12
+
13
+ #### Workflow
14
+
15
+ **Step 1 — Audit submission readiness**
16
+ Check for:
17
+ - App icon: 1024x1024 for iOS (no alpha, no rounded corners), adaptive icon for Android
18
+ - Splash screen configured
19
+ - Privacy policy URL in app config
20
+ - Required permissions with specific (not generic) usage descriptions — "App requires access to your camera" gets rejected. Must be specific: "Used to scan QR codes for quick login"
21
+ - `PrivacyInfo.xcprivacy` present (mandatory since April 2025): Apple requires privacy manifest for apps using file timestamp, boot time, disk space, or UserDefaults APIs. React Native core and many libraries access these APIs. Missing manifest = auto-rejection
22
+ - Minimum SDK versions: iOS 18 SDK mandatory (Xcode 16+, April 2025), Android API 34 minimum
23
+ - Release signing configured (not debug)
24
+ - `.aab` format for Google Play (APK no longer accepted for new apps)
25
+
26
+ **Step 2 — Generate metadata**
27
+ From README and app config, generate: app title (30 chars max), subtitle (30 chars), description (4000 chars), keywords (100 chars), category selection, age rating questionnaire answers, and screenshot specifications per device size.
28
+
29
+ Current required screenshot sizes:
30
+ - iPhone 6.9" (1320×2868) — iPhone 16 Pro Max (NEW, required for new apps)
31
+ - iPhone 6.7" (1290×2796)
32
+ - iPhone 6.5" (1242×2688)
33
+ - iPad 12.9" (2048×2732) — if app supports iPad
34
+ - Android: feature graphic 1024×500
35
+
36
+ **Step 3 — Emit submission checklist**
37
+ Output structured checklist covering both platforms with platform-specific gotchas.
38
+
39
+ #### Example
40
+
41
+ ```markdown
42
+ ## App Store Submission Checklist
43
+
44
+ ### iOS (Apple App Store Connect)
45
+ - [ ] App icon: 1024x1024 PNG, no alpha, no rounded corners
46
+ - [ ] Screenshots: 6.9" (1320x2868), 6.7" (1290x2796), 6.5" (1242x2688)
47
+ - [ ] Privacy policy URL: https://example.com/privacy
48
+ - [ ] `PrivacyInfo.xcprivacy` included (MANDATORY since April 2025)
49
+ - [ ] NSCameraUsageDescription: "Used to scan QR codes for quick login" (SPECIFIC, not generic)
50
+ - [ ] NSLocationWhenInUseUsageDescription: "Used to show nearby stores on the map"
51
+ - [ ] TestFlight build uploaded and tested on physical device
52
+ - [ ] Export compliance: Uses HTTPS only (no custom encryption) → select "No"
53
+ - [ ] Built with Xcode 16+ / iOS 18 SDK (mandatory since April 2025)
54
+
55
+ ### Android (Google Play Console)
56
+ - [ ] Adaptive icon: foreground (108dp) + background layer
57
+ - [ ] Feature graphic: 1024x500 PNG
58
+ - [ ] App Bundle format (.aab, NOT .apk)
59
+ - [ ] Target API 34+ (Android 14)
60
+ - [ ] 64-bit native libraries included (32-bit only = rejection)
61
+ - [ ] Data safety form: accurately declare ALL collected data (analytics SDKs collect device IDs)
62
+ - [ ] `SCHEDULE_EXACT_ALARM` justified if using scheduled notifications
63
+ - [ ] Content rating: IARC questionnaire completed
64
+ - [ ] Internal testing track: at least 1 build tested
65
+ - [ ] Signing: upload key + app signing by Google Play enabled
66
+ ```
@@ -0,0 +1,109 @@
1
+ ---
2
+ name: "deep-linking"
3
+ pack: "@rune/mobile"
4
+ description: "Deep linking setup and debugging — Universal Links (iOS), App Links (Android), deferred deep links, authentication + deep link integration."
5
+ model: sonnet
6
+ tools: [Read, Edit, Write, Grep, Glob, Bash]
7
+ ---
8
+
9
+ # deep-linking
10
+
11
+ Deep linking setup and debugging — Universal Links (iOS), App Links (Android), deferred deep links, authentication + deep link integration.
12
+
13
+ #### Workflow
14
+
15
+ **Step 1 — Detect current deep link setup**
16
+ Use Grep to find: `expo-linking`, `Linking.addEventListener`, `useURL`, `expo-router` deep link config, `apple-app-site-association`, `assetlinks.json`, `IntentFilter` in `AndroidManifest.xml`. Check for React Navigation `linking` config or Expo Router file-based deep link handling.
17
+
18
+ **Step 2 — Audit deep link reliability**
19
+ Check for these common failure modes:
20
+ - **AASA file redirect**: `.well-known/apple-app-site-association` endpoint must not redirect (HTTP→HTTPS or www→non-www). Any redirect silently breaks Universal Links
21
+ - **AASA caching**: Apple CDN caches AASA aggressively (up to 24h). Changes appear correct on server but old version is served to devices
22
+ - **SHA-256 mismatch**: Dev/Preview builds use different signing key than Production. `assetlinks.json` must include ALL certificates (upload key + app signing key)
23
+ - **Multiple environments**: Staging and production need separate AASA entries with different bundle IDs and team IDs
24
+ - **Firebase Dynamic Links dead**: Shut down August 25, 2025. All `page.link` subdomains stopped working. Must migrate to Branch.io, custom server, or standard App Links/Universal Links
25
+ - **Simulator limitation**: Universal Links and App Links do not work on simulators. Must test on real physical devices
26
+
27
+ **Step 3 — Audit authentication + deep link integration**
28
+ Check for race condition: deep link arrives before auth state resolves. Pattern: capture initial URL, wait for auth, then navigate. In React Navigation v7, `NAVIGATE` action pushes new screen even for existing routes — deep link handler must check current route before navigating.
29
+
30
+ **Step 4 — Emit deep link configuration**
31
+ For Expo Router: verify file-based route structure matches expected deep link paths. For React Navigation v7: emit typed `linking` config with authentication gate. For server: emit AASA and `assetlinks.json` with correct team ID, bundle ID, and all signing certificates.
32
+
33
+ #### Example
34
+
35
+ ```typescript
36
+ // Expo Router — app/_layout.tsx with auth-gated deep link handling
37
+ import { useURL } from 'expo-linking';
38
+ import { useRouter, useSegments } from 'expo-router';
39
+
40
+ export default function RootLayout() {
41
+ const url = useURL();
42
+ const router = useRouter();
43
+ const segments = useSegments();
44
+ const { user, isLoading } = useAuth();
45
+ const pendingDeepLink = useRef<string | null>(null);
46
+
47
+ // Capture deep link before auth resolves
48
+ useEffect(() => {
49
+ if (url && isLoading) {
50
+ pendingDeepLink.current = url;
51
+ }
52
+ }, [url, isLoading]);
53
+
54
+ // Navigate after auth resolves
55
+ useEffect(() => {
56
+ if (isLoading) return;
57
+
58
+ const inAuthGroup = segments[0] === '(auth)';
59
+ if (!user && !inAuthGroup) {
60
+ router.replace('/login');
61
+ } else if (user && inAuthGroup) {
62
+ // Process pending deep link or go to home
63
+ if (pendingDeepLink.current) {
64
+ const path = new URL(pendingDeepLink.current).pathname;
65
+ pendingDeepLink.current = null;
66
+ router.replace(path);
67
+ } else {
68
+ router.replace('/');
69
+ }
70
+ }
71
+ }, [user, isLoading, segments]);
72
+
73
+ return <Slot />;
74
+ }
75
+ ```
76
+
77
+ ```json
78
+ // .well-known/apple-app-site-association — NO redirects on this endpoint
79
+ {
80
+ "applinks": {
81
+ "details": [
82
+ {
83
+ "appIDs": ["TEAMID.com.example.app", "TEAMID.com.example.app.staging"],
84
+ "components": [
85
+ { "/": "/product/*", "comment": "Product deep links" },
86
+ { "/": "/invite/*", "comment": "Invite deep links" }
87
+ ]
88
+ }
89
+ ]
90
+ }
91
+ }
92
+ ```
93
+
94
+ ```json
95
+ // .well-known/assetlinks.json — include BOTH upload key AND app signing key
96
+ [
97
+ {
98
+ "relation": ["delegate_permission/common.handle_all_urls"],
99
+ "target": {
100
+ "namespace": "android_app",
101
+ "package_name": "com.example.app",
102
+ "sha256_cert_fingerprints": [
103
+ "AA:BB:CC:...:upload_key_fingerprint",
104
+ "DD:EE:FF:...:app_signing_key_fingerprint"
105
+ ]
106
+ }
107
+ }
108
+ ]
109
+ ```