create-disposabl-app 0.0.4 → 0.1.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 (399) hide show
  1. package/dist/index.js +490 -105
  2. package/dist/templates/default/LICENSE +21 -0
  3. package/dist/templates/default/apps/blog/package.json +1 -0
  4. package/dist/templates/default/apps/changelog/package.json +1 -0
  5. package/dist/templates/default/apps/desktop/.oxfmtrc.json +5 -0
  6. package/dist/templates/default/apps/desktop/.oxlintrc.json +6 -0
  7. package/dist/templates/default/apps/desktop/README.md +58 -0
  8. package/dist/templates/default/apps/desktop/forge.config.mts +90 -0
  9. package/dist/templates/default/apps/desktop/index.html +12 -0
  10. package/dist/templates/default/apps/desktop/package.json +55 -0
  11. package/dist/templates/default/apps/desktop/src/declarations.d.ts +2 -0
  12. package/dist/templates/default/apps/desktop/src/index.css +8 -0
  13. package/dist/templates/default/apps/desktop/src/main.ts +58 -0
  14. package/dist/templates/default/apps/desktop/src/preload.ts +3 -0
  15. package/dist/templates/default/apps/desktop/src/renderer.ts +19 -0
  16. package/dist/templates/default/apps/desktop/tsconfig.json +14 -0
  17. package/dist/templates/default/apps/desktop/vite.main.config.mts +4 -0
  18. package/dist/templates/default/apps/desktop/vite.preload.config.mts +4 -0
  19. package/dist/templates/default/apps/desktop/vite.renderer.config.mts +4 -0
  20. package/dist/templates/default/apps/docs/package.json +1 -0
  21. package/dist/templates/default/apps/mobile/.agents/skills/agent-device/SKILL.md +22 -0
  22. package/dist/templates/default/apps/mobile/.agents/skills/android-emulator/SKILL.md +32 -0
  23. package/dist/templates/default/apps/mobile/.agents/skills/dogfood/SKILL.md +27 -0
  24. package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/SKILL.md +176 -0
  25. package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/agents/openai.yaml +4 -0
  26. package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/references/app-store-metadata.md +497 -0
  27. package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/references/ios-app-store.md +376 -0
  28. package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/references/native-ios.md +167 -0
  29. package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/references/play-store.md +244 -0
  30. package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/references/testflight.md +62 -0
  31. package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/references/workflows.md +120 -0
  32. package/dist/templates/default/apps/mobile/.agents/skills/eas-hosting/SKILL.md +431 -0
  33. package/dist/templates/default/apps/mobile/.agents/skills/eas-hosting/agents/openai.yaml +4 -0
  34. package/dist/templates/default/apps/mobile/.agents/skills/eas-observe/SKILL.md +46 -0
  35. package/dist/templates/default/apps/mobile/.agents/skills/eas-observe/agents/openai.yaml +4 -0
  36. package/dist/templates/default/apps/mobile/.agents/skills/eas-observe/references/metrics.md +98 -0
  37. package/dist/templates/default/apps/mobile/.agents/skills/eas-observe/references/queries.md +444 -0
  38. package/dist/templates/default/apps/mobile/.agents/skills/eas-observe/references/setup.md +529 -0
  39. package/dist/templates/default/apps/mobile/.agents/skills/eas-observe/references/third-party.md +136 -0
  40. package/dist/templates/default/apps/mobile/.agents/skills/eas-simulator/SKILL.md +237 -0
  41. package/dist/templates/default/apps/mobile/.agents/skills/eas-simulator/agents/openai.yaml +4 -0
  42. package/dist/templates/default/apps/mobile/.agents/skills/eas-simulator/references/controllers.md +139 -0
  43. package/dist/templates/default/apps/mobile/.agents/skills/eas-simulator/references/logs-and-crashes.md +101 -0
  44. package/dist/templates/default/apps/mobile/.agents/skills/eas-simulator/references/run-your-app.md +256 -0
  45. package/dist/templates/default/apps/mobile/.agents/skills/eas-simulator/references/troubleshooting.md +56 -0
  46. package/dist/templates/default/apps/mobile/.agents/skills/eas-update/SKILL.md +146 -0
  47. package/dist/templates/default/apps/mobile/.agents/skills/eas-update/agents/openai.yaml +4 -0
  48. package/dist/templates/default/apps/mobile/.agents/skills/eas-update-insights/SKILL.md +238 -0
  49. package/dist/templates/default/apps/mobile/.agents/skills/eas-update-insights/agents/openai.yaml +4 -0
  50. package/dist/templates/default/apps/mobile/.agents/skills/eas-update-insights/references/channel-insights-schema.md +47 -0
  51. package/dist/templates/default/apps/mobile/.agents/skills/eas-update-insights/references/update-insights-schema.md +69 -0
  52. package/dist/templates/default/apps/mobile/.agents/skills/eas-workflows/SKILL.md +99 -0
  53. package/dist/templates/default/apps/mobile/.agents/skills/eas-workflows/agents/openai.yaml +4 -0
  54. package/dist/templates/default/apps/mobile/.agents/skills/eas-workflows/scripts/fetch.js +109 -0
  55. package/dist/templates/default/apps/mobile/.agents/skills/eas-workflows/scripts/package.json +6 -0
  56. package/dist/templates/default/apps/mobile/.agents/skills/expo-animation/LICENSE +21 -0
  57. package/dist/templates/default/apps/mobile/.agents/skills/expo-animation/RECIPES.md +385 -0
  58. package/dist/templates/default/apps/mobile/.agents/skills/expo-animation/SKILL.md +274 -0
  59. package/dist/templates/default/apps/mobile/.agents/skills/expo-animation/agents/openai.yaml +4 -0
  60. package/dist/templates/default/apps/mobile/.agents/skills/expo-app-clip/SKILL.md +290 -0
  61. package/dist/templates/default/apps/mobile/.agents/skills/expo-app-clip/agents/openai.yaml +4 -0
  62. package/dist/templates/default/apps/mobile/.agents/skills/expo-app-clip/references/native-module.md +96 -0
  63. package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/SKILL.md +69 -0
  64. package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/agents/openai.yaml +4 -0
  65. package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/references/brownfield-integrated.md +551 -0
  66. package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/references/brownfield-isolated.md +449 -0
  67. package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/references/comparison.md +63 -0
  68. package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/references/feature-integration.md +163 -0
  69. package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/references/troubleshooting.md +88 -0
  70. package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/references/version-compatibility.md +40 -0
  71. package/dist/templates/default/apps/mobile/.agents/skills/expo-data-fetching/SKILL.md +478 -0
  72. package/dist/templates/default/apps/mobile/.agents/skills/expo-data-fetching/agents/openai.yaml +4 -0
  73. package/dist/templates/default/apps/mobile/.agents/skills/expo-data-fetching/references/expo-router-loaders.md +341 -0
  74. package/dist/templates/default/apps/mobile/.agents/skills/expo-data-fetching/references/offline-and-cancellation.md +68 -0
  75. package/dist/templates/default/apps/mobile/.agents/skills/expo-design-system/SKILL.md +376 -0
  76. package/dist/templates/default/apps/mobile/.agents/skills/expo-design-system/agents/openai.yaml +4 -0
  77. package/dist/templates/default/apps/mobile/.agents/skills/expo-design-system/references/audit.md +190 -0
  78. package/dist/templates/default/apps/mobile/.agents/skills/expo-design-system/references/native-slop.md +74 -0
  79. package/dist/templates/default/apps/mobile/.agents/skills/expo-dev-client/SKILL.md +184 -0
  80. package/dist/templates/default/apps/mobile/.agents/skills/expo-dev-client/agents/openai.yaml +4 -0
  81. package/dist/templates/default/apps/mobile/.agents/skills/expo-dom/SKILL.md +425 -0
  82. package/dist/templates/default/apps/mobile/.agents/skills/expo-dom/agents/openai.yaml +4 -0
  83. package/dist/templates/default/apps/mobile/.agents/skills/expo-examples/SKILL.md +106 -0
  84. package/dist/templates/default/apps/mobile/.agents/skills/expo-examples/agents/openai.yaml +4 -0
  85. package/dist/templates/default/apps/mobile/.agents/skills/expo-examples/references/catalog.md +105 -0
  86. package/dist/templates/default/apps/mobile/.agents/skills/expo-migrate-module/SKILL.md +124 -0
  87. package/dist/templates/default/apps/mobile/.agents/skills/expo-migrate-module/agents/openai.yaml +4 -0
  88. package/dist/templates/default/apps/mobile/.agents/skills/expo-migrate-module/references/compatibility.md +130 -0
  89. package/dist/templates/default/apps/mobile/.agents/skills/expo-migrate-module/references/example.md +212 -0
  90. package/dist/templates/default/apps/mobile/.agents/skills/expo-migrate-module/references/migration-map.md +457 -0
  91. package/dist/templates/default/apps/mobile/.agents/skills/expo-module/SKILL.md +151 -0
  92. package/dist/templates/default/apps/mobile/.agents/skills/expo-module/agents/openai.yaml +4 -0
  93. package/dist/templates/default/apps/mobile/.agents/skills/expo-module/references/config-plugin.md +90 -0
  94. package/dist/templates/default/apps/mobile/.agents/skills/expo-module/references/create-expo-module.md +206 -0
  95. package/dist/templates/default/apps/mobile/.agents/skills/expo-module/references/lifecycle.md +127 -0
  96. package/dist/templates/default/apps/mobile/.agents/skills/expo-module/references/module-config.md +48 -0
  97. package/dist/templates/default/apps/mobile/.agents/skills/expo-module/references/native-module.md +286 -0
  98. package/dist/templates/default/apps/mobile/.agents/skills/expo-module/references/native-view.md +171 -0
  99. package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/SKILL.md +201 -0
  100. package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/agents/openai.yaml +4 -0
  101. package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/controls.md +231 -0
  102. package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/gradients.md +106 -0
  103. package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/icons.md +232 -0
  104. package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/media.md +193 -0
  105. package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/storage.md +121 -0
  106. package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/visual-effects.md +198 -0
  107. package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/webgpu-three.md +605 -0
  108. package/dist/templates/default/apps/mobile/.agents/skills/expo-overview/SKILL.md +120 -0
  109. package/dist/templates/default/apps/mobile/.agents/skills/expo-overview/agents/openai.yaml +4 -0
  110. package/dist/templates/default/apps/mobile/.agents/skills/expo-overview/references/launch-without-dev-menu.md +24 -0
  111. package/dist/templates/default/apps/mobile/.agents/skills/expo-project-structure/SKILL.md +114 -0
  112. package/dist/templates/default/apps/mobile/.agents/skills/expo-project-structure/agents/openai.yaml +4 -0
  113. package/dist/templates/default/apps/mobile/.agents/skills/expo-router/SKILL.md +240 -0
  114. package/dist/templates/default/apps/mobile/.agents/skills/expo-router/agents/openai.yaml +4 -0
  115. package/dist/templates/default/apps/mobile/.agents/skills/expo-router/references/form-sheet.md +253 -0
  116. package/dist/templates/default/apps/mobile/.agents/skills/expo-router/references/route-structure.md +229 -0
  117. package/dist/templates/default/apps/mobile/.agents/skills/expo-router/references/search.md +248 -0
  118. package/dist/templates/default/apps/mobile/.agents/skills/expo-router/references/tabs.md +433 -0
  119. package/dist/templates/default/apps/mobile/.agents/skills/expo-router/references/toolbar-and-headers.md +284 -0
  120. package/dist/templates/default/apps/mobile/.agents/skills/expo-router/references/zoom-transitions.md +158 -0
  121. package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/SKILL.md +314 -0
  122. package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/agents/visual-grader.md +52 -0
  123. package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/references/design-rubric.md +45 -0
  124. package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/references/runtime-matrix.md +34 -0
  125. package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/check-static.sh +64 -0
  126. package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/clean-fixture.sh +56 -0
  127. package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/generate_viewer.py +450 -0
  128. package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/latest-sdk.sh +46 -0
  129. package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/make-fixture.sh +95 -0
  130. package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/make-workspace.sh +31 -0
  131. package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/snapshot-android.sh +284 -0
  132. package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/snapshot-ios.sh +132 -0
  133. package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/snapshot-web.sh +61 -0
  134. package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/SKILL.md +101 -0
  135. package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/agents/openai.yaml +4 -0
  136. package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/references/drop-in-replacements.md +27 -0
  137. package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/references/jetpack-compose.md +73 -0
  138. package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/references/swift-ui.md +73 -0
  139. package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/references/universal.md +104 -0
  140. package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/scripts/list-components.js +193 -0
  141. package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/SKILL.md +150 -0
  142. package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/agents/openai.yaml +4 -0
  143. package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/expo-av-to-audio.md +132 -0
  144. package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/expo-av-to-video.md +160 -0
  145. package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/native-tabs.md +124 -0
  146. package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/new-architecture.md +79 -0
  147. package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/react-19.md +79 -0
  148. package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/react-compiler.md +59 -0
  149. package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/react-navigation-to-expo-router.md +61 -0
  150. package/dist/templates/default/apps/mobile/.agents/skills/expo-web-to-native/SKILL.md +91 -0
  151. package/dist/templates/default/apps/mobile/.agents/skills/expo-web-to-native/agents/openai.yaml +4 -0
  152. package/dist/templates/default/apps/mobile/.agents/skills/expo-web-to-native/references/false-friends.md +119 -0
  153. package/dist/templates/default/apps/mobile/.agents/skills/expo-web-to-native/references/native-patterns.md +39 -0
  154. package/dist/templates/default/apps/mobile/.agents/skills/expo-web-to-native/references/run-as-goal.md +48 -0
  155. package/dist/templates/default/apps/mobile/.agents/skills/expo-web-to-native/references/verify-on-device.md +45 -0
  156. package/dist/templates/default/apps/mobile/.agents/skills/ios-simulator/SKILL.md +32 -0
  157. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/POWER.md +172 -0
  158. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/SKILL.md +238 -0
  159. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/agents/openai.yaml +4 -0
  160. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-analyze-app.md +208 -0
  161. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-analyze-js.md +264 -0
  162. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-barrel-exports.md +250 -0
  163. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-code-splitting.md +255 -0
  164. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-hermes-mmap.md +167 -0
  165. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-library-size.md +164 -0
  166. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-native-assets.md +208 -0
  167. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-r8-android.md +231 -0
  168. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-tree-shaking.md +215 -0
  169. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/bundle-treemap-source-map-explorer.png +0 -0
  170. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/controlled-textinput-pingpong.png +0 -0
  171. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/devtools-flamegraph.png +0 -0
  172. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/emerge-xray-ios.png +0 -0
  173. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/expo-atlas-treemap.png +0 -0
  174. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/flashlight-flatlist-vs-flashlist.png +0 -0
  175. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/fps-drop-graph.png +0 -0
  176. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/memory-heap-snapshot.png +0 -0
  177. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/tti-warm-start-diagram.png +0 -0
  178. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/view-hierarchy-flattening.png +0 -0
  179. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/xcode-instruments-templates.png +0 -0
  180. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/xcode-thread-view.png +0 -0
  181. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-animations-reanimated.md +273 -0
  182. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-atomic-state.md +190 -0
  183. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-bottomsheet.md +339 -0
  184. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-concurrent-react.md +238 -0
  185. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-lists-flatlist-flashlist.md +223 -0
  186. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-measure-fps.md +178 -0
  187. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-memory-leaks.md +168 -0
  188. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-profile-react.md +138 -0
  189. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-react-compiler.md +261 -0
  190. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-uncontrolled-components.md +219 -0
  191. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-android-16kb-alignment.md +114 -0
  192. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-measure-tti.md +221 -0
  193. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-memory-leaks.md +206 -0
  194. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-memory-patterns.md +240 -0
  195. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-platform-setup.md +112 -0
  196. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-profiling.md +140 -0
  197. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-sdks-over-polyfills.md +192 -0
  198. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-threading-model.md +230 -0
  199. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-turbo-modules.md +210 -0
  200. package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-view-flattening.md +180 -0
  201. package/dist/templates/default/apps/mobile/AGENTS.md +41 -0
  202. package/dist/templates/default/apps/mobile/app.json +38 -0
  203. package/dist/templates/default/apps/mobile/assets/expo.icon/Assets/expo-symbol 2.svg +3 -0
  204. package/dist/templates/default/apps/mobile/assets/expo.icon/Assets/grid.png +0 -0
  205. package/dist/templates/default/apps/mobile/assets/expo.icon/icon.json +40 -0
  206. package/dist/templates/default/apps/mobile/assets/images/android-icon-background.png +0 -0
  207. package/dist/templates/default/apps/mobile/assets/images/android-icon-foreground.png +0 -0
  208. package/dist/templates/default/apps/mobile/assets/images/android-icon-monochrome.png +0 -0
  209. package/dist/templates/default/apps/mobile/assets/images/icon.png +0 -0
  210. package/dist/templates/default/apps/mobile/assets/images/splash-icon.png +0 -0
  211. package/dist/templates/default/apps/mobile/eslint.config.js +10 -0
  212. package/dist/templates/default/apps/mobile/package.json +43 -0
  213. package/dist/templates/default/apps/mobile/skills-lock.json +185 -0
  214. package/dist/templates/default/apps/mobile/src/app/_layout.tsx +5 -0
  215. package/dist/templates/default/apps/mobile/src/app/index.tsx +17 -0
  216. package/dist/templates/default/apps/mobile/tsconfig.json +20 -0
  217. package/dist/templates/default/apps/web/.agents/skills/frontend-design/SKILL.md +71 -0
  218. package/dist/templates/default/apps/web/.agents/skills/web-design-guidelines/SKILL.md +39 -0
  219. package/dist/templates/default/apps/web/.env.example +3 -0
  220. package/dist/templates/default/apps/web/components.json +23 -0
  221. package/dist/templates/default/apps/web/eslint.config.ts +21 -0
  222. package/dist/templates/default/apps/web/package.json +39 -0
  223. package/dist/templates/default/apps/web/public/disposabl-logo.svg +8 -0
  224. package/dist/templates/default/apps/web/public/favicon.ico +0 -0
  225. package/dist/templates/default/apps/web/public/manifest.json +25 -0
  226. package/dist/templates/default/apps/web/skills-lock.json +17 -0
  227. package/dist/templates/default/apps/web/src/index.css +92 -0
  228. package/dist/templates/default/apps/web/src/routeTree.gen.ts +282 -0
  229. package/dist/templates/default/apps/web/src/router/__root.tsx +63 -0
  230. package/dist/templates/default/apps/web/src/router/_authenticated/dashboard.tsx +9 -0
  231. package/dist/templates/default/apps/web/src/router/_authenticated/todos/$id.tsx +27 -0
  232. package/dist/templates/default/apps/web/src/router/_authenticated/todos/index.tsx +33 -0
  233. package/dist/templates/default/apps/web/src/router/index.tsx +15 -0
  234. package/dist/templates/default/apps/web/src/router.tsx +20 -0
  235. package/dist/templates/default/apps/web/tsconfig.json +33 -0
  236. package/dist/templates/default/apps/web/tsr.config.json +6 -0
  237. package/dist/templates/default/apps/web/vite.config.ts +67 -0
  238. package/dist/templates/default/bun.lock +3932 -0
  239. package/dist/templates/default/bunfig.toml +5 -0
  240. package/dist/templates/default/disposabl.json +5 -0
  241. package/dist/templates/default/gitignore +10 -0
  242. package/dist/templates/default/package.json +31 -10
  243. package/dist/templates/default/packages/backend/.agents/skills/convex/SKILL.md +69 -0
  244. package/dist/templates/default/packages/backend/.agents/skills/convex-add/SKILL.md +26 -0
  245. package/dist/templates/default/packages/backend/.agents/skills/convex-advisor/SKILL.md +32 -0
  246. package/dist/templates/default/packages/backend/.agents/skills/convex-agent/SKILL.md +25 -0
  247. package/dist/templates/default/packages/backend/.agents/skills/convex-auth/SKILL.md +29 -0
  248. package/dist/templates/default/packages/backend/.agents/skills/convex-authz/SKILL.md +36 -0
  249. package/dist/templates/default/packages/backend/.agents/skills/convex-backup/SKILL.md +33 -0
  250. package/dist/templates/default/packages/backend/.agents/skills/convex-billing/SKILL.md +69 -0
  251. package/dist/templates/default/packages/backend/.agents/skills/convex-cost/SKILL.md +29 -0
  252. package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/SKILL.md +325 -0
  253. package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/agents/openai.yaml +14 -0
  254. package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/assets/icon.svg +3 -0
  255. package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/references/advanced-patterns.md +146 -0
  256. package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/references/hybrid-components.md +38 -0
  257. package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/references/local-components.md +39 -0
  258. package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/references/packaged-components.md +54 -0
  259. package/dist/templates/default/packages/backend/.agents/skills/convex-crons/SKILL.md +23 -0
  260. package/dist/templates/default/packages/backend/.agents/skills/convex-deploy-guard/SKILL.md +29 -0
  261. package/dist/templates/default/packages/backend/.agents/skills/convex-design/SKILL.md +30 -0
  262. package/dist/templates/default/packages/backend/.agents/skills/convex-docs/SKILL.md +31 -0
  263. package/dist/templates/default/packages/backend/.agents/skills/convex-domains/SKILL.md +26 -0
  264. package/dist/templates/default/packages/backend/.agents/skills/convex-env/SKILL.md +24 -0
  265. package/dist/templates/default/packages/backend/.agents/skills/convex-expert/SKILL.md +38 -0
  266. package/dist/templates/default/packages/backend/.agents/skills/convex-explain-app/SKILL.md +29 -0
  267. package/dist/templates/default/packages/backend/.agents/skills/convex-improve-convex-plugin/SKILL.md +24 -0
  268. package/dist/templates/default/packages/backend/.agents/skills/convex-insights/SKILL.md +32 -0
  269. package/dist/templates/default/packages/backend/.agents/skills/convex-launch-readiness/SKILL.md +35 -0
  270. package/dist/templates/default/packages/backend/.agents/skills/convex-migrate/SKILL.md +23 -0
  271. package/dist/templates/default/packages/backend/.agents/skills/convex-migrate-rehearse/SKILL.md +31 -0
  272. package/dist/templates/default/packages/backend/.agents/skills/convex-monitor/SKILL.md +22 -0
  273. package/dist/templates/default/packages/backend/.agents/skills/convex-optimize/SKILL.md +26 -0
  274. package/dist/templates/default/packages/backend/.agents/skills/convex-quickstart/SKILL.md +29 -0
  275. package/dist/templates/default/packages/backend/.agents/skills/convex-quickstart/agents/openai.yaml +14 -0
  276. package/dist/templates/default/packages/backend/.agents/skills/convex-quickstart/assets/icon.svg +4 -0
  277. package/dist/templates/default/packages/backend/.agents/skills/convex-reviewer/SKILL.md +26 -0
  278. package/dist/templates/default/packages/backend/.agents/skills/convex-seed/SKILL.md +23 -0
  279. package/dist/templates/default/packages/backend/.agents/skills/convex-self-heal/SKILL.md +38 -0
  280. package/dist/templates/default/packages/backend/.agents/skills/convex-sentinel/SKILL.md +25 -0
  281. package/dist/templates/default/packages/backend/.agents/skills/convex-suggest/SKILL.md +27 -0
  282. package/dist/templates/default/packages/backend/.agents/skills/convex-test/SKILL.md +23 -0
  283. package/dist/templates/default/packages/backend/.agents/skills/convex-verify/SKILL.md +34 -0
  284. package/dist/templates/default/packages/backend/.prettierignore +4 -0
  285. package/dist/templates/default/packages/backend/AGENTS.md +18 -0
  286. package/dist/templates/default/packages/backend/CLAUDE.md +13 -0
  287. package/dist/templates/default/packages/backend/README.md +25 -0
  288. package/dist/templates/default/packages/backend/convex/_generated/ai/ai-files.state.json +6 -0
  289. package/dist/templates/default/packages/backend/convex/_generated/ai/guidelines.md +286 -0
  290. package/dist/templates/default/packages/backend/convex/_generated/api.d.ts +66 -0
  291. package/dist/templates/default/packages/backend/convex/_generated/api.js +23 -0
  292. package/dist/templates/default/packages/backend/convex/_generated/dataModel.d.ts +60 -0
  293. package/dist/templates/default/packages/backend/convex/_generated/server.d.ts +164 -0
  294. package/dist/templates/default/packages/backend/convex/_generated/server.js +101 -0
  295. package/dist/templates/default/packages/backend/convex/auth.config.ts +14 -0
  296. package/dist/templates/default/packages/backend/convex/auth.ts +15 -0
  297. package/dist/templates/default/packages/backend/convex/convex.config.ts +30 -0
  298. package/dist/templates/default/packages/backend/convex/http.ts +5 -0
  299. package/dist/templates/default/packages/backend/convex/mcp.ts +8 -0
  300. package/dist/templates/default/packages/backend/convex/schema.ts +10 -0
  301. package/dist/templates/default/packages/backend/convex/todos/index.ts +26 -0
  302. package/dist/templates/default/packages/backend/convex/todos/internal.ts +43 -0
  303. package/dist/templates/default/packages/backend/convex/tsconfig.json +27 -0
  304. package/dist/templates/default/packages/backend/convex/users.ts +20 -0
  305. package/dist/templates/default/packages/backend/eslint.config.mjs +62 -0
  306. package/dist/templates/default/packages/backend/package.json +36 -0
  307. package/dist/templates/default/packages/backend/skills-lock.json +203 -0
  308. package/dist/templates/default/packages/disposabl-kit/client/components/ui/accordion.tsx +77 -0
  309. package/dist/templates/default/packages/disposabl-kit/client/components/ui/alert-dialog.tsx +185 -0
  310. package/dist/templates/default/packages/disposabl-kit/client/components/ui/alert.tsx +75 -0
  311. package/dist/templates/default/packages/disposabl-kit/client/components/ui/aspect-ratio.tsx +22 -0
  312. package/dist/templates/default/packages/disposabl-kit/client/components/ui/attachment.tsx +207 -0
  313. package/dist/templates/default/packages/disposabl-kit/client/components/ui/avatar.tsx +106 -0
  314. package/dist/templates/default/packages/disposabl-kit/client/components/ui/badge.tsx +51 -0
  315. package/dist/templates/default/packages/disposabl-kit/client/components/ui/breadcrumb.tsx +121 -0
  316. package/dist/templates/default/packages/disposabl-kit/client/components/ui/bubble.tsx +127 -0
  317. package/dist/templates/default/packages/disposabl-kit/client/components/ui/button-group.tsx +87 -0
  318. package/dist/templates/default/packages/disposabl-kit/client/components/ui/button.tsx +57 -0
  319. package/dist/templates/default/packages/disposabl-kit/client/components/ui/calendar.tsx +241 -0
  320. package/dist/templates/default/packages/disposabl-kit/client/components/ui/card.tsx +102 -0
  321. package/dist/templates/default/packages/disposabl-kit/client/components/ui/carousel.tsx +239 -0
  322. package/dist/templates/default/packages/disposabl-kit/client/components/ui/chart.tsx +368 -0
  323. package/dist/templates/default/packages/disposabl-kit/client/components/ui/checkbox.tsx +27 -0
  324. package/dist/templates/default/packages/disposabl-kit/client/components/ui/code-block.tsx +243 -0
  325. package/dist/templates/default/packages/disposabl-kit/client/components/ui/collapsible.tsx +19 -0
  326. package/dist/templates/default/packages/disposabl-kit/client/components/ui/combobox.tsx +300 -0
  327. package/dist/templates/default/packages/disposabl-kit/client/components/ui/command.tsx +194 -0
  328. package/dist/templates/default/packages/disposabl-kit/client/components/ui/context-menu.tsx +271 -0
  329. package/dist/templates/default/packages/disposabl-kit/client/components/ui/dialog.tsx +156 -0
  330. package/dist/templates/default/packages/disposabl-kit/client/components/ui/direction.tsx +4 -0
  331. package/dist/templates/default/packages/disposabl-kit/client/components/ui/drawer.tsx +224 -0
  332. package/dist/templates/default/packages/disposabl-kit/client/components/ui/dropdown-menu.tsx +269 -0
  333. package/dist/templates/default/packages/disposabl-kit/client/components/ui/empty.tsx +103 -0
  334. package/dist/templates/default/packages/disposabl-kit/client/components/ui/field.tsx +236 -0
  335. package/dist/templates/default/packages/disposabl-kit/client/components/ui/hover-card.tsx +50 -0
  336. package/dist/templates/default/packages/disposabl-kit/client/components/ui/input-group.tsx +158 -0
  337. package/dist/templates/default/packages/disposabl-kit/client/components/ui/input-otp.tsx +83 -0
  338. package/dist/templates/default/packages/disposabl-kit/client/components/ui/input.tsx +19 -0
  339. package/dist/templates/default/packages/disposabl-kit/client/components/ui/item.tsx +201 -0
  340. package/dist/templates/default/packages/disposabl-kit/client/components/ui/kbd.tsx +26 -0
  341. package/dist/templates/default/packages/disposabl-kit/client/components/ui/label.tsx +19 -0
  342. package/dist/templates/default/packages/disposabl-kit/client/components/ui/marker.tsx +70 -0
  343. package/dist/templates/default/packages/disposabl-kit/client/components/ui/menubar.tsx +284 -0
  344. package/dist/templates/default/packages/disposabl-kit/client/components/ui/message-scroller.tsx +128 -0
  345. package/dist/templates/default/packages/disposabl-kit/client/components/ui/message.tsx +91 -0
  346. package/dist/templates/default/packages/disposabl-kit/client/components/ui/native-select.tsx +64 -0
  347. package/dist/templates/default/packages/disposabl-kit/client/components/ui/navigation-menu.tsx +170 -0
  348. package/dist/templates/default/packages/disposabl-kit/client/components/ui/pagination.tsx +133 -0
  349. package/dist/templates/default/packages/disposabl-kit/client/components/ui/popover.tsx +87 -0
  350. package/dist/templates/default/packages/disposabl-kit/client/components/ui/progress.tsx +82 -0
  351. package/dist/templates/default/packages/disposabl-kit/client/components/ui/questionnaire.tsx +330 -0
  352. package/dist/templates/default/packages/disposabl-kit/client/components/ui/radio-group.tsx +35 -0
  353. package/dist/templates/default/packages/disposabl-kit/client/components/ui/resizable.tsx +49 -0
  354. package/dist/templates/default/packages/disposabl-kit/client/components/ui/scroll-area.tsx +51 -0
  355. package/dist/templates/default/packages/disposabl-kit/client/components/ui/select.tsx +201 -0
  356. package/dist/templates/default/packages/disposabl-kit/client/components/ui/separator.tsx +22 -0
  357. package/dist/templates/default/packages/disposabl-kit/client/components/ui/sheet.tsx +132 -0
  358. package/dist/templates/default/packages/disposabl-kit/client/components/ui/sidebar.tsx +723 -0
  359. package/dist/templates/default/packages/disposabl-kit/client/components/ui/skeleton.tsx +13 -0
  360. package/dist/templates/default/packages/disposabl-kit/client/components/ui/slider.tsx +51 -0
  361. package/dist/templates/default/packages/disposabl-kit/client/components/ui/spinner.tsx +16 -0
  362. package/dist/templates/default/packages/disposabl-kit/client/components/ui/switch.tsx +31 -0
  363. package/dist/templates/default/packages/disposabl-kit/client/components/ui/table.tsx +113 -0
  364. package/dist/templates/default/packages/disposabl-kit/client/components/ui/tabs.tsx +81 -0
  365. package/dist/templates/default/packages/disposabl-kit/client/components/ui/textarea.tsx +17 -0
  366. package/dist/templates/default/packages/disposabl-kit/client/components/ui/toast.tsx +229 -0
  367. package/dist/templates/default/packages/disposabl-kit/client/components/ui/toggle-group.tsx +87 -0
  368. package/dist/templates/default/packages/disposabl-kit/client/components/ui/toggle.tsx +42 -0
  369. package/dist/templates/default/packages/disposabl-kit/client/components/ui/tooltip.tsx +65 -0
  370. package/dist/templates/default/packages/disposabl-kit/client/components/ui/trace.tsx +161 -0
  371. package/dist/templates/default/packages/disposabl-kit/client/hooks/use-mobile.ts +21 -0
  372. package/dist/templates/default/packages/disposabl-kit/client/lib/prerender.ts +89 -0
  373. package/dist/templates/default/packages/disposabl-kit/client/lib/return-to.ts +12 -0
  374. package/dist/templates/default/packages/disposabl-kit/client/lib/utils.ts +1 -0
  375. package/dist/templates/default/packages/disposabl-kit/client/routes/_auth-pages/login.tsx +114 -0
  376. package/dist/templates/default/packages/disposabl-kit/client/routes/_auth-pages/signUp.tsx +120 -0
  377. package/dist/templates/default/packages/disposabl-kit/client/routes/_authenticated/route.tsx +38 -0
  378. package/dist/templates/default/packages/disposabl-kit/client/routes/consent.tsx +137 -0
  379. package/dist/templates/default/packages/disposabl-kit/client/routes/route.tsx +30 -0
  380. package/dist/templates/default/packages/disposabl-kit/client/styles/globals.css +60 -0
  381. package/dist/templates/default/packages/disposabl-kit/client/vite.config.ts +32 -0
  382. package/dist/templates/default/packages/disposabl-kit/components.json +23 -0
  383. package/dist/templates/default/packages/disposabl-kit/eslint.config.js +21 -0
  384. package/dist/templates/default/packages/disposabl-kit/package.json +60 -0
  385. package/dist/templates/default/packages/disposabl-kit/server/http.ts +86 -0
  386. package/dist/templates/default/packages/disposabl-kit/server/lib/functions.ts +40 -0
  387. package/dist/templates/default/packages/disposabl-kit/server/lib/platforms.ts +20 -0
  388. package/dist/templates/default/packages/disposabl-kit/server/lib/static-routes.ts +56 -0
  389. package/dist/templates/default/packages/disposabl-kit/tsconfig.json +17 -0
  390. package/dist/templates/default/patches/@convex-dev%2Fauth@2.0.0-beta.0.patch +310 -0
  391. package/dist/templates/default/patches/@convex-dev%2Fstatic-hosting@0.2.1.patch +187 -0
  392. package/dist/templates/default/tsconfig.json +9 -0
  393. package/dist/templates/default/turbo.json +51 -0
  394. package/package.json +21 -5
  395. package/README.md +0 -34
  396. package/dist/templates/default/README.md +0 -12
  397. package/dist/templates/default/docs/index.html +0 -8
  398. package/dist/templates/default/eslint.config.js +0 -18
  399. package/dist/templates/default/index.ts +0 -14
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env bash
2
+ # Create the eval workspace directory tree for a run.
3
+ #
4
+ # Usage: make-workspace.sh <workspace> <iteration> <num-evals> [configs]
5
+ # workspace Run root, e.g. /private/tmp/expo-skill-eval-<skill>
6
+ # iteration Iteration folder name, e.g. "iteration-1"
7
+ # num-evals Number of eval cases; creates eval-0 .. eval-(N-1)
8
+ # configs Space- or comma-separated config names
9
+ # (default: "with_skill without_skill")
10
+ #
11
+ # Creates <workspace>/trigger-evals/scratch and, per eval x config,
12
+ # <workspace>/<iteration>/eval-<i>/<config>/outputs. Run this once at the
13
+ # start of a run instead of ad-hoc `mkdir` so the call is covered by the
14
+ # skill's `Bash(bash *expo-skill-eval/scripts/*)` rule (the mkdir calls
15
+ # inside run as children of this script and need no permission of their own).
16
+ set -euo pipefail
17
+
18
+ WORKSPACE="${1:?usage: make-workspace.sh <workspace> <iteration> <num-evals> [configs]}"
19
+ ITERATION="${2:?usage: make-workspace.sh <workspace> <iteration> <num-evals> [configs]}"
20
+ NUM_EVALS="${3:?usage: make-workspace.sh <workspace> <iteration> <num-evals> [configs]}"
21
+ CONFIGS="${4:-with_skill without_skill}"
22
+ CONFIGS="${CONFIGS//,/ }"
23
+
24
+ mkdir -p "$WORKSPACE/trigger-evals/scratch"
25
+ for ((i = 0; i < NUM_EVALS; i++)); do
26
+ for cfg in $CONFIGS; do
27
+ mkdir -p "$WORKSPACE/$ITERATION/eval-$i/$cfg/outputs"
28
+ done
29
+ done
30
+
31
+ echo "workspace ready: $WORKSPACE/$ITERATION ($NUM_EVALS evals x [$CONFIGS])"
@@ -0,0 +1,284 @@
1
+ #!/usr/bin/env bash
2
+ # Run an Expo app in Expo Go on an Android emulator and capture a screenshot.
3
+ #
4
+ # Usage: snapshot-android.sh <project-path> <output-png> [port] [settle-seconds]
5
+ #
6
+ # Env: EXPO_SKILL_EVAL_RUNNER = expo-go (default) | dev-build — dev-build runs the
7
+ # app via `expo run:android` (native dev-client compile, slow) instead of Expo Go.
8
+ #
9
+ # If no device is attached, boots the first available AVD and waits for it
10
+ # (the slow path - keep one emulator running across an eval session).
11
+ # Starts Metro with `expo start --android` (auto-installs Expo Go, sets up
12
+ # adb reverse, opens the app), waits for the bundle, settles, screenshots
13
+ # via screencap, and tears Metro down. The Metro log is saved next to the
14
+ # screenshot as <name>.metro.log. On bundle failure it still captures a
15
+ # best-effort screenshot and exits 1.
16
+ set -uo pipefail
17
+
18
+ PROJECT_PATH="${1:?usage: snapshot-android.sh <project-path> <output-png> [port] [settle-seconds]}"
19
+ OUT="${2:?usage: snapshot-android.sh <project-path> <output-png> [port] [settle-seconds]}"
20
+ PORT="${3:-8082}"
21
+ RUNNER="${EXPO_SKILL_EVAL_RUNNER:-expo-go}" # expo-go | dev-build
22
+
23
+ # Step-level logging with timestamp. Every major phase emits a marker so a
24
+ # crash report can be correlated to "which step was running when it died."
25
+ log_step() { echo "[$(date '+%H:%M:%S')] [snapshot-android] STEP: $*" >&2; }
26
+
27
+ # Track the emulator qemu PID so liveness checks in wait loops can detect a
28
+ # mid-flight crash and emit a clear "emulator crashed at step X" message.
29
+ EMULATOR_PID=""
30
+
31
+ emulator_alive() {
32
+ [[ -n "$EMULATOR_PID" ]] && kill -0 "$EMULATOR_PID" 2>/dev/null
33
+ }
34
+
35
+ log_step "start runner=$RUNNER port=$PORT project=$PROJECT_PATH"
36
+
37
+ # GPU mode is fixed to host (Metal on Apple Silicon, hardware-accelerated). The
38
+ # env-var knob was removed on purpose. If host self-aborts the emulator on a
39
+ # given machine (qemu SIGABRT deep in gfxstream/Metal — possible on Apple Silicon
40
+ # under load), change this to "guest" and bump SETTLE to ~25 (software rendering
41
+ # paints slowly). Avoid swiftshader_indirect — it hangs at boot on arm64.
42
+ GPU_MODE="host"
43
+ log_step "gpu_mode=$GPU_MODE"
44
+
45
+ SETTLE="${4:-8}"
46
+
47
+ if [[ "$RUNNER" == "dev-build" ]]; then
48
+ BUNDLE_TIMEOUT="${EXPO_SKILL_EVAL_BUNDLE_TIMEOUT:-900}" # native compile is slow
49
+ else
50
+ BUNDLE_TIMEOUT="${EXPO_SKILL_EVAL_BUNDLE_TIMEOUT:-240}"
51
+ fi
52
+ LOG="${OUT%.png}.metro.log"
53
+
54
+ mkdir -p "$(dirname "$OUT")"
55
+
56
+ # Free the port up front in case a previous run (or a crash) left Metro on it,
57
+ # so `expo start` binds the port we expect instead of silently incrementing.
58
+ # Runs inside this script, so the eval harness never needs ad-hoc lsof/kill.
59
+ lsof -ti "tcp:$PORT" -sTCP:LISTEN 2>/dev/null | xargs kill -9 2>/dev/null || true
60
+
61
+ find_sdk_tool() {
62
+ local tool="$1" subdir="$2"
63
+ if command -v "$tool" >/dev/null; then
64
+ command -v "$tool"
65
+ return
66
+ fi
67
+ local sdk
68
+ for sdk in "${ANDROID_HOME:-}" "${ANDROID_SDK_ROOT:-}" "$HOME/Library/Android/sdk" "$HOME/Android/Sdk"; do
69
+ if [[ -n "$sdk" && -x "$sdk/$subdir/$tool" ]]; then
70
+ echo "$sdk/$subdir/$tool"
71
+ return
72
+ fi
73
+ done
74
+ return 1
75
+ }
76
+
77
+ ADB="$(find_sdk_tool adb platform-tools)" || { echo "error: adb not found (set ANDROID_HOME)" >&2; exit 1; }
78
+
79
+ # Recycle a wedged emulator before the boot check. An "offline"/unresponsive
80
+ # emulator isn't in "device" state, so the check below would otherwise reuse it
81
+ # (and hang) or stack a second emulator beside it. Graceful console shutdown
82
+ # first; force-kill only the survivors, then reset adb to clear the stale entry —
83
+ # so the boot check sees a clean slate and cold-boots a fresh (swiftshader) one.
84
+ log_step "checking for wedged/offline emulators"
85
+ STALE="$("$ADB" devices | awk 'NR>1 && $1 ~ /^emulator-/ && $2!="device" {print $1}')"
86
+ if [[ -n "$STALE" ]]; then
87
+ echo "recycling wedged emulator(s): $STALE" >&2
88
+ for serial in $STALE; do
89
+ "$ADB" -s "$serial" emu kill 2>/dev/null || true # graceful: ask the console to quit
90
+ done
91
+ sleep 2
92
+ # Still wedged after the graceful attempt? Force-kill the qemu process(es) and
93
+ # reset the adb server to drop the stale "offline" entry. pkill is broad (all
94
+ # qemu emulators), which is fine here: the eval harness runs a single emulator.
95
+ if "$ADB" devices | awk 'NR>1 && $1 ~ /^emulator-/ && $2!="device"' | grep -q .; then
96
+ pkill -9 -f qemu-system-aarch64 2>/dev/null || true
97
+ "$ADB" kill-server 2>/dev/null || true
98
+ "$ADB" start-server 2>/dev/null || true
99
+ sleep 2
100
+ fi
101
+ fi
102
+
103
+ # GPU mismatch: if an emulator is already running with a different GPU mode than
104
+ # the one we need, recycle it so the boot path cold-starts with the correct mode.
105
+ # gfxstream (host GPU) uses a gRPC channel that can crash on Metro teardown via
106
+ # a bad_function_call SIGABRT; guest GPU avoids this by keeping rendering in-guest.
107
+ CURRENT_GPU="$(ps aux | grep qemu-system-aarch64 | grep -v grep | grep -o -- '-gpu [a-z_]*' | awk '{print $2}' | head -1)"
108
+ log_step "current_gpu=${CURRENT_GPU:-none} required=$GPU_MODE"
109
+ if [[ -n "$CURRENT_GPU" && "$CURRENT_GPU" != "$GPU_MODE" ]]; then
110
+ echo "GPU mismatch: running=$CURRENT_GPU required=$GPU_MODE — recycling emulator" >&2
111
+ "$ADB" emu kill 2>/dev/null || true
112
+ sleep 2
113
+ pkill -9 -f qemu-system-aarch64 2>/dev/null || true
114
+ "$ADB" kill-server 2>/dev/null || true
115
+ "$ADB" start-server 2>/dev/null || true
116
+ sleep 2
117
+ fi
118
+
119
+ log_step "checking device availability"
120
+ if ! "$ADB" devices | awk 'NR>1 && $2=="device"' | grep -q .; then
121
+ EMULATOR="$(find_sdk_tool emulator emulator)" || { echo "error: no device attached and emulator binary not found" >&2; exit 1; }
122
+ AVD="$("$EMULATOR" -list-avds | head -1)"
123
+ if [[ -z "$AVD" ]]; then
124
+ echo "error: no AVDs configured" >&2
125
+ exit 1
126
+ fi
127
+ # Reset adb server before cold-booting. A previously crashed emulator leaves
128
+ # the server in a bad state (still trying to reconnect to dead ports 5554/5555),
129
+ # which causes adb wait-for-device to hang indefinitely on the next boot.
130
+ log_step "resetting adb server before cold boot"
131
+ "$ADB" kill-server 2>/dev/null || true
132
+ "$ADB" start-server 2>/dev/null || true
133
+ sleep 1
134
+ log_step "booting emulator avd=$AVD gpu=$GPU_MODE"
135
+ # nohup + disown so the emulator outlives this script and is reused by later
136
+ # eval runs. -no-snapshot forces a clean cold boot (no stale snapshot to replay)
137
+ # and writes no multi-GB snapshot (disk is often tight).
138
+ nohup "$EMULATOR" -avd "$AVD" -no-boot-anim \
139
+ -gpu "$GPU_MODE" -no-snapshot </dev/null >/dev/null 2>&1 &
140
+ disown
141
+ EMULATOR_PID="$(pgrep -f "emulator.*-avd $AVD" | head -1)"
142
+ log_step "emulator booted pid=${EMULATOR_PID:-unknown}"
143
+ "$ADB" wait-for-device
144
+ log_step "adb device appeared — waiting for full boot"
145
+ until [[ "$("$ADB" shell getprop sys.boot_completed 2>/dev/null | tr -d '\r')" == "1" ]]; do
146
+ if [[ -n "$EMULATOR_PID" ]] && ! kill -0 "$EMULATOR_PID" 2>/dev/null; then
147
+ echo "error: emulator pid=$EMULATOR_PID crashed during boot (check DiagnosticReports for qemu SIGABRT)" >&2
148
+ exit 1
149
+ fi
150
+ sleep 2
151
+ done
152
+ log_step "emulator fully booted"
153
+ else
154
+ EMULATOR_PID="$(pgrep -f qemu-system-aarch64 | head -1)"
155
+ log_step "reusing running emulator pid=${EMULATOR_PID:-unknown}"
156
+ fi
157
+
158
+ # --android makes the CLI install Expo Go on the device when missing. Pin the
159
+ # packager hostname to 127.0.0.1 so every exp:// URL goes through the adb
160
+ # reverse tunnel - the default LAN-IP URL is often unreachable from the
161
+ # emulator (host firewall) and leaves a stuck experience in Expo Go's task
162
+ # stack that hijacks later deep links.
163
+ # dev-build: expo run:android prebuilds + native-compiles a dev client, installs
164
+ # and launches it, and starts Metro — no Expo Go involved.
165
+ if [[ "$RUNNER" == "dev-build" ]]; then
166
+ log_step "starting expo run:android port=$PORT"
167
+ # Pass --port so Metro binds to $PORT and the health-check curl matches.
168
+ (cd "$PROJECT_PATH" && exec env -u CI REACT_NATIVE_PACKAGER_HOSTNAME=127.0.0.1 bunx expo run:android --port "$PORT") </dev/null >"$LOG" 2>&1 &
169
+ else
170
+ log_step "starting expo start --android port=$PORT"
171
+ (cd "$PROJECT_PATH" && exec env -u CI REACT_NATIVE_PACKAGER_HOSTNAME=127.0.0.1 bunx expo start --port "$PORT" --android) </dev/null >"$LOG" 2>&1 &
172
+ fi
173
+ METRO_PID=$!
174
+ # APP_PKG is set later (dev-build only) but must be in scope for cleanup.
175
+ APP_PKG=""
176
+ cleanup() {
177
+ kill "$METRO_PID" 2>/dev/null
178
+ lsof -ti "tcp:$PORT" -sTCP:LISTEN 2>/dev/null | xargs kill -9 2>/dev/null || true
179
+ wait "$METRO_PID" 2>/dev/null
180
+ }
181
+ trap cleanup EXIT
182
+ # Resolve the app package name up front so the cleanup trap has it even on
183
+ # early exit. app.json is a fixture source file always present before Metro starts.
184
+ if [[ "$RUNNER" == "dev-build" ]]; then
185
+ APP_PKG="$(node -e "try{var a=require('$PROJECT_PATH/app.json');console.log((a.expo&&a.expo.android&&a.expo.android.package)||'com.exposkilleval.fixture')}catch(e){console.log('com.exposkilleval.fixture')}" 2>/dev/null || echo 'com.exposkilleval.fixture')"
186
+ log_step "app package=$APP_PKG"
187
+ fi
188
+
189
+ DEADLINE=$((SECONDS + BUNDLE_TIMEOUT))
190
+ STATUS=0
191
+
192
+ log_step "waiting for Metro on port=$PORT"
193
+ until curl -sf "http://localhost:$PORT/status" >/dev/null; do
194
+ if ! kill -0 "$METRO_PID" 2>/dev/null; then
195
+ echo "error: Metro (pid=$METRO_PID) exited before coming up. Log tail:" >&2
196
+ tail -40 "$LOG" >&2
197
+ exit 1
198
+ fi
199
+ if emulator_alive; then : ; elif [[ -n "$EMULATOR_PID" ]]; then
200
+ echo "error: emulator pid=$EMULATOR_PID crashed while waiting for Metro" >&2
201
+ tail -40 "$LOG" >&2
202
+ exit 1
203
+ fi
204
+ if ((SECONDS > DEADLINE)); then
205
+ echo "error: timed out after ${BUNDLE_TIMEOUT}s waiting for Metro. Log tail:" >&2
206
+ tail -40 "$LOG" >&2
207
+ exit 1
208
+ fi
209
+ sleep 2
210
+ done
211
+ log_step "Metro is up"
212
+ # Expo Go only: wait for it to install (the CLI may still be installing it).
213
+ if [[ "$RUNNER" != "dev-build" ]]; then
214
+ log_step "waiting for Expo Go install on device"
215
+ until "$ADB" shell pm list packages 2>/dev/null | grep -q host.exp.exponent; do
216
+ if ((SECONDS > DEADLINE)); then
217
+ echo "error: Expo Go was not installed on the device. Log tail:" >&2
218
+ tail -40 "$LOG" >&2
219
+ exit 1
220
+ fi
221
+ sleep 2
222
+ done
223
+ fi
224
+ # Both runners: route the bundle over the adb reverse tunnel.
225
+ log_step "setting up adb reverse tunnel port=$PORT"
226
+ "$ADB" reverse "tcp:$PORT" "tcp:$PORT"
227
+ if [[ "$RUNNER" == "dev-build" ]]; then
228
+ # expo run:android launches the dev client BEFORE Metro is ready, so it shows
229
+ # "Cannot connect to Expo CLI". Now that Metro + adb-reverse are both up,
230
+ # force-restart via explicit MainActivity to avoid the "Open in X?" dialog
231
+ # that an implicit VIEW intent triggers. expo run:android --port embeds the
232
+ # Metro URL in the build, so the dev client auto-connects on relaunch.
233
+ if [[ -n "$APP_PKG" ]]; then
234
+ log_step "launching dev-build app pkg=$APP_PKG"
235
+ "$ADB" shell am force-stop "$APP_PKG" 2>/dev/null || true
236
+ sleep 2
237
+ "$ADB" shell am start -W -n "${APP_PKG}/.MainActivity" >/dev/null 2>&1 || true
238
+ fi
239
+ else
240
+ log_step "launching Expo Go exp://127.0.0.1:$PORT"
241
+ # Force-stop so a stale experience from a previous run can't be resumed, then
242
+ # give the system a moment to finish task cleanup - launching immediately
243
+ # after force-stop races it and the new activity gets torn down too.
244
+ "$ADB" shell am force-stop host.exp.exponent
245
+ sleep 2
246
+ "$ADB" shell am start -W -a android.intent.action.VIEW -d "exp://127.0.0.1:$PORT" >/dev/null
247
+ fi
248
+
249
+ log_step "waiting for JS bundle"
250
+ until grep -q 'Bundled' "$LOG"; do
251
+ if ! kill -0 "$METRO_PID" 2>/dev/null; then
252
+ echo "error: Metro (pid=$METRO_PID) exited before bundling. Log tail:" >&2
253
+ tail -40 "$LOG" >&2
254
+ STATUS=1
255
+ break
256
+ fi
257
+ if emulator_alive; then : ; elif [[ -n "$EMULATOR_PID" ]]; then
258
+ echo "error: emulator pid=$EMULATOR_PID crashed while waiting for JS bundle" >&2
259
+ tail -40 "$LOG" >&2
260
+ STATUS=1
261
+ break
262
+ fi
263
+ if ((SECONDS > DEADLINE)); then
264
+ echo "error: timed out after ${BUNDLE_TIMEOUT}s waiting for bundle. Log tail:" >&2
265
+ tail -40 "$LOG" >&2
266
+ STATUS=1
267
+ break
268
+ fi
269
+ sleep 2
270
+ done
271
+
272
+ log_step "bundle done — settling ${SETTLE}s"
273
+ sleep "$SETTLE"
274
+ log_step "taking screenshot"
275
+ "$ADB" exec-out screencap -p >"$OUT" || STATUS=1
276
+ # Raw emulator captures are ~2800px tall and overflow the eval viewer's
277
+ # window. Downscale to a review/grading-friendly size.
278
+ if [[ -s "$OUT" ]]; then
279
+ sips -Z "${EXPO_SKILL_EVAL_MAX_DIM:-600}" "$OUT" >/dev/null 2>&1 || true
280
+ fi
281
+ log_step "done status=$STATUS screenshot=$OUT"
282
+ echo "screenshot: $OUT"
283
+ echo "metro log: $LOG"
284
+ exit "$STATUS"
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env bash
2
+ # Run an Expo app in Expo Go on an iOS simulator and capture a screenshot.
3
+ #
4
+ # Usage: snapshot-ios.sh <project-path> <output-png> [port] [settle-seconds]
5
+ #
6
+ # Env: EXPO_SKILL_EVAL_RUNNER = expo-go (default) | dev-build — dev-build runs the
7
+ # app via `expo run:ios` (native dev-client compile, slow) instead of Expo Go.
8
+ #
9
+ # Boots the newest available iPhone simulator if none is booted, starts
10
+ # Metro with `expo start --ios` (auto-installs Expo Go on the simulator and
11
+ # opens the app), waits for the bundle to load, settles, screenshots, and
12
+ # tears Metro down. The Metro log is saved next to the screenshot as
13
+ # <name>.metro.log. On bundle failure it still captures a best-effort
14
+ # screenshot (the error screen is grading evidence) and exits 1.
15
+ set -uo pipefail
16
+
17
+ PROJECT_PATH="${1:?usage: snapshot-ios.sh <project-path> <output-png> [port] [settle-seconds]}"
18
+ OUT="${2:?usage: snapshot-ios.sh <project-path> <output-png> [port] [settle-seconds]}"
19
+ PORT="${3:-8081}"
20
+ SETTLE="${4:-8}"
21
+ RUNNER="${EXPO_SKILL_EVAL_RUNNER:-expo-go}" # expo-go | dev-build
22
+ if [[ "$RUNNER" == "dev-build" ]]; then
23
+ BUNDLE_TIMEOUT="${EXPO_SKILL_EVAL_BUNDLE_TIMEOUT:-900}" # native compile is slow
24
+ else
25
+ BUNDLE_TIMEOUT="${EXPO_SKILL_EVAL_BUNDLE_TIMEOUT:-240}"
26
+ fi
27
+ LOG="${OUT%.png}.metro.log"
28
+
29
+ mkdir -p "$(dirname "$OUT")"
30
+
31
+ # Free the port up front in case a previous run (or a crash) left Metro on it,
32
+ # so `expo start` binds the port we expect instead of silently incrementing.
33
+ # Runs inside this script, so the eval harness never needs ad-hoc lsof/kill.
34
+ lsof -ti "tcp:$PORT" -sTCP:LISTEN 2>/dev/null | xargs kill -9 2>/dev/null || true
35
+
36
+ if ! xcrun simctl list devices booted | grep -q '(Booted)'; then
37
+ UDID="$(xcrun simctl list devices available | grep 'iPhone' | tail -1 | grep -oE '[0-9A-F-]{36}')"
38
+ if [[ -z "$UDID" ]]; then
39
+ echo "error: no available iPhone simulator found" >&2
40
+ exit 1
41
+ fi
42
+ echo "booting simulator $UDID..." >&2
43
+ xcrun simctl boot "$UDID"
44
+ open -a Simulator
45
+ xcrun simctl bootstatus "$UDID"
46
+ fi
47
+
48
+ # expo-go: --ios installs Expo Go when missing; its own open is unreliable if a
49
+ # previous experience is foregrounded, so we relaunch deterministically below.
50
+ # dev-build: expo run:ios prebuilds + native-compiles a dev client, installs and
51
+ # launches it on the simulator, and starts Metro — no Expo Go involved.
52
+ if [[ "$RUNNER" == "dev-build" ]]; then
53
+ # Pass --port so Metro binds to $PORT and the health-check curl matches.
54
+ (cd "$PROJECT_PATH" && exec env -u CI bunx expo run:ios --port "$PORT") </dev/null >"$LOG" 2>&1 &
55
+ else
56
+ (cd "$PROJECT_PATH" && exec env -u CI REACT_NATIVE_PACKAGER_HOSTNAME=127.0.0.1 bunx expo start --port "$PORT" --ios) </dev/null >"$LOG" 2>&1 &
57
+ fi
58
+ METRO_PID=$!
59
+ cleanup() {
60
+ kill "$METRO_PID" 2>/dev/null
61
+ lsof -ti "tcp:$PORT" -sTCP:LISTEN 2>/dev/null | xargs kill -9 2>/dev/null || true
62
+ wait "$METRO_PID" 2>/dev/null
63
+ }
64
+ trap cleanup EXIT
65
+
66
+ DEADLINE=$((SECONDS + BUNDLE_TIMEOUT))
67
+ STATUS=0
68
+
69
+ until curl -sf "http://localhost:$PORT/status" >/dev/null; do
70
+ if ! kill -0 "$METRO_PID" 2>/dev/null || ((SECONDS > DEADLINE)); then
71
+ echo "error: Metro did not come up. Log tail:" >&2
72
+ tail -40 "$LOG" >&2
73
+ exit 1
74
+ fi
75
+ sleep 2
76
+ done
77
+ # Expo Go only: wait for Expo Go to install, then relaunch the experience
78
+ # deterministically. dev-build skips this — expo run:ios launches the dev client.
79
+ if [[ "$RUNNER" != "dev-build" ]]; then
80
+ until xcrun simctl get_app_container booted host.exp.Exponent >/dev/null 2>&1; do
81
+ if ((SECONDS > DEADLINE)); then
82
+ echo "error: Expo Go was not installed on the simulator. Log tail:" >&2
83
+ tail -40 "$LOG" >&2
84
+ exit 1
85
+ fi
86
+ sleep 2
87
+ done
88
+ # Terminate any running Expo Go so a stale experience can't stay foregrounded,
89
+ # then open the project URL explicitly.
90
+ xcrun simctl terminate booted host.exp.Exponent 2>/dev/null || true
91
+ sleep 2
92
+ xcrun simctl openurl booted "exp://127.0.0.1:$PORT"
93
+ fi
94
+
95
+ until grep -q 'Bundled' "$LOG"; do
96
+ if ! kill -0 "$METRO_PID" 2>/dev/null; then
97
+ echo "error: Metro exited before bundling. Log tail:" >&2
98
+ tail -40 "$LOG" >&2
99
+ STATUS=1
100
+ break
101
+ fi
102
+ if ((SECONDS > DEADLINE)); then
103
+ echo "error: timed out after ${BUNDLE_TIMEOUT}s waiting for bundle. Log tail:" >&2
104
+ tail -40 "$LOG" >&2
105
+ STATUS=1
106
+ break
107
+ fi
108
+ sleep 2
109
+ done
110
+
111
+ # dev-build: after bundling, relaunch the app so it is reliably in the
112
+ # foreground. Use xcrun simctl launch (not openurl) to avoid the "Open in X?"
113
+ # confirmation dialog that xcrun simctl openurl triggers on the iOS Simulator.
114
+ # expo run:ios embeds the Metro URL in the build, so the dev client auto-connects.
115
+ if [[ "$RUNNER" == "dev-build" ]]; then
116
+ BUNDLE_ID="$(node -e "try{var a=require('$PROJECT_PATH/app.json');console.log((a.expo&&a.expo.ios&&a.expo.ios.bundleIdentifier)||'com.exposkilleval.fixture')}catch(e){console.log('com.exposkilleval.fixture')}" 2>/dev/null || echo 'com.exposkilleval.fixture')"
117
+ xcrun simctl terminate booted "$BUNDLE_ID" 2>/dev/null || true
118
+ sleep 2
119
+ xcrun simctl launch --terminate-running-process booted "$BUNDLE_ID" >/dev/null 2>&1 || true
120
+ sleep 3
121
+ fi
122
+
123
+ sleep "$SETTLE"
124
+ xcrun simctl io booted screenshot "$OUT" || STATUS=1
125
+ # Raw simulator captures are 3x retina (~2600px tall) and overflow the eval
126
+ # viewer's window. Downscale to a review/grading-friendly size.
127
+ if [[ -f "$OUT" ]]; then
128
+ sips -Z "${EXPO_SKILL_EVAL_MAX_DIM:-600}" "$OUT" >/dev/null 2>&1 || true
129
+ fi
130
+ echo "screenshot: $OUT"
131
+ echo "metro log: $LOG"
132
+ exit "$STATUS"
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env bash
2
+ # Run an Expo app's web target and capture a browser screenshot. (Phase 4 -
3
+ # only for eval cases whose runtime.platforms includes "web".)
4
+ #
5
+ # Usage: snapshot-web.sh <project-path> <output-png> [port] [settle-seconds]
6
+ #
7
+ # Starts Metro with `expo start --web`, waits for the dev server to respond,
8
+ # then screenshots with Playwright's CLI at an iPhone-ish viewport. The first
9
+ # run downloads Chromium via `bunx playwright install chromium`.
10
+ set -uo pipefail
11
+
12
+ PROJECT_PATH="${1:?usage: snapshot-web.sh <project-path> <output-png> [port] [settle-seconds]}"
13
+ OUT="${2:?usage: snapshot-web.sh <project-path> <output-png> [port] [settle-seconds]}"
14
+ PORT="${3:-8081}"
15
+ SETTLE="${4:-8}"
16
+ SERVER_TIMEOUT="${EXPO_SKILL_EVAL_BUNDLE_TIMEOUT:-240}"
17
+ LOG="${OUT%.png}.metro.log"
18
+
19
+ mkdir -p "$(dirname "$OUT")"
20
+
21
+ # Free the port up front in case a previous run (or a crash) left Metro on it,
22
+ # so `expo start` binds the port we expect instead of silently incrementing.
23
+ # Runs inside this script, so the eval harness never needs ad-hoc lsof/kill.
24
+ lsof -ti "tcp:$PORT" -sTCP:LISTEN 2>/dev/null | xargs kill -9 2>/dev/null || true
25
+
26
+ bunx playwright install chromium >/dev/null 2>&1 || true
27
+
28
+ (cd "$PROJECT_PATH" && exec env -u CI bunx expo start --port "$PORT" --web) </dev/null >"$LOG" 2>&1 &
29
+ METRO_PID=$!
30
+ cleanup() {
31
+ kill "$METRO_PID" 2>/dev/null
32
+ pkill -f "expo start --port $PORT" 2>/dev/null
33
+ wait "$METRO_PID" 2>/dev/null
34
+ }
35
+ trap cleanup EXIT
36
+
37
+ DEADLINE=$((SECONDS + SERVER_TIMEOUT))
38
+ until curl -sf "http://localhost:$PORT" >/dev/null; do
39
+ if ! kill -0 "$METRO_PID" 2>/dev/null || ((SECONDS > DEADLINE)); then
40
+ echo "error: web dev server did not come up. Log tail:" >&2
41
+ tail -40 "$LOG" >&2
42
+ exit 1
43
+ fi
44
+ sleep 2
45
+ done
46
+
47
+ STATUS=0
48
+ bunx playwright screenshot \
49
+ --browser chromium \
50
+ --viewport-size "390,844" \
51
+ --wait-for-timeout "$((SETTLE * 1000))" \
52
+ "http://localhost:$PORT" "$OUT" || STATUS=1
53
+
54
+ # Keep parity with the device snapshot scripts: cap the largest dimension so
55
+ # screenshots fit the eval viewer's window.
56
+ if [[ -f "$OUT" ]]; then
57
+ sips -Z "${EXPO_SKILL_EVAL_MAX_DIM:-600}" "$OUT" >/dev/null 2>&1 || true
58
+ fi
59
+ echo "screenshot: $OUT"
60
+ echo "metro log: $LOG"
61
+ exit "$STATUS"
@@ -0,0 +1,101 @@
1
+ ---
2
+ name: expo-ui
3
+ description: "Build native UI with the @expo/ui package: real SwiftUI on iOS and Jetpack Compose on Android. Default to @expo/ui for sheets (BottomSheet), pickers, sliders, toggles, menus, and grouped-form sections — do NOT reach for Reanimated, @gorhom/bottom-sheet, or RN built-in Picker/Switch; use @expo/ui instead. Fall back to RN built-ins only when @expo/ui is missing the component. NOTE: @expo/ui List renders native grouped rows like an iOS Settings screen — it is NOT a virtualized list; use FlatList/FlashList for large datasets. Covers universal components (Host, Column, Row, Button, Text, List, BottomSheet, FieldGroup, Switch, Slider, Picker, Menu), drop-in replacements for RN community libraries, and platform-specific SwiftUI/Jetpack Compose trees. Not for Expo Router navigation, Reanimated, or data fetching."
4
+ version: 1.0.0
5
+ license: MIT
6
+ allowed-tools: "Bash(node *expo-ui/scripts/list-components.js *)"
7
+ ---
8
+
9
+ # Expo UI (`@expo/ui`)
10
+
11
+ `@expo/ui` renders real native UI from React: SwiftUI on iOS, Jetpack Compose on Android. It also ships drop-in replacements for migrating off RN community UI libraries.
12
+
13
+ > These instructions track the latest Expo SDK. The **universal** layer requires **SDK 56+** and works in Expo Go — no custom build needed. Drop-in replacements and the platform-specific layers also exist on SDK 55. For component details on a specific SDK, refer to the Expo UI docs for that version.
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npx expo install @expo/ui
19
+ ```
20
+
21
+ Every `@expo/ui` tree — universal or platform-specific — must be wrapped in `Host`.
22
+
23
+ ## Use @expo/ui by default — don't reach for RN alternatives first
24
+
25
+ **Before using Reanimated, `@gorhom/bottom-sheet`, React Native's built-in `Switch`/`Picker`, or any community UI library for the items below, use `@expo/ui` instead.** Only fall back to RN built-ins when `@expo/ui` is missing the component.
26
+
27
+ | Need | Use |
28
+ |------|-----|
29
+ | Slide-up sheet / bottom sheet | `BottomSheet` from `@expo/ui` — **not** Reanimated or `@gorhom/bottom-sheet` |
30
+ | Grouped native list rows (settings/form-style) | `List` + `ListItem` from `@expo/ui` — **not** `FlatList` (see note below) |
31
+ | Toggle | `Switch` from `@expo/ui` |
32
+ | Slider | `Slider` from `@expo/ui` |
33
+ | Date/time picker | `@expo/ui/community/datetimepicker` |
34
+ | Menu | `Menu` from `@expo/ui` |
35
+ | Form section with label | `FieldGroup` from `@expo/ui` |
36
+ | Collapsible section | `Collapsible` from `@expo/ui` |
37
+
38
+ > **`List` is NOT a virtualized scrolling list.** It renders native grouped table rows — the visual look of an iOS Settings screen or a form section, with disclosure indicators and native row styling. Each `ListItem` is a native node on the JS thread; rows are not recycled. For any list with large or unknown-length data (feeds, search results, catalogs), use **`FlatList`** or **`FlashList`** instead. `List` is the right choice for short, fixed-length groups: a settings screen, a detail panel's rows, a fixed menu.
39
+
40
+ **`BottomSheet` example** (use this for map pin details, action sheets, detail panels — not Reanimated):
41
+
42
+ ```tsx
43
+ import { Host, BottomSheet, Column, Text } from '@expo/ui';
44
+ import { useState } from 'react';
45
+
46
+ export default function MapScreen() {
47
+ const [isOpen, setIsOpen] = useState(false);
48
+
49
+ return (
50
+ <View style={{ flex: 1 }}>
51
+ <MapView onMarkerPress={() => setIsOpen(true)} />
52
+ <Host>
53
+ <BottomSheet
54
+ isPresented={isOpen}
55
+ onDismiss={() => setIsOpen(false)}
56
+ snapPoints={['half', 'full']}
57
+ >
58
+ <Column>
59
+ <Text>Café name</Text>
60
+ <Text>Address</Text>
61
+ </Column>
62
+ </BottomSheet>
63
+ </Host>
64
+ </View>
65
+ );
66
+ }
67
+ ```
68
+
69
+ `BottomSheet` uses `isPresented`/`onDismiss` — **not** `isOpened`, `isOpen`, `onIsOpenedChange`, or `onChange` (those are `@gorhom/bottom-sheet` props and will silently do nothing). `snapPoints` accepts `'half'`, `'full'`, `{ fraction: 0.5 }`, or `{ height: 400 }` and is optional (auto-sizes to content when omitted).
70
+
71
+ ## Choosing an approach
72
+
73
+ Work down this list and stop at the first layer that meets the need:
74
+
75
+ 1. **Universal components — start here.** Import from the `@expo/ui` root. One component tree runs unmodified on iOS, Android, and web from a single source (Compose on Android, SwiftUI on iOS, `react-native-web`/`react-dom` on web). No platform file splits. → `./references/universal.md`
76
+
77
+ 2. **Platform-specific (SwiftUI / Jetpack Compose).** Import from `@expo/ui/swift-ui` or `@expo/ui/jetpack-compose`. Use **only** when the universal layer is missing a component or modifier you need, or when you need platform-specific behavior or optimization. **Downside:** you write two trees and split them into `.ios.tsx` / `.android.tsx` files (or branch on `Platform.OS`) — more code to maintain.
78
+
79
+ > **`@expo/ui/swift-ui` is iOS-only. `@expo/ui/jetpack-compose` is Android-only.** Importing either in a file that runs on the other platform will crash at runtime with "Unable to get view config" errors. Isolate platform-specific trees in `.ios.tsx` / `.android.tsx` files placed in `components/` (never inside `app/` — Expo Router does not support platform extensions for route files), or guard with `Platform.OS` in a regular route file. `Host` must always be imported from `@expo/ui` (the universal package root), not from the platform-specific sub-packages. → `./references/swift-ui.md` and `./references/jetpack-compose.md`
80
+
81
+ **Already using an RN community UI library?** `@expo/ui` also ships **drop-in replacements** — API-compatible swaps for popular libraries (`@gorhom/bottom-sheet`, `@react-native-community/datetimepicker`, and more), imported from `@expo/ui/community/<name>`. This is a migration side-path for replacing an existing dependency, not a step in the universal-vs-platform decision above. → `./references/drop-in-replacements.md`
82
+
83
+ ## References
84
+
85
+ Consult these resources as needed:
86
+
87
+ ```
88
+ references/
89
+ universal.md Universal @expo/ui components and when to use them (SDK 56+)
90
+ drop-in-replacements.md API-compatible replacements for RN community UI libraries
91
+ swift-ui.md Platform-specific iOS UI: @expo/ui/swift-ui components, modifiers, RNHostView, useNativeState
92
+ jetpack-compose.md Platform-specific Android UI: @expo/ui/jetpack-compose components, modifiers, LazyColumn caveat, icons, useNativeState
93
+ ```
94
+
95
+ ## Submitting Feedback
96
+ If you encounter errors, misleading or outdated information in this skill, report it so Expo can improve:
97
+ ```bash
98
+ npx --yes @expo/agent-cli@latest feedback --category skills --subject "expo-ui" "<actionable feedback>"
99
+ ```
100
+ Only submit when you have something specific and actionable to report. Include as much relevant context as possible.
101
+ If an agent repeatedly fails at an Expo task or the user has to step in, submit a brief report of the task, expected result, and what went wrong using `--category evals` and the relevant Expo package or command as `--subject`.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Expo UI"
3
+ short_description: "Build native UI with @expo/ui — universal components first, SwiftUI/Jetpack Compose when needed"
4
+ default_prompt: "Use $expo-ui when adding or reviewing @expo/ui UI: universal cross-platform components (Host, Column, Row, Button, Text, List, ...), drop-in replacements for React Native community libraries, or platform-specific @expo/ui/swift-ui and @expo/ui/jetpack-compose trees and modifiers. Recommend universal components first; use drop-in replacements when migrating off a community UI library; reach for platform-specific layers only when universal is missing something or you need platform optimization (which requires .ios.tsx/.android.tsx splits)."
@@ -0,0 +1,27 @@
1
+ # Drop-in replacements for RN community libraries
2
+
3
+ `@expo/ui` ships API-compatible replacements for popular React Native community libraries, powered by native `@expo/ui` components (Jetpack Compose on Android, SwiftUI on iOS). Use these when migrating an existing app off a community UI dependency — the API matches the library being replaced, so the swap is usually just the import path.
4
+
5
+ ## Available replacements
6
+
7
+ Every drop-in lives under `@expo/ui/community/<kebab-case-name>`. Note which are default vs named imports.
8
+
9
+ | Replaces | Import |
10
+ |----------|--------|
11
+ | `@gorhom/bottom-sheet` | `import BottomSheet, { BottomSheetView } from '@expo/ui/community/bottom-sheet'` |
12
+ | `@react-native-community/datetimepicker` | `import DateTimePicker from '@expo/ui/community/datetime-picker'` |
13
+ | `@react-native-masked-view/masked-view` | `import { MaskedView } from '@expo/ui/community/masked-view'` |
14
+ | `@react-native-menu/menu` | `import { MenuView } from '@expo/ui/community/menu'` |
15
+ | `react-native-pager-view` | `import PagerView from '@expo/ui/community/pager-view'` |
16
+ | `@react-native-picker/picker` | `import { Picker } from '@expo/ui/community/picker'` |
17
+ | `@react-native-segmented-control/segmented-control` | `import SegmentedControl from '@expo/ui/community/segmented-control'` |
18
+ | `@react-native-community/slider` | `import Slider from '@expo/ui/community/slider'` |
19
+
20
+ ## Confirming the API
21
+
22
+ Each component has a dedicated docs page with setup and usage:
23
+
24
+ - Overview — https://docs.expo.dev/versions/latest/sdk/ui/drop-in-replacements/index.md
25
+ - Per component — https://docs.expo.dev/versions/latest/sdk/ui/drop-in-replacements/{component}/index.md (slug is the component name lowercased, no hyphens, e.g. `bottomsheet`, `datetimepicker`, `segmentedcontrol`)
26
+
27
+ The installed package's TypeScript types (`.d.ts`) are the most reliable source of truth for the exact props on your SDK version (@expo/ui is versioned with the SDK and its API can change between versions). Use the doc page to find platform support and any props that differ from the library being replaced.