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.
- package/dist/index.js +490 -105
- package/dist/templates/default/LICENSE +21 -0
- package/dist/templates/default/apps/blog/package.json +1 -0
- package/dist/templates/default/apps/changelog/package.json +1 -0
- package/dist/templates/default/apps/desktop/.oxfmtrc.json +5 -0
- package/dist/templates/default/apps/desktop/.oxlintrc.json +6 -0
- package/dist/templates/default/apps/desktop/README.md +58 -0
- package/dist/templates/default/apps/desktop/forge.config.mts +90 -0
- package/dist/templates/default/apps/desktop/index.html +12 -0
- package/dist/templates/default/apps/desktop/package.json +55 -0
- package/dist/templates/default/apps/desktop/src/declarations.d.ts +2 -0
- package/dist/templates/default/apps/desktop/src/index.css +8 -0
- package/dist/templates/default/apps/desktop/src/main.ts +58 -0
- package/dist/templates/default/apps/desktop/src/preload.ts +3 -0
- package/dist/templates/default/apps/desktop/src/renderer.ts +19 -0
- package/dist/templates/default/apps/desktop/tsconfig.json +14 -0
- package/dist/templates/default/apps/desktop/vite.main.config.mts +4 -0
- package/dist/templates/default/apps/desktop/vite.preload.config.mts +4 -0
- package/dist/templates/default/apps/desktop/vite.renderer.config.mts +4 -0
- package/dist/templates/default/apps/docs/package.json +1 -0
- package/dist/templates/default/apps/mobile/.agents/skills/agent-device/SKILL.md +22 -0
- package/dist/templates/default/apps/mobile/.agents/skills/android-emulator/SKILL.md +32 -0
- package/dist/templates/default/apps/mobile/.agents/skills/dogfood/SKILL.md +27 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/SKILL.md +176 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/references/app-store-metadata.md +497 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/references/ios-app-store.md +376 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/references/native-ios.md +167 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/references/play-store.md +244 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/references/testflight.md +62 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-app-stores/references/workflows.md +120 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-hosting/SKILL.md +431 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-hosting/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-observe/SKILL.md +46 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-observe/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-observe/references/metrics.md +98 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-observe/references/queries.md +444 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-observe/references/setup.md +529 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-observe/references/third-party.md +136 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-simulator/SKILL.md +237 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-simulator/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-simulator/references/controllers.md +139 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-simulator/references/logs-and-crashes.md +101 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-simulator/references/run-your-app.md +256 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-simulator/references/troubleshooting.md +56 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-update/SKILL.md +146 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-update/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-update-insights/SKILL.md +238 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-update-insights/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-update-insights/references/channel-insights-schema.md +47 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-update-insights/references/update-insights-schema.md +69 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-workflows/SKILL.md +99 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-workflows/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-workflows/scripts/fetch.js +109 -0
- package/dist/templates/default/apps/mobile/.agents/skills/eas-workflows/scripts/package.json +6 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-animation/LICENSE +21 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-animation/RECIPES.md +385 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-animation/SKILL.md +274 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-animation/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-app-clip/SKILL.md +290 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-app-clip/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-app-clip/references/native-module.md +96 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/SKILL.md +69 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/references/brownfield-integrated.md +551 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/references/brownfield-isolated.md +449 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/references/comparison.md +63 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/references/feature-integration.md +163 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/references/troubleshooting.md +88 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-brownfield/references/version-compatibility.md +40 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-data-fetching/SKILL.md +478 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-data-fetching/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-data-fetching/references/expo-router-loaders.md +341 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-data-fetching/references/offline-and-cancellation.md +68 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-design-system/SKILL.md +376 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-design-system/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-design-system/references/audit.md +190 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-design-system/references/native-slop.md +74 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-dev-client/SKILL.md +184 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-dev-client/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-dom/SKILL.md +425 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-dom/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-examples/SKILL.md +106 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-examples/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-examples/references/catalog.md +105 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-migrate-module/SKILL.md +124 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-migrate-module/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-migrate-module/references/compatibility.md +130 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-migrate-module/references/example.md +212 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-migrate-module/references/migration-map.md +457 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-module/SKILL.md +151 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-module/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-module/references/config-plugin.md +90 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-module/references/create-expo-module.md +206 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-module/references/lifecycle.md +127 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-module/references/module-config.md +48 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-module/references/native-module.md +286 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-module/references/native-view.md +171 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/SKILL.md +201 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/controls.md +231 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/gradients.md +106 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/icons.md +232 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/media.md +193 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/storage.md +121 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/visual-effects.md +198 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-native-ui/references/webgpu-three.md +605 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-overview/SKILL.md +120 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-overview/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-overview/references/launch-without-dev-menu.md +24 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-project-structure/SKILL.md +114 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-project-structure/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-router/SKILL.md +240 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-router/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-router/references/form-sheet.md +253 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-router/references/route-structure.md +229 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-router/references/search.md +248 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-router/references/tabs.md +433 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-router/references/toolbar-and-headers.md +284 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-router/references/zoom-transitions.md +158 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/SKILL.md +314 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/agents/visual-grader.md +52 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/references/design-rubric.md +45 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/references/runtime-matrix.md +34 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/check-static.sh +64 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/clean-fixture.sh +56 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/generate_viewer.py +450 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/latest-sdk.sh +46 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/make-fixture.sh +95 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/make-workspace.sh +31 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/snapshot-android.sh +284 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/snapshot-ios.sh +132 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/snapshot-web.sh +61 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/SKILL.md +101 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/references/drop-in-replacements.md +27 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/references/jetpack-compose.md +73 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/references/swift-ui.md +73 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/references/universal.md +104 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/scripts/list-components.js +193 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/SKILL.md +150 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/expo-av-to-audio.md +132 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/expo-av-to-video.md +160 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/native-tabs.md +124 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/new-architecture.md +79 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/react-19.md +79 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/react-compiler.md +59 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-upgrade/references/react-navigation-to-expo-router.md +61 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-web-to-native/SKILL.md +91 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-web-to-native/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-web-to-native/references/false-friends.md +119 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-web-to-native/references/native-patterns.md +39 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-web-to-native/references/run-as-goal.md +48 -0
- package/dist/templates/default/apps/mobile/.agents/skills/expo-web-to-native/references/verify-on-device.md +45 -0
- package/dist/templates/default/apps/mobile/.agents/skills/ios-simulator/SKILL.md +32 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/POWER.md +172 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/SKILL.md +238 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/agents/openai.yaml +4 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-analyze-app.md +208 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-analyze-js.md +264 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-barrel-exports.md +250 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-code-splitting.md +255 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-hermes-mmap.md +167 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-library-size.md +164 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-native-assets.md +208 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-r8-android.md +231 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/bundle-tree-shaking.md +215 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/bundle-treemap-source-map-explorer.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/controlled-textinput-pingpong.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/devtools-flamegraph.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/emerge-xray-ios.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/expo-atlas-treemap.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/flashlight-flatlist-vs-flashlist.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/fps-drop-graph.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/memory-heap-snapshot.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/tti-warm-start-diagram.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/view-hierarchy-flattening.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/xcode-instruments-templates.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/images/xcode-thread-view.png +0 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-animations-reanimated.md +273 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-atomic-state.md +190 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-bottomsheet.md +339 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-concurrent-react.md +238 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-lists-flatlist-flashlist.md +223 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-measure-fps.md +178 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-memory-leaks.md +168 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-profile-react.md +138 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-react-compiler.md +261 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/js-uncontrolled-components.md +219 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-android-16kb-alignment.md +114 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-measure-tti.md +221 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-memory-leaks.md +206 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-memory-patterns.md +240 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-platform-setup.md +112 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-profiling.md +140 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-sdks-over-polyfills.md +192 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-threading-model.md +230 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-turbo-modules.md +210 -0
- package/dist/templates/default/apps/mobile/.agents/skills/react-native-best-practices/references/native-view-flattening.md +180 -0
- package/dist/templates/default/apps/mobile/AGENTS.md +41 -0
- package/dist/templates/default/apps/mobile/app.json +38 -0
- package/dist/templates/default/apps/mobile/assets/expo.icon/Assets/expo-symbol 2.svg +3 -0
- package/dist/templates/default/apps/mobile/assets/expo.icon/Assets/grid.png +0 -0
- package/dist/templates/default/apps/mobile/assets/expo.icon/icon.json +40 -0
- package/dist/templates/default/apps/mobile/assets/images/android-icon-background.png +0 -0
- package/dist/templates/default/apps/mobile/assets/images/android-icon-foreground.png +0 -0
- package/dist/templates/default/apps/mobile/assets/images/android-icon-monochrome.png +0 -0
- package/dist/templates/default/apps/mobile/assets/images/icon.png +0 -0
- package/dist/templates/default/apps/mobile/assets/images/splash-icon.png +0 -0
- package/dist/templates/default/apps/mobile/eslint.config.js +10 -0
- package/dist/templates/default/apps/mobile/package.json +43 -0
- package/dist/templates/default/apps/mobile/skills-lock.json +185 -0
- package/dist/templates/default/apps/mobile/src/app/_layout.tsx +5 -0
- package/dist/templates/default/apps/mobile/src/app/index.tsx +17 -0
- package/dist/templates/default/apps/mobile/tsconfig.json +20 -0
- package/dist/templates/default/apps/web/.agents/skills/frontend-design/SKILL.md +71 -0
- package/dist/templates/default/apps/web/.agents/skills/web-design-guidelines/SKILL.md +39 -0
- package/dist/templates/default/apps/web/.env.example +3 -0
- package/dist/templates/default/apps/web/components.json +23 -0
- package/dist/templates/default/apps/web/eslint.config.ts +21 -0
- package/dist/templates/default/apps/web/package.json +39 -0
- package/dist/templates/default/apps/web/public/disposabl-logo.svg +8 -0
- package/dist/templates/default/apps/web/public/favicon.ico +0 -0
- package/dist/templates/default/apps/web/public/manifest.json +25 -0
- package/dist/templates/default/apps/web/skills-lock.json +17 -0
- package/dist/templates/default/apps/web/src/index.css +92 -0
- package/dist/templates/default/apps/web/src/routeTree.gen.ts +282 -0
- package/dist/templates/default/apps/web/src/router/__root.tsx +63 -0
- package/dist/templates/default/apps/web/src/router/_authenticated/dashboard.tsx +9 -0
- package/dist/templates/default/apps/web/src/router/_authenticated/todos/$id.tsx +27 -0
- package/dist/templates/default/apps/web/src/router/_authenticated/todos/index.tsx +33 -0
- package/dist/templates/default/apps/web/src/router/index.tsx +15 -0
- package/dist/templates/default/apps/web/src/router.tsx +20 -0
- package/dist/templates/default/apps/web/tsconfig.json +33 -0
- package/dist/templates/default/apps/web/tsr.config.json +6 -0
- package/dist/templates/default/apps/web/vite.config.ts +67 -0
- package/dist/templates/default/bun.lock +3932 -0
- package/dist/templates/default/bunfig.toml +5 -0
- package/dist/templates/default/disposabl.json +5 -0
- package/dist/templates/default/gitignore +10 -0
- package/dist/templates/default/package.json +31 -10
- package/dist/templates/default/packages/backend/.agents/skills/convex/SKILL.md +69 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-add/SKILL.md +26 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-advisor/SKILL.md +32 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-agent/SKILL.md +25 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-auth/SKILL.md +29 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-authz/SKILL.md +36 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-backup/SKILL.md +33 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-billing/SKILL.md +69 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-cost/SKILL.md +29 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/SKILL.md +325 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/agents/openai.yaml +14 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/assets/icon.svg +3 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/references/advanced-patterns.md +146 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/references/hybrid-components.md +38 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/references/local-components.md +39 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-create-component/references/packaged-components.md +54 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-crons/SKILL.md +23 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-deploy-guard/SKILL.md +29 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-design/SKILL.md +30 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-docs/SKILL.md +31 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-domains/SKILL.md +26 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-env/SKILL.md +24 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-expert/SKILL.md +38 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-explain-app/SKILL.md +29 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-improve-convex-plugin/SKILL.md +24 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-insights/SKILL.md +32 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-launch-readiness/SKILL.md +35 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-migrate/SKILL.md +23 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-migrate-rehearse/SKILL.md +31 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-monitor/SKILL.md +22 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-optimize/SKILL.md +26 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-quickstart/SKILL.md +29 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-quickstart/agents/openai.yaml +14 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-quickstart/assets/icon.svg +4 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-reviewer/SKILL.md +26 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-seed/SKILL.md +23 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-self-heal/SKILL.md +38 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-sentinel/SKILL.md +25 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-suggest/SKILL.md +27 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-test/SKILL.md +23 -0
- package/dist/templates/default/packages/backend/.agents/skills/convex-verify/SKILL.md +34 -0
- package/dist/templates/default/packages/backend/.prettierignore +4 -0
- package/dist/templates/default/packages/backend/AGENTS.md +18 -0
- package/dist/templates/default/packages/backend/CLAUDE.md +13 -0
- package/dist/templates/default/packages/backend/README.md +25 -0
- package/dist/templates/default/packages/backend/convex/_generated/ai/ai-files.state.json +6 -0
- package/dist/templates/default/packages/backend/convex/_generated/ai/guidelines.md +286 -0
- package/dist/templates/default/packages/backend/convex/_generated/api.d.ts +66 -0
- package/dist/templates/default/packages/backend/convex/_generated/api.js +23 -0
- package/dist/templates/default/packages/backend/convex/_generated/dataModel.d.ts +60 -0
- package/dist/templates/default/packages/backend/convex/_generated/server.d.ts +164 -0
- package/dist/templates/default/packages/backend/convex/_generated/server.js +101 -0
- package/dist/templates/default/packages/backend/convex/auth.config.ts +14 -0
- package/dist/templates/default/packages/backend/convex/auth.ts +15 -0
- package/dist/templates/default/packages/backend/convex/convex.config.ts +30 -0
- package/dist/templates/default/packages/backend/convex/http.ts +5 -0
- package/dist/templates/default/packages/backend/convex/mcp.ts +8 -0
- package/dist/templates/default/packages/backend/convex/schema.ts +10 -0
- package/dist/templates/default/packages/backend/convex/todos/index.ts +26 -0
- package/dist/templates/default/packages/backend/convex/todos/internal.ts +43 -0
- package/dist/templates/default/packages/backend/convex/tsconfig.json +27 -0
- package/dist/templates/default/packages/backend/convex/users.ts +20 -0
- package/dist/templates/default/packages/backend/eslint.config.mjs +62 -0
- package/dist/templates/default/packages/backend/package.json +36 -0
- package/dist/templates/default/packages/backend/skills-lock.json +203 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/accordion.tsx +77 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/alert-dialog.tsx +185 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/alert.tsx +75 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/aspect-ratio.tsx +22 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/attachment.tsx +207 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/avatar.tsx +106 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/badge.tsx +51 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/breadcrumb.tsx +121 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/bubble.tsx +127 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/button-group.tsx +87 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/button.tsx +57 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/calendar.tsx +241 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/card.tsx +102 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/carousel.tsx +239 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/chart.tsx +368 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/checkbox.tsx +27 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/code-block.tsx +243 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/collapsible.tsx +19 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/combobox.tsx +300 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/command.tsx +194 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/context-menu.tsx +271 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/dialog.tsx +156 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/direction.tsx +4 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/drawer.tsx +224 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/dropdown-menu.tsx +269 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/empty.tsx +103 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/field.tsx +236 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/hover-card.tsx +50 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/input-group.tsx +158 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/input-otp.tsx +83 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/input.tsx +19 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/item.tsx +201 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/kbd.tsx +26 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/label.tsx +19 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/marker.tsx +70 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/menubar.tsx +284 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/message-scroller.tsx +128 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/message.tsx +91 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/native-select.tsx +64 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/navigation-menu.tsx +170 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/pagination.tsx +133 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/popover.tsx +87 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/progress.tsx +82 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/questionnaire.tsx +330 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/radio-group.tsx +35 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/resizable.tsx +49 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/scroll-area.tsx +51 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/select.tsx +201 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/separator.tsx +22 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/sheet.tsx +132 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/sidebar.tsx +723 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/skeleton.tsx +13 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/slider.tsx +51 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/spinner.tsx +16 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/switch.tsx +31 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/table.tsx +113 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/tabs.tsx +81 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/textarea.tsx +17 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/toast.tsx +229 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/toggle-group.tsx +87 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/toggle.tsx +42 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/tooltip.tsx +65 -0
- package/dist/templates/default/packages/disposabl-kit/client/components/ui/trace.tsx +161 -0
- package/dist/templates/default/packages/disposabl-kit/client/hooks/use-mobile.ts +21 -0
- package/dist/templates/default/packages/disposabl-kit/client/lib/prerender.ts +89 -0
- package/dist/templates/default/packages/disposabl-kit/client/lib/return-to.ts +12 -0
- package/dist/templates/default/packages/disposabl-kit/client/lib/utils.ts +1 -0
- package/dist/templates/default/packages/disposabl-kit/client/routes/_auth-pages/login.tsx +114 -0
- package/dist/templates/default/packages/disposabl-kit/client/routes/_auth-pages/signUp.tsx +120 -0
- package/dist/templates/default/packages/disposabl-kit/client/routes/_authenticated/route.tsx +38 -0
- package/dist/templates/default/packages/disposabl-kit/client/routes/consent.tsx +137 -0
- package/dist/templates/default/packages/disposabl-kit/client/routes/route.tsx +30 -0
- package/dist/templates/default/packages/disposabl-kit/client/styles/globals.css +60 -0
- package/dist/templates/default/packages/disposabl-kit/client/vite.config.ts +32 -0
- package/dist/templates/default/packages/disposabl-kit/components.json +23 -0
- package/dist/templates/default/packages/disposabl-kit/eslint.config.js +21 -0
- package/dist/templates/default/packages/disposabl-kit/package.json +60 -0
- package/dist/templates/default/packages/disposabl-kit/server/http.ts +86 -0
- package/dist/templates/default/packages/disposabl-kit/server/lib/functions.ts +40 -0
- package/dist/templates/default/packages/disposabl-kit/server/lib/platforms.ts +20 -0
- package/dist/templates/default/packages/disposabl-kit/server/lib/static-routes.ts +56 -0
- package/dist/templates/default/packages/disposabl-kit/tsconfig.json +17 -0
- package/dist/templates/default/patches/@convex-dev%2Fauth@2.0.0-beta.0.patch +310 -0
- package/dist/templates/default/patches/@convex-dev%2Fstatic-hosting@0.2.1.patch +187 -0
- package/dist/templates/default/tsconfig.json +9 -0
- package/dist/templates/default/turbo.json +51 -0
- package/package.json +21 -5
- package/README.md +0 -34
- package/dist/templates/default/README.md +0 -12
- package/dist/templates/default/docs/index.html +0 -8
- package/dist/templates/default/eslint.config.js +0 -18
- package/dist/templates/default/index.ts +0 -14
package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/make-workspace.sh
ADDED
|
@@ -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"
|
package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/snapshot-ios.sh
ADDED
|
@@ -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"
|
package/dist/templates/default/apps/mobile/.agents/skills/expo-skill-eval/scripts/snapshot-web.sh
ADDED
|
@@ -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)."
|
package/dist/templates/default/apps/mobile/.agents/skills/expo-ui/references/drop-in-replacements.md
ADDED
|
@@ -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.
|