vybekiit 0.7.26 → 0.7.27
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/bin.js +3891 -1301
- package/dist/global-skills/aws-cdk/SKILL.md +19 -5
- package/dist/global-skills/aws-cdk/references/fast-deployments.md +191 -0
- package/dist/global-skills/aws-cdk/references/troubleshooting-deployment.md +16 -0
- package/dist/global-skills/aws-cloudformation/SKILL.md +16 -26
- package/dist/global-skills/aws-cloudformation/references/check-cloudformation-template-compliance.script.md +7 -3
- package/dist/global-skills/aws-cloudformation/references/cloudformation-language-server.md +177 -0
- package/dist/global-skills/aws-cloudformation/references/cloudformation-pre-deploy-validation.script.md +8 -2
- package/dist/global-skills/aws-cloudformation/references/persist-template-context.script.md +5 -8
- package/dist/global-skills/aws-cloudformation/references/retrieve-template-context.script.md +1 -1
- package/dist/global-skills/aws-cloudformation/references/security-considerations.md +51 -0
- package/dist/global-skills/aws-cloudformation/references/troubleshoot-failed-stack.script.md +138 -0
- package/dist/global-skills/aws-cloudformation/references/{validate-cloudformation-template.script.md → validate-with-cfn-lint.script.md} +15 -27
- package/dist/global-skills/aws-cloudformation/references/validate-with-cloudformation-validate.script.md +181 -0
- package/dist/global-skills/aws-cloudformation/references/validation-tool-selection.md +44 -0
- package/dist/global-skills/aws-serverless/SKILL.md +9 -1
- package/dist/global-skills/aws-serverless/references/architecture.md +3 -1
- package/dist/global-skills/aws-serverless/references/lambda.md +3 -1
- package/dist/global-skills/aws-serverless/references/orchestration.md +1 -0
- package/dist/global-skills/better-auth-best-practices/SKILL.md +18 -8
- package/dist/global-skills/eas-app-stores/SKILL.md +31 -15
- package/dist/global-skills/eas-app-stores/agents/openai.yaml +2 -2
- package/dist/global-skills/eas-app-stores/references/ios-app-store.md +37 -32
- package/dist/global-skills/eas-app-stores/references/native-ios.md +167 -0
- package/dist/global-skills/eas-app-stores/references/play-store.md +3 -7
- package/dist/global-skills/eas-app-stores/references/testflight.md +39 -35
- package/dist/global-skills/eas-simulator/SKILL.md +48 -26
- package/dist/global-skills/eas-simulator/references/controllers.md +32 -3
- package/dist/global-skills/eas-simulator/references/run-your-app.md +34 -4
- package/dist/global-skills/eas-simulator/references/troubleshooting.md +8 -4
- package/dist/global-skills/eas-update/SKILL.md +146 -0
- package/dist/global-skills/eas-update/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-animation/RECIPES.md +2 -2
- package/dist/global-skills/expo-animation/SKILL.md +9 -2
- package/dist/global-skills/expo-brownfield/SKILL.md +18 -11
- package/dist/global-skills/expo-brownfield/agents/openai.yaml +2 -2
- package/dist/global-skills/expo-brownfield/references/brownfield-integrated.md +94 -69
- package/dist/global-skills/expo-brownfield/references/brownfield-isolated.md +40 -42
- package/dist/global-skills/expo-brownfield/references/comparison.md +5 -5
- package/dist/global-skills/expo-brownfield/references/feature-integration.md +163 -0
- package/dist/global-skills/expo-brownfield/references/troubleshooting.md +17 -17
- package/dist/global-skills/expo-brownfield/references/version-compatibility.md +40 -0
- package/dist/global-skills/expo-data-fetching/SKILL.md +27 -6
- package/dist/global-skills/expo-design-system/SKILL.md +27 -7
- package/dist/global-skills/expo-design-system/references/audit.md +7 -2
- package/dist/global-skills/expo-design-system/references/native-slop.md +74 -0
- package/dist/global-skills/expo-examples/SKILL.md +0 -1
- package/dist/global-skills/expo-examples/references/catalog.md +1 -1
- package/dist/global-skills/expo-migrate-module/SKILL.md +21 -10
- package/dist/global-skills/expo-migrate-module/references/compatibility.md +80 -23
- package/dist/global-skills/expo-migrate-module/references/migration-map.md +162 -11
- package/dist/global-skills/expo-native-ui/SKILL.md +25 -16
- package/dist/global-skills/expo-native-ui/agents/openai.yaml +2 -2
- package/dist/global-skills/expo-native-ui/references/controls.md +5 -46
- package/dist/global-skills/expo-native-ui/references/icons.md +21 -2
- package/dist/global-skills/expo-native-ui/references/media.md +15 -20
- package/dist/global-skills/expo-native-ui/references/visual-effects.md +12 -11
- package/dist/global-skills/expo-overview/SKILL.md +17 -12
- package/dist/global-skills/expo-router/SKILL.md +5 -3
- package/dist/global-skills/expo-router/references/tabs.md +5 -5
- package/dist/global-skills/expo-upgrade/SKILL.md +3 -1
- package/dist/global-skills/expo-web-to-native/references/false-friends.md +2 -2
- package/dist/global-skills/expo-web-to-native/references/native-patterns.md +1 -1
- package/dist/global-skills/firebase-ai-logic-basics/SKILL.md +13 -16
- package/dist/global-skills/firebase-ai-logic-basics/references/ios_setup.md +4 -5
- package/dist/global-skills/firebase-ai-logic-basics/references/usage_patterns_android.md +4 -4
- package/dist/global-skills/firebase-ai-logic-basics/references/usage_patterns_web.md +3 -3
- package/dist/global-skills/firebase-auth-basics/SKILL.md +11 -6
- package/dist/global-skills/firebase-auth-basics/references/client_sdk_android.md +4 -5
- package/dist/global-skills/firebase-auth-basics/references/client_sdk_web.md +3 -3
- package/dist/global-skills/firebase-auth-basics/references/flutter_setup.md +24 -25
- package/dist/global-skills/firebase-auth-basics/references/security_rules.md +4 -2
- package/dist/global-skills/firebase-crashlytics/references/android_setup.md +7 -4
- package/dist/global-skills/firebase-crashlytics/references/ios_setup.md +2 -3
- package/dist/global-skills/firebase-data-connect/SKILL.md +2 -1
- package/dist/global-skills/firebase-data-connect/examples.md +4 -4
- package/dist/global-skills/firebase-data-connect/reference/config.md +5 -4
- package/dist/global-skills/firebase-data-connect/reference/realtime.md +1 -2
- package/dist/global-skills/firebase-data-connect/reference/sdk_flutter.md +2 -2
- package/dist/global-skills/firebase-data-connect/reference/sdk_ios.md +2 -2
- package/dist/global-skills/firebase-data-connect/reference/sdk_web.md +17 -6
- package/dist/global-skills/firebase-data-connect/reference/security.md +5 -5
- package/dist/global-skills/firebase-data-connect/templates.md +2 -1
- package/dist/global-skills/firebase-firestore/SKILL.md +20 -8
- package/dist/global-skills/firebase-firestore/references/enterprise/android_sdk_usage.md +5 -4
- package/dist/global-skills/firebase-firestore/references/enterprise/data_model.md +12 -3
- package/dist/global-skills/firebase-firestore/references/enterprise/indexes.md +16 -18
- package/dist/global-skills/firebase-firestore/references/enterprise/provisioning.md +1 -1
- package/dist/global-skills/firebase-firestore/references/enterprise/python_sdk_usage.md +5 -1
- package/dist/global-skills/firebase-firestore/references/enterprise/web_sdk_usage.md +7 -7
- package/dist/global-skills/firebase-firestore/references/standard/android_sdk_usage.md +5 -5
- package/dist/global-skills/firebase-firestore/references/standard/flutter_setup.md +4 -4
- package/dist/global-skills/firebase-firestore/references/standard/indexes.md +16 -18
- package/dist/global-skills/firebase-firestore/references/standard/provisioning.md +1 -1
- package/dist/global-skills/firebase-remote-config-basics/SKILL.md +0 -5
- package/dist/global-skills/firebase-remote-config-basics/references/android_setup.md +36 -8
- package/dist/global-skills/firebase-remote-config-basics/references/ios_setup.md +1 -7
- package/dist/global-skills/firebase-security-rules-auditor/SKILL.md +17 -6
- package/dist/global-skills/{firebase-firestore/references/standard/security_rules.md → firestore-rules-creation/SKILL.md} +24 -13
- package/dist/global-skills/grow-my-customers/SKILL.md +23 -0
- package/dist/global-skills/instrument-feature-flags/SKILL.md +25 -25
- package/dist/global-skills/instrument-feature-flags/references/adding-feature-flag-code.md +141 -285
- package/dist/global-skills/instrument-feature-flags/references/android.md +6 -15
- package/dist/global-skills/instrument-feature-flags/references/api.md +4 -11
- package/dist/global-skills/instrument-feature-flags/references/best-practices.md +1 -13
- package/dist/global-skills/instrument-feature-flags/references/django.md +14 -27
- package/dist/global-skills/instrument-feature-flags/references/dotnet.md +20 -79
- package/dist/global-skills/instrument-feature-flags/references/elixir.md +1 -9
- package/dist/global-skills/instrument-feature-flags/references/flask.md +13 -13
- package/dist/global-skills/instrument-feature-flags/references/flutter.md +3 -24
- package/dist/global-skills/instrument-feature-flags/references/go.md +3 -15
- package/dist/global-skills/instrument-feature-flags/references/ios.md +4 -17
- package/dist/global-skills/instrument-feature-flags/references/java.md +5 -13
- package/dist/global-skills/instrument-feature-flags/references/laravel.md +13 -17
- package/dist/global-skills/instrument-feature-flags/references/next-js.md +25 -32
- package/dist/global-skills/instrument-feature-flags/references/nodejs.md +8 -15
- package/dist/global-skills/instrument-feature-flags/references/php.md +1 -15
- package/dist/global-skills/instrument-feature-flags/references/python.md +2 -15
- package/dist/global-skills/instrument-feature-flags/references/react-native.md +13 -15
- package/dist/global-skills/instrument-feature-flags/references/react.md +17 -21
- package/dist/global-skills/instrument-feature-flags/references/ruby-on-rails.md +37 -83
- package/dist/global-skills/instrument-feature-flags/references/ruby.md +2 -15
- package/dist/global-skills/instrument-feature-flags/references/rust.md +13 -25
- package/dist/global-skills/instrument-feature-flags/references/usage.md +14 -63
- package/dist/global-skills/instrument-feature-flags/references/web.md +9 -14
- package/dist/global-skills/instrument-product-analytics/SKILL.md +29 -29
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-hybrid.md +3 -1
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-ssr.md +3 -1
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-static.md +3 -1
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-view-transitions.md +3 -1
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-ruby-on-rails.md +3 -1
- package/dist/global-skills/instrument-product-analytics/references/android.md +72 -107
- package/dist/global-skills/instrument-product-analytics/references/angular.md +26 -28
- package/dist/global-skills/instrument-product-analytics/references/astro.md +13 -24
- package/dist/global-skills/instrument-product-analytics/references/configuration.md +45 -63
- package/dist/global-skills/instrument-product-analytics/references/django.md +14 -27
- package/dist/global-skills/instrument-product-analytics/references/dotnet.md +20 -79
- package/dist/global-skills/instrument-product-analytics/references/elixir.md +47 -49
- package/dist/global-skills/instrument-product-analytics/references/flask.md +13 -13
- package/dist/global-skills/instrument-product-analytics/references/flutter.md +60 -90
- package/dist/global-skills/instrument-product-analytics/references/go.md +17 -56
- package/dist/global-skills/instrument-product-analytics/references/identify-users.md +15 -15
- package/dist/global-skills/instrument-product-analytics/references/ios.md +11 -15
- package/dist/global-skills/instrument-product-analytics/references/laravel.md +13 -17
- package/dist/global-skills/instrument-product-analytics/references/next-js.md +25 -32
- package/dist/global-skills/instrument-product-analytics/references/nuxt-js-3-6.md +13 -27
- package/dist/global-skills/instrument-product-analytics/references/nuxt-js.md +14 -28
- package/dist/global-skills/instrument-product-analytics/references/php.md +33 -84
- package/dist/global-skills/instrument-product-analytics/references/posthog-python.md +229 -9
- package/dist/global-skills/instrument-product-analytics/references/python.md +415 -106
- package/dist/global-skills/instrument-product-analytics/references/react-native.md +161 -155
- package/dist/global-skills/instrument-product-analytics/references/react-router-v6.md +12 -33
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-data-mode.md +15 -33
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-declarative-mode.md +12 -33
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-framework-mode.md +26 -41
- package/dist/global-skills/instrument-product-analytics/references/ruby-on-rails.md +37 -83
- package/dist/global-skills/instrument-product-analytics/references/ruby.md +48 -108
- package/dist/global-skills/instrument-product-analytics/references/svelte.md +18 -24
- package/dist/global-skills/instrument-product-analytics/references/tanstack-start.md +17 -19
- package/dist/global-skills/instrument-product-analytics/references/usage.md +14 -63
- package/dist/global-skills/instrument-product-analytics/references/vue-js.md +29 -28
- package/dist/global-skills/manifest.json +8 -2
- package/dist/global-skills/mongodb-search-and-ai/SKILL.md +28 -37
- package/dist/global-skills/mongodb-search-and-ai/references/automated-embedding.md +438 -0
- package/dist/global-skills/mongodb-search-and-ai/references/hybrid-search.md +60 -4
- package/dist/global-skills/mongodb-search-and-ai/references/vector-search.md +46 -108
- package/dist/global-skills/neon/SKILL.md +207 -213
- package/dist/global-skills/neon/references/auth.md +12 -0
- package/dist/global-skills/neon/references/claimable-neon.md +10 -14
- package/dist/global-skills/neon/references/function-triggers.md +53 -0
- package/dist/global-skills/neon/references/logs-loki.md +61 -0
- package/dist/global-skills/neon/references/parse-env.md +32 -0
- package/dist/global-skills/neon/references/sdk.md +7 -0
- package/dist/global-skills/neon-ai-gateway/SKILL.md +14 -16
- package/dist/global-skills/neon-auth/SKILL.md +155 -0
- package/dist/global-skills/neon-auth/references/managed-auth.md +173 -0
- package/dist/global-skills/neon-auth/references/self-managed.md +25 -0
- package/dist/global-skills/neon-functions/SKILL.md +159 -84
- package/dist/global-skills/neon-functions/references/ai-sdk.md +4 -6
- package/dist/global-skills/neon-functions/references/function-triggers.md +249 -0
- package/dist/global-skills/neon-functions/references/mastra-studio.md +3 -3
- package/dist/global-skills/neon-functions/references/mcp.md +1 -1
- package/dist/global-skills/neon-functions/references/production-hardening.md +340 -0
- package/dist/global-skills/neon-functions/references/sse.md +8 -5
- package/dist/global-skills/neon-object-storage/SKILL.md +10 -11
- package/dist/global-skills/neon-postgres/SKILL.md +120 -17
- package/dist/global-skills/neon-postgres/references/full-text-search.md +99 -0
- package/dist/global-skills/neon-postgres/references/hybrid-search.md +90 -0
- package/dist/global-skills/neon-postgres/references/lakebase-search-drizzle.md +172 -0
- package/dist/global-skills/neon-postgres/references/vector-search.md +137 -0
- package/dist/global-skills/neon-postgres-branches/SKILL.md +3 -3
- package/dist/global-skills/neon-postgres-egress-optimizer/SKILL.md +1 -1
- package/dist/global-skills/onboarding/SKILL.md +8 -6
- package/dist/global-skills/resend/SKILL.md +4 -2
- package/dist/global-skills/resend/references/broadcasts.md +6 -1
- package/dist/global-skills/resend/references/receiving.md +29 -10
- package/dist/global-skills/resend/references/sending/email-management.md +14 -4
- package/dist/global-skills/resend/references/topics.md +9 -6
- package/dist/global-skills/resend/references/usage.md +117 -0
- package/dist/global-skills/resend/references/webhooks.md +59 -2
- package/dist/global-skills/stripe-best-practices/SKILL.md +35 -29
- package/dist/global-skills/stripe-best-practices/references/billing.md +9 -2
- package/dist/global-skills/stripe-best-practices/references/payments.md +4 -2
- package/dist/global-skills/stripe-best-practices/references/security.md +3 -1
- package/dist/global-skills/stripe-best-practices/references/tax.md +39 -20
- package/dist/global-skills/supabase/SKILL.md +6 -0
- package/dist/global-skills/use-railway/SKILL.md +42 -22
- package/dist/global-skills/use-railway/references/analyze-db.md +7 -6
- package/dist/global-skills/use-railway/references/cloud-agents.md +70 -0
- package/dist/global-skills/use-railway/references/configure.md +17 -2
- package/dist/global-skills/use-railway/references/databases.md +107 -0
- package/dist/global-skills/use-railway/references/deploy.md +5 -5
- package/dist/global-skills/use-railway/references/feature-flags.md +25 -13
- package/dist/global-skills/use-railway/references/iac.md +66 -77
- package/dist/global-skills/use-railway/references/operate.md +26 -3
- package/dist/global-skills/use-railway/references/request.md +31 -23
- package/dist/global-skills/use-railway/references/setup.md +16 -5
- package/dist/global-skills/use-railway/references/tracing.md +261 -0
- package/dist/global-skills/use-railway/references/usage.md +52 -0
- package/dist/global-skills/validate-my-idea/SKILL.md +54 -0
- package/dist/global-skills/{feedback → vybekiit-feedback}/SKILL.md +16 -12
- package/dist/global-skills/watch-my-app/SKILL.md +53 -0
- package/dist/global-skills/workers-best-practices/SKILL.md +36 -103
- package/dist/global-skills/workers-best-practices/references/configuration.md +139 -0
- package/dist/global-skills/workers-best-practices/references/platform-apis.md +51 -0
- package/dist/global-skills/workers-best-practices/references/{rules.md → runtime-patterns.md} +13 -137
- package/dist/global-skills/wrangler/SKILL.md +48 -901
- package/dist/global-skills/xcode-project-setup/scripts/xcode_spm_setup/Sources/main.swift +19 -15
- package/package.json +9 -8
- package/dist/global-skills/expo-native-ui/references/animations.md +0 -220
- package/dist/global-skills/firebase-firestore/references/enterprise/security_rules.md +0 -577
- package/dist/global-skills/workers-best-practices/references/review.md +0 -174
|
@@ -1,58 +1,62 @@
|
|
|
1
1
|
# TestFlight
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
For a SwiftUI/UIKit app with no React Native runtime, start with [native-ios.md](native-ios.md). EAS can build and submit it without adding Expo or React Native. For an established Expo/React Native app, `npx testflight` is also a convenient setup flow.
|
|
4
4
|
|
|
5
|
-
## Submit
|
|
5
|
+
## Submit an identified build
|
|
6
|
+
|
|
7
|
+
Use a store-distribution profile and record the source revision and returned build ID:
|
|
6
8
|
|
|
7
9
|
```bash
|
|
8
|
-
|
|
10
|
+
eas build --platform ios --profile testflight --no-wait --non-interactive
|
|
11
|
+
# After checking that build's result:
|
|
12
|
+
eas submit --platform ios --profile testflight --id BUILD_ID --non-interactive
|
|
9
13
|
```
|
|
10
14
|
|
|
11
|
-
|
|
15
|
+
Use the project's actual profile name. If `--non-interactive` exposes missing first-time credentials, configure them with `eas credentials -p ios`; repeated noninteractive retries will not complete that setup. Keep an existing EAS project, Apple team, bundle ID, and App Store Connect app record aligned.
|
|
16
|
+
|
|
17
|
+
`eas build --auto-submit` can submit the finished build with its matching submit profile. For separate jobs, pass the explicit build ID rather than selecting whichever unrelated build is newest.
|
|
12
18
|
|
|
13
|
-
##
|
|
19
|
+
## Read status without reopening a submission
|
|
14
20
|
|
|
15
|
-
|
|
21
|
+
The following commands were verified with EAS CLI 23.2.0, including read-only checks of a completed iOS submission and its actual TestFlight state:
|
|
16
22
|
|
|
17
23
|
```bash
|
|
18
|
-
|
|
19
|
-
|
|
24
|
+
eas submit:list --platform ios --json
|
|
25
|
+
eas submit:view SUBMISSION_ID --json
|
|
26
|
+
eas submit:status --platform ios --profile testflight --json --non-interactive
|
|
20
27
|
```
|
|
21
28
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
## Why TestFlight First
|
|
25
|
-
|
|
26
|
-
- Internal testers get builds instantly (no review)
|
|
27
|
-
- External testers require one Beta App Review, then instant updates
|
|
28
|
-
- Catch crashes before App Store review rejects you
|
|
29
|
-
- TestFlight crash reports are better than App Store crash reports
|
|
30
|
-
- 90 days to test before builds expire
|
|
31
|
-
- Real users on real devices, not simulators
|
|
29
|
+
Use the project's actual profile. `submit:view` reports the EAS job; `submit:status` reads App Store Connect and reports App Store versions and TestFlight processing/internal/external states. The latter needs an App Store Connect API key from the selected profile, environment, or existing EAS credentials. In noninteractive mode, a missing key is a setup error; it does not mean the build failed or does not exist. A beta state alone does not establish that a particular tester has access.
|
|
32
30
|
|
|
33
|
-
|
|
31
|
+
Older CLIs such as 18.6.0 lack these commands. Check `eas --version` and command help, or use a pinned `npx eas-cli@23.2.0` invocation. Prefer the supported CLI over importing its internal Node modules or writing private GraphQL queries. An errored `submit:view --json` result can still omit the underlying error; follow its log URLs to diagnose it.
|
|
34
32
|
|
|
35
|
-
|
|
33
|
+
## Track the release state
|
|
36
34
|
|
|
37
|
-
|
|
35
|
+
| Verified state | What it establishes | Next check |
|
|
36
|
+
| --- | --- | --- |
|
|
37
|
+
| EAS build finished | An artifact was produced | Confirm the intended build ID, source revision and store-distribution profile |
|
|
38
|
+
| Submission queued | EAS scheduled an upload | Follow the returned submission URL and worker logs |
|
|
39
|
+
| Apple upload/processing succeeded | Apple accepted the binary | Check TestFlight availability and any export-compliance work |
|
|
40
|
+
| Build assigned and available to testers | The intended testers can install it | Verify the beta app on a device |
|
|
41
|
+
| App Review approved and released | Public App Store distribution | Only part of an authorized production release |
|
|
38
42
|
|
|
39
|
-
|
|
43
|
+
Do not report an upload as finished based only on `--no-wait` returning successfully. If a submission fails with an empty summary, inspect its worker logs; the underlying Apple error may be there. Report the exact version/build and the furthest state actually verified.
|
|
40
44
|
|
|
41
|
-
-
|
|
42
|
-
- Beta App Review is faster and more lenient than App Store Review
|
|
43
|
-
- Add release notes—testers actually read them
|
|
44
|
-
- Use TestFlight's built-in feedback and screenshots
|
|
45
|
-
- Never go straight to App Store. Ever.
|
|
45
|
+
[Apple's TestFlight overview](https://developer.apple.com/help/app-store-connect/test-a-beta-version/testflight-overview/) describes tester limits and beta review. Processing, compliance, group assignment and invitations affect availability; do not promise immediate installation. Internal testing and external beta review are separate from public App Review. Add builds to existing requested groups when authorized; do not create invitations or expand distribution implicitly.
|
|
46
46
|
|
|
47
47
|
## Troubleshooting
|
|
48
48
|
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
| Symptom | Action |
|
|
50
|
+
| --- | --- |
|
|
51
|
+
| Required agreement missing or expired | The Account Holder must resolve it for the app's Apple team. Retrying or rebuilding does not accept an agreement. |
|
|
52
|
+
| App missing in App Store Connect | Check the selected organization and `ascAppId` against the native bundle identifier. One login may belong to several teams. |
|
|
53
|
+
| Duplicate build number despite EAS auto-increment | Inspect the archive's `CFBundleVersion`; for native Swift, check explicit versus generated plist configuration in `native-ios.md`. |
|
|
54
|
+
| Invalid large app icon / alpha channel | For the default (Any/light) AppIcon PNG, remove the alpha channel and rebuild. Even an all-opaque RGBA file can fail. Check the icon selected by that profile; preserve transparency in dark variants and Icon Composer layers. See the icon checks in `native-ios.md`. |
|
|
55
|
+
| Upload accepted but no installable build | Check processing/compliance state and the intended tester group's build assignment in App Store Connect. |
|
|
56
|
+
| Optional release-notes feature rejected by the EAS plan | Complete the required upload without that optional parameter and use App Store Connect for notes. Do not rebuild a valid binary or change the account plan for this. |
|
|
51
57
|
|
|
52
|
-
|
|
53
|
-
Use `autoIncrement: true` in `eas.json`. Problem solved.
|
|
58
|
+
After an archive-content failure, fix the cause, validate the new artifact and submit its exact ID. After an account/submission-only failure, reuse the valid existing artifact once the account issue is resolved. Keep the requested release scope; uploading a beta does not authorize a public App Store release.
|
|
54
59
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
```
|
|
60
|
+
EAS CLI 23.2.0 also provides `eas submit:retry SUBMISSION_ID --json --non-interactive`. Check `submit:view` for retry eligibility and diagnose the cause first. Retrying an unchanged archive cannot fix its build number or icon; submit the corrected build instead. Use retry only when repeating the existing authorized upload is appropriate.
|
|
61
|
+
|
|
62
|
+
Use [EAS Submit for iOS](https://docs.expo.dev/submit/ios/) for current CLI/configuration guidance, and [Apple's internal-tester guide](https://developer.apple.com/help/app-store-connect/test-a-beta-version/add-internal-testers/) for group setup. EAS upload success alone does not show that a particular tester has access.
|
|
@@ -8,11 +8,11 @@ allowed-tools: "Bash(npx *eas-cli@*), Bash(npx *agent-device@*), Bash(npx expo *
|
|
|
8
8
|
|
|
9
9
|
# EAS Simulator
|
|
10
10
|
|
|
11
|
-
> **EAS service - costs apply.** EAS Simulator
|
|
11
|
+
> **EAS service - costs apply.** EAS Simulator is a hosted EAS service. Session usage is subject to your account's pricing and limits. See https://expo.dev/pricing for current terms.
|
|
12
12
|
|
|
13
13
|
EAS Simulator runs a remote iOS simulator or Android emulator on EAS infrastructure that you drive from your machine — from the CLI, from an AI agent (via `agent-device`), and from a browser preview. It's the unlock for **environments that can't run a simulator locally** (Linux boxes, cloud/background agents like Cursor Cloud), and for letting an agent *verify* a change on a real device instead of only reasoning about code.
|
|
14
14
|
|
|
15
|
-
The `simulator:*` commands are **experimental and hidden**, and need a recent eas-cli (≥ 20.3.0 as of writing) — which is why this skill runs everything via `npx --yes eas-cli@latest`. Flags and verbs may change;
|
|
15
|
+
The `simulator:*` commands are **experimental and hidden**, and need a recent eas-cli (≥ 20.3.0 as of writing) — which is why this skill runs everything via `npx --yes eas-cli@latest`. Flags and verbs may change; **the relevant subcommand's `--help` output is authoritative.**
|
|
16
16
|
|
|
17
17
|
## When to use
|
|
18
18
|
|
|
@@ -20,32 +20,32 @@ The frontmatter `description` carries the trigger phrases. In short: use this to
|
|
|
20
20
|
|
|
21
21
|
## Cloud vs local: decide this first
|
|
22
22
|
|
|
23
|
-
- **
|
|
24
|
-
- **
|
|
25
|
-
-
|
|
23
|
+
- **Explicit cloud/remote/shareable request:** use EAS Simulator after checking access, on any host.
|
|
24
|
+
- **Generic simulator request:** use a suitable local simulator when available. If the host cannot run the requested simulator (for example, iOS on Linux or a cloud sandbox), use EAS Simulator after checking access. A non-macOS host may still support a local Android emulator.
|
|
25
|
+
- Honor an explicit local choice; hand off to `expo run:ios` / Xcode / Android Studio as appropriate. Clarify only when the requested environment remains ambiguous and affects the task.
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
echo "no local sim — proceed with EAS Simulator"
|
|
31
|
-
else
|
|
32
|
-
echo "local sim available — ask the user (cloud or local?)"
|
|
33
|
-
fi
|
|
34
|
-
```
|
|
27
|
+
When the user requests EAS Simulator or a cloud simulator, proceed within that request and
|
|
28
|
+
any stated budget. Explain applicable usage once and carry existing authorization through
|
|
29
|
+
the session. Ask before exceeding a stated budget or expanding beyond the requested work.
|
|
35
30
|
|
|
36
31
|
## Prerequisites
|
|
37
32
|
|
|
38
33
|
- **Run every `eas` command via `npx --yes eas-cli@latest …`** — guarantees a CLI new enough to have `simulator:*` (a global `eas` is often too old), and `--yes` skips npx's prompt. (Bare `eas` is fine if `eas --version` is current.)
|
|
39
34
|
- **Authenticated.** Interactive machine → `npx --yes eas-cli@latest login`. **Cloud sandbox / CI / headless agent has no browser login — set `EXPO_TOKEN`** (expo.dev → Account → Access Tokens) in the env instead. Verify either way with `npx --yes eas-cli@latest whoami`.
|
|
40
35
|
- Run from an Expo **project directory.** A fresh app needs one-time setup: `npx --yes eas-cli@latest init` to create/link the project (when there's no `projectId`), and **set `ios.bundleIdentifier`** in app config if it's missing — a fresh `create-expo-app` often has none, and `prebuild`/`eas build` need it (they prompt or fail without it; e.g. `dev.<owner>.<slug>`). Read current config with `npx expo config --json` (it may live in `app.config.js`). The first Mode-C run is slow (native build); later runs reuse it.
|
|
41
|
-
- A controller to drive the device. This skill uses **agent-device** (open source, MIT), run on demand via `npx agent-device@latest` — nothing globally installed. **argent**
|
|
36
|
+
- A controller to drive the device. This skill uses **agent-device** (open source, MIT), run on demand via `npx agent-device@latest` — nothing globally installed. **Appium** and **argent** are alternative automation interfaces; `web-preview-only` has no automation interface. See [references/controllers.md](./references/controllers.md).
|
|
42
37
|
- **`.env.eas-simulator`** is written/managed by eas-cli (not this skill): it holds the session id (`EAS_SIMULATOR_SESSION_ID`) + the daemon URL/**token**, so `get`/`stop`/`exec` default to that session (usually **omit `--id`**; pass `--id <id>` to target another). It carries a **token → keep it gitignored** (eas-cli marks it "do not commit" but may not add the ignore rule, and a fresh app's `.gitignore` won't cover it — add `.env.eas-simulator` if missing).
|
|
43
|
-
- `--max-duration-minutes` is paid-plan only; otherwise a default applies.
|
|
44
38
|
- **The command blocks assume a POSIX shell** (bash/zsh) — `printf`, `lsof`, `$(seq …)` loops won't run in cmd/PowerShell. On Windows, run them in WSL or Git Bash, or translate as you go (the `eas-cli`/`agent-device` invocations themselves are cross-platform).
|
|
45
39
|
|
|
40
|
+
## Session lifetime
|
|
41
|
+
|
|
42
|
+
- `--max-duration-minutes N` is the hard automatic-stop deadline. Customize it when supported by the account; otherwise use the service's default session limit.
|
|
43
|
+
- `--max-idle-time-minutes N` stops a session after that many inactive minutes. Omitted means **no idle timeout**: the session runs until its maximum duration or an explicit stop.
|
|
44
|
+
- **Only activity reported through `agent-device` and `argent` resets the idle timer.** Appium commands and browser-preview activity do not reset it. For Appium or a user-driven browser preview, rely on the maximum duration—not idle time—to bound the session; customize it with `--max-duration-minutes` when supported by the account.
|
|
45
|
+
|
|
46
46
|
## Check availability first
|
|
47
47
|
|
|
48
|
-
EAS Simulator is a **limited-access** EAS feature that is still rolling out, so it isn't enabled on every account.
|
|
48
|
+
EAS Simulator is a **limited-access** EAS feature that is still rolling out, so it isn't enabled on every account. Check access **before** starting a session; this read-only command does not create a session.
|
|
49
49
|
|
|
50
50
|
```bash
|
|
51
51
|
npx --yes eas-cli@latest simulator:availability --json
|
|
@@ -65,7 +65,11 @@ A session is: **start → (install your app) → drive → stop.** `eas-cli` own
|
|
|
65
65
|
|
|
66
66
|
```bash
|
|
67
67
|
# 1. Start a session (boots the remote sim + agent-device daemon; writes .env.eas-simulator).
|
|
68
|
-
|
|
68
|
+
# If the dotenv names a session, inspect it with simulator:get --json first. Reuse it when it
|
|
69
|
+
# belongs to this run; stop it only when it is in scope and no longer needed. An IN_PROGRESS
|
|
70
|
+
# session may be intentionally concurrent, so preserve its id/config before resetting the dotenv.
|
|
71
|
+
# Continue below only after choosing how to handle that existing session.
|
|
72
|
+
printf '# managed by eas-cli\n' > .env.eas-simulator # clear only after resolving any live session
|
|
69
73
|
npx --yes eas-cli@latest simulator:start --platform ios --type agent-device --non-interactive \
|
|
70
74
|
--name "Checkout flow screenshots" # always name it — see 'Always name the session'
|
|
71
75
|
# Then confirm it's live: simulator:get --json → status IN_PROGRESS (bounded poll in run-your-app.md).
|
|
@@ -77,16 +81,16 @@ npx --yes eas-cli@latest simulator:exec npx agent-device@latest snapshot -i
|
|
|
77
81
|
npx --yes eas-cli@latest simulator:exec npx agent-device@latest press @e2 # tap a ref (NOTE: 'press', not 'tap')
|
|
78
82
|
npx --yes eas-cli@latest simulator:exec npx agent-device@latest screenshot ./shot.png
|
|
79
83
|
|
|
80
|
-
# 3. Stop
|
|
84
|
+
# 3. Stop the session and reset the dotenv. Omit --id to target the dotenv session.
|
|
81
85
|
npx --yes eas-cli@latest simulator:stop
|
|
82
86
|
printf '# managed by eas-cli\n' > .env.eas-simulator
|
|
83
87
|
```
|
|
84
88
|
|
|
85
|
-
To **watch** it live, hand the user the `webPreviewUrl` that `start` prints
|
|
89
|
+
To **watch** it live, hand the user the `webPreviewUrl` that `start` prints. All current session types include a browser preview; `agent-device`, `appium`, and `argent` also provide automation, while `web-preview-only` provides no automation interface. **This URL is for the *user's* browser — you cannot open it for them, and it must never touch the sim:**
|
|
86
90
|
- **"Open it here" (Cursor/VS Code)** → print the URL on its own line and tell the user to open Simple Browser (`Cmd/Ctrl+Shift+P` → "Simple Browser: Show") and paste it. Then **stop**: do not shell out to a system browser or a Cursor/VS Code URL handler, and do not ask "did a tab appear?" — you can't confirm it, the handoff is done.
|
|
87
91
|
- **Never `open` the `webPreviewUrl` on the sim.** It's a browser preview, not a deep link and not an `agent-device open` argument; routing it to the device renders a browser-in-a-browser (a real past failure).
|
|
88
92
|
- **Headless agent** (no display) → just return the URL as the deliverable.
|
|
89
|
-
- **Keeping it alive for the user to drive** →
|
|
93
|
+
- **Keeping it alive for the user to drive** → use `--max-duration-minutes N` when supported, otherwise use the service's default limit. Browser-preview activity does not reset `--max-idle-time-minutes`, so idle timeout is not a reliable lifetime bound for this case. Tell the user when the session expires, using the CLI's reported duration or expiry. Keep it running for the requested preview; stop sessions created for one-shot tasks when the task finishes.
|
|
90
94
|
|
|
91
95
|
`start` also prints a job-run URL.
|
|
92
96
|
|
|
@@ -115,13 +119,27 @@ Rules:
|
|
|
115
119
|
|
|
116
120
|
## Commands at a glance
|
|
117
121
|
|
|
122
|
+
Query the installed CLI for the complete current flag set before using non-default start
|
|
123
|
+
flags, machine-readable/config output, list filters, or session events:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
# Replace `start` with the simulator subcommand you are about to run.
|
|
127
|
+
npx --yes eas-cli@latest simulator:start --help
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
The examples below cover the common workflow; they are intentionally not an exhaustive
|
|
131
|
+
copy of the CLI surface. Keep non-obvious behavioral guidance from this skill—especially
|
|
132
|
+
[Session lifetime](#session-lifetime)—even when constructing the command from `--help`.
|
|
133
|
+
|
|
118
134
|
| Command | Purpose |
|
|
119
135
|
|---|---|
|
|
120
|
-
| `npx --yes eas-cli@latest simulator:
|
|
136
|
+
| `npx --yes eas-cli@latest simulator:availability [--json] [--non-interactive]` | Check access without creating a session. |
|
|
137
|
+
| `npx --yes eas-cli@latest simulator:start --platform ios\|android --name "<description>" [flags]` | Create a session; boot the sim + selected interface; write `.env.eas-simulator` by default; print the preview + job-run URLs. **Always pass `--name`**. `--json` does not suppress the dotenv; use `--out-config-type env` when no file should be written. |
|
|
121
138
|
| `npx --yes eas-cli@latest simulator:exec <cmd> [args…]` | Load `.env.eas-simulator`, then run `<cmd>` with that env. The bridge to the controller. |
|
|
122
|
-
| `npx --yes eas-cli@latest simulator:get [--id] [--json]` | Session status + connection details, including the session
|
|
123
|
-
| `npx --yes eas-cli@latest simulator:list [--
|
|
124
|
-
| `npx --yes eas-cli@latest simulator:
|
|
139
|
+
| `npx --yes eas-cli@latest simulator:get [--id <id>] [--json] [--non-interactive]` | Session status + connection details, including the session name. **Use this to confirm readiness** (see *Operating principles*). |
|
|
140
|
+
| `npx --yes eas-cli@latest simulator:list [filters] [--limit N] [--after <cursor>] [--json]` | List and paginate project sessions; filter by status, type, platform, name prefix, and tags. |
|
|
141
|
+
| `npx --yes eas-cli@latest simulator:events [--id <id>] [--follow\|--json]` | Show recorded activity events; `--follow` watches until the session ends. |
|
|
142
|
+
| `npx --yes eas-cli@latest simulator:stop [--id <id>] [--json] [--non-interactive]` | Stop a session (idempotent). |
|
|
125
143
|
|
|
126
144
|
## Running the user's app — pick a mode
|
|
127
145
|
|
|
@@ -144,8 +162,12 @@ Quick decision — **default to C; A and B are explicit-only:**
|
|
|
144
162
|
- **A:** only an explicit one-shot **static** screenshot on a Mac.
|
|
145
163
|
- **B:** only when the user names an existing/EAS build or wants a static EAS artifact (CI/sharing) — see the box above for why a static build is the wrong tool for "iterate."
|
|
146
164
|
|
|
165
|
+
Before starting a Mode C tunnel or connecting the dev client, read [Tunnel scope and approvals](./references/run-your-app.md#tunnel-scope-and-approvals). Carry existing authorization for this project's remote development transport through tunnel creation, connection, and live edits; include its source and the concrete data flow in any approval request.
|
|
166
|
+
|
|
147
167
|
## Driving the device (agent-device)
|
|
148
168
|
|
|
169
|
+
If a controller fails to download a recording, retrieve it from [EAS session artifacts](./references/controllers.md#recording-download-recovery).
|
|
170
|
+
|
|
149
171
|
`agent-device` is the controller. Common verbs (run each as `npx --yes eas-cli@latest simulator:exec npx agent-device@latest <verb>`):
|
|
150
172
|
|
|
151
173
|
| Verb | Does |
|
|
@@ -178,12 +200,12 @@ The non-obvious mental model worth internalizing. Specific error→fix lookups (
|
|
|
178
200
|
If current code isn't rendering after your **first** connect, stop poking live state: **reset to baseline** (stop session → clear dotenv → kill your Metro) and redo the mode **once**; a second failure → stop and report. Never restart Metro in place, reconnect more than once, rebuild the native client to fix a JS/connection problem, or surface a preview URL while state is unknown. (A daemon drop — `ERR_NGROK_3200` / `Remote daemon is unavailable` — is the same: reset, don't retry.)
|
|
179
201
|
2. **`exec` is a wrapper, not a driver.** `simulator:exec` loads `.env.eas-simulator` and spawns the command you pass; the device verbs come from the controller (`npx agent-device@latest`). There is no `simulator:tap`.
|
|
180
202
|
3. **Act immediately; don't park an idle session.** Sessions are short-lived — install and drive right after `start`. Leaving one idle drops the tunnel/daemon (→ reset, per #1).
|
|
181
|
-
4. **Stop on
|
|
203
|
+
4. **Stop sessions you created on completion or failure and reset the dotenv.** `--non-interactive` does not stop a session when your task ends. For a requested live preview, follow the duration guidance above. Poll the existing session during a slow boot; starting another creates an extra session and overwrites the dotenv's session id.
|
|
182
204
|
5. **Screenshot only the correct, fresh build.** Mode C only after the dev client connects to Metro; A/B only from a build matching current source — reusing a pre-existing build is the #1 "my edits don't show" cause (see the build caveat above). (`9:41` in the status bar is the sim default, not staleness.)
|
|
183
205
|
|
|
184
206
|
## Stop and clean up
|
|
185
207
|
|
|
186
|
-
|
|
208
|
+
After the task, stop the session you created **and reset the dotenv** so a later run doesn't try to reuse the dead session. For a requested live preview, keep it available for the agreed duration instead:
|
|
187
209
|
|
|
188
210
|
```bash
|
|
189
211
|
npx --yes eas-cli@latest simulator:stop # omit --id → stops the dotenv session (or pass --id <id>)
|
|
@@ -1,10 +1,25 @@
|
|
|
1
|
-
# Controllers: agent-device and argent
|
|
1
|
+
# Controllers: agent-device, Appium, and argent
|
|
2
2
|
|
|
3
|
-
`eas-cli` has no device verbs — it manages the *session*.
|
|
3
|
+
`eas-cli` has no device verbs — it manages the *session*. Automation commands come from the interface selected by `simulator:start --type`:
|
|
4
4
|
|
|
5
5
|
- `agent-device` (Callstack, MIT) — used throughout this skill; runs on demand via `npx agent-device@latest`, nothing installed globally.
|
|
6
|
+
- `appium` — exposes `APPIUM_URL` and `APPIUM_CAPS` for an Appium client.
|
|
6
7
|
- `argent` (Software Mansion) — a capable alternative controller; check its license for your use.
|
|
7
|
-
- `
|
|
8
|
+
- `web-preview-only` — browser preview with no programmatic control.
|
|
9
|
+
|
|
10
|
+
All four types include a web preview. Before setting `--max-idle-time-minutes`, follow [Session lifetime](../SKILL.md#session-lifetime); activity does not reset the timer for every interface.
|
|
11
|
+
|
|
12
|
+
## Appium
|
|
13
|
+
|
|
14
|
+
Start with `--type appium`, then run the user's Appium client through `simulator:exec`; the wrapper loads `APPIUM_URL` and JSON-encoded `APPIUM_CAPS` from `.env.eas-simulator`:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npx --yes eas-cli@latest simulator:start --platform ios --type appium --non-interactive \
|
|
18
|
+
--name "Appium checkout run"
|
|
19
|
+
npx --yes eas-cli@latest simulator:exec <appium-client> [args...]
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Use the maximum duration as the lifetime bound; Appium commands do not reset the idle timer.
|
|
8
23
|
|
|
9
24
|
## agent-device verbs (run via `npx --yes eas-cli@latest simulator:exec npx agent-device@latest <verb>`)
|
|
10
25
|
|
|
@@ -24,6 +39,20 @@ EAS-specific notes:
|
|
|
24
39
|
- **`install` uploads** a local binary to the daemon; **`install-from-source`** has the VM download from a URL (use for EAS artifacts — avoids a large upload).
|
|
25
40
|
- **Exercised against a live session:** `apps`, `install`, `install-from-source`, `open`, `snapshot -i`, `press`, `fill`, `screenshot`, `scroll`, `gesture` (needs a preset, e.g. `gesture swipe left`), `logs`, `record` (`start`/`stop <path>`), `network`, `perf`. `metro` (`prepare`/`reload`) is the Mode C dev-client bridge. Pass `--platform ios`; run `<verb>` with no args to see its required subcommand/args.
|
|
26
41
|
|
|
42
|
+
## Recording download recovery
|
|
43
|
+
|
|
44
|
+
If downloading a recording through agent-device or argent fails, fetch the recording from **EAS session artifacts**. A controller download failure does not mean the recording was lost. Keep the original EAS session id and query its artifacts:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npx --yes eas-cli@latest simulator:get --id <session-id> --json
|
|
48
|
+
# Select the recording in artifacts[] by filename/name and metadata; use its downloadUrl:
|
|
49
|
+
curl --fail --location --max-time 600 --output ./capture.mp4 '<downloadUrl>'
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Use the URL returned by EAS, not a path on the simulator or a controller artifact id. If the recording has not appeared yet, poll the same session with a bounded wait for upload completion. Already-uploaded artifacts can be retrieved after the session stops using its explicit id. If a download URL expires, query the session again for a fresh one. Give the download command more than 10 minutes in the outer runner, increase `--max-time` for larger files, and verify the downloaded video before reporting success.
|
|
53
|
+
|
|
54
|
+
Source: EAS CLI [simulator:get](https://github.com/expo/eas-cli/blob/main/packages/eas-cli/src/commands/simulator/get.ts) exposes `artifacts[].{id,name,filename,metadata,downloadUrl}`.
|
|
55
|
+
|
|
27
56
|
## argent (alternative)
|
|
28
57
|
|
|
29
58
|
`npx --yes eas-cli@latest simulator:start --type argent` provisions an argent remote session. The connection config it returns is different (`ARGENT_TOOLS_URL` / `ARGENT_AUTH_TOKEN`).
|
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
# Running your app on the remote sim — tested sequences
|
|
2
2
|
|
|
3
|
-
The remote sim boots blank. You install a **simulator-targeted** build onto the session, then open it. Pick a mode from `SKILL.md`. (Sequences validated against eas-cli 20.3.x + agent-device 0.17.x in mid-2026
|
|
3
|
+
The remote sim boots blank. You install a **simulator-targeted** build onto the session, then open it. Pick a mode from `SKILL.md`. (Sequences validated against eas-cli 20.3.x + agent-device 0.17.x in mid-2026. These commands are experimental — check the relevant subcommand's `--help` before using non-default flags.)
|
|
4
4
|
|
|
5
5
|
In all modes, the session is started the same way and driven through `npx --yes eas-cli@latest simulator:exec`. Replace `dev.example.app` with the app's iOS `bundleIdentifier` (from `app.json` → `ios.bundleIdentifier`), and run from the project directory.
|
|
6
6
|
|
|
7
|
-
> These sequences are **iOS**. For **Android**: build via `npx --yes eas-cli@latest build --platform android` (or local Gradle), `install` the `.apk` instead of an `.app`, skip `pod install
|
|
7
|
+
> These sequences are **iOS**. For **Android**: build via `npx --yes eas-cli@latest build --platform android` (or local Gradle), `install` the `.apk` instead of an `.app`, and skip `pod install`. Current simulator session types include a web preview, though Android support is still in development and may lack iOS parity.
|
|
8
8
|
|
|
9
9
|
## Starting a session (shared by all modes)
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
#
|
|
12
|
+
# If the dotenv names a session, inspect it first with simulator:get --json. Reuse it when it belongs
|
|
13
|
+
# to this run; stop it only when it is in scope and no longer needed. An IN_PROGRESS session may be
|
|
14
|
+
# intentionally concurrent, so preserve its id/config before resetting the dotenv. Replacing the file
|
|
15
|
+
# does not stop the remote session. Reset only after choosing how to handle the existing session.
|
|
13
16
|
printf '# managed by eas-cli\n' > .env.eas-simulator
|
|
14
17
|
|
|
15
|
-
# Start (
|
|
18
|
+
# Start (the default --out-config-type dotenv writes .env.eas-simulator). It boots the sim + agent-device daemon.
|
|
19
|
+
# --json changes stdout but does not suppress the completed dotenv write; use --out-config-type env for no file.
|
|
16
20
|
# --name is required practice: it labels the session in simulator:list/get and on expo.dev.
|
|
17
21
|
# Describe what the run is for, in the user's terms — see "Always name the session" in SKILL.md.
|
|
18
22
|
npx --yes eas-cli@latest simulator:start --platform ios --type agent-device --non-interactive \
|
|
@@ -217,6 +221,32 @@ Method 1 passes each as two flags: `--launch-arg "<key>" --launch-arg "<value>"`
|
|
|
217
221
|
|
|
218
222
|
### Metro tunnel backends (both methods)
|
|
219
223
|
|
|
224
|
+
#### Tunnel scope and approvals
|
|
225
|
+
|
|
226
|
+
Mode C needs a route from the EAS VM to your local Metro server. The account-signed Expo tunnel is the normal transport for this workflow: it forwards requests to `http://localhost:<your-free-port>` so the remote app can fetch its development manifest, JavaScript bundle, and assets and receive live updates. Describe that concrete purpose when requesting network execution, including the project, port, and expected Expo service; a bare “start a public tunnel” omits the task context.
|
|
227
|
+
|
|
228
|
+
**Carry authorization through the whole development loop.** When the user's existing authorization covers this project's EAS Simulator live development and required networking, treat starting its temporary Metro tunnel, connecting its dev client (including the launcher **Connect** button), and fetching subsequent bundles through Fast Refresh as steps of that authorized workflow. Do not ask the user to repeat consent for each step or later in-scope UI edit. A newly generated hostname on the same verified tunnel provider does not by itself expand the authorized scope; a different project, provider, exposed service, or user restriction requires reassessing it.
|
|
229
|
+
|
|
230
|
+
This skill supplies technical context, not permission, and cannot override the host's approval policy. Identify the actual authorization: quote the relevant user message or user-provided project instruction and name its source, subject to the host's trust rules. Do not present this skill's own workflow instructions as user consent. A signed tunnel URL authenticates tunnel creation to an Expo account; it is **not proof that requests to the public Metro URL require authentication**. URL randomness limits discoverability, not access. Keep the URL within the intended session and stop your Metro process when finished.
|
|
231
|
+
|
|
232
|
+
Put the authorization and transport details in the approval request itself so the reviewer can evaluate them together. Adapt this example only to facts verified for the current run:
|
|
233
|
+
|
|
234
|
+
> Continue the authorized EAS Simulator live-development workflow for `<project>`.
|
|
235
|
+
> Existing authorization: `<quote the relevant instruction>` from `<user message or project instruction source>`.
|
|
236
|
+
> Start this project's Metro server on `localhost:<port>` through `<verified tunnel provider>`
|
|
237
|
+
> so the project's dev client on EAS Simulator can fetch its development manifest,
|
|
238
|
+
> JavaScript bundle, and assets and receive Fast Refresh updates. The Metro endpoint
|
|
239
|
+
> is publicly reachable by URL while the tunnel runs. Keep the URL within the intended
|
|
240
|
+
> session and stop this Metro process when the requested development session ends.
|
|
241
|
+
|
|
242
|
+
For a dev-client connection request, reference the same authorization and the verified Metro URL from this run. Explain that **Connect** performs the bundle fetch for the already authorized workflow.
|
|
243
|
+
|
|
244
|
+
If approval review rejects the tunnel or connection, explain the exact action and stated reason. If the host permits reconsideration and the rejection missed relevant evidence, submit a reconsideration with the concrete transport details and original authorization source. Do not blindly repeat a denied command or switch tools or providers to evade the rejection. If reconsideration is unavailable or still denied, report the remaining block and ask for approval of that specific exposure as the host requires. Keep a live-edit request on Mode C while resolving the block. Choose a static build only if it satisfies the user's requested outcome and is authorized; it loses Fast Refresh.
|
|
245
|
+
|
|
246
|
+
Source: Expo CLI's [AsyncWsTunnel.ts](https://github.com/expo/expo/blob/main/packages/%40expo/cli/src/start/server/AsyncWsTunnel.ts) resolves the Expo account, requests a signed URL, and sets the local target port. Verify the installed CLI's actual backend below: the environment flag alone does not prove it selected Expo's service.
|
|
247
|
+
|
|
248
|
+
#### Backend selection
|
|
249
|
+
|
|
220
250
|
Start Metro on your OWN free port — each run gets its own tunnel URL, so never fight for or kill :8081 (#133's rule). BOTH backends accept ANY `--port`:
|
|
221
251
|
- **ws-tunnel v2 (account-signed):** `EXPO_UNSTABLE_TUNNEL_V2=1` — signed URL for your EAS account, `on.expo.app` host, and the path for robot/EXPO_TOKEN/cloud agents (plain ngrok is blocked for them). Needs login / an EAS-linked project; if the signed URL fails, the CLI says to unset the flag and use ngrok.
|
|
222
252
|
- **ngrok (plain `--tunnel`, no flag):** `<host>.exp.direct` host; blocked for robot/EXPO_TOKEN users.
|
|
@@ -4,16 +4,19 @@ Concrete errors seen while validating this flow, and the fix.
|
|
|
4
4
|
|
|
5
5
|
| Symptom | Cause | Fix |
|
|
6
6
|
|---|---|---|
|
|
7
|
+
| Approval review rejects the Mode C Metro tunnel or dev-client Connect action | Review may lack or misinterpret the transport details or existing authorization; a signed URL alone does not establish private access | Follow [Tunnel scope and approvals](./run-your-app.md#tunnel-scope-and-approvals). Include the original authorization source and verified transport in the request; use reconsideration only where the host permits it. Preserve the requested live workflow while resolving approval. |
|
|
8
|
+
| Controller recording download fails or times out | The local transfer can fail even though EAS retains the recording | Fetch it from [EAS session artifacts](./controllers.md#recording-download-recovery) using the original EAS session id and the recording’s `downloadUrl`. |
|
|
7
9
|
| `Command simulator:start not found` | `eas-cli` too old (commands are hidden but present from ≥ 20.3.0) | Run via `npx --yes eas-cli@latest …`, or upgrade `eas-cli`. |
|
|
8
10
|
| `simulator:start` rejects `--name` (e.g. `Nonexistent flag: --name`) | `eas-cli` too old — `--name` was added after `simulator:start` itself | Run via `npx --yes eas-cli@latest …`, or upgrade `eas-cli`. If you can't upgrade, retry once **without** `--name`; the session starts unnamed. |
|
|
9
11
|
| `An Expo user account is required` / `whoami` shows logged-out | No browser login on a cloud/CI/headless box, or `EXPO_TOKEN` unset/invalid | Set **`EXPO_TOKEN`** (expo.dev → Account → Access Tokens) in the env; verify `npx --yes eas-cli@latest whoami`. (Interactive machines can `eas login`.) |
|
|
10
12
|
| `simulator:start`/`build`: no linked project / missing `projectId` | A fresh `create-expo-app` isn't linked to EAS | `npx --yes eas-cli@latest init` to create/link it (writes `extra.eas.projectId`). |
|
|
11
13
|
| `prebuild`/`eas build` prompts for or fails on a missing **iOS bundle identifier** | A fresh app often has no `ios.bundleIdentifier` | Set it in app config (e.g. `dev.<owner>.<slug>`); confirm via `npx expo config --json` (may live in `app.config.js`). |
|
|
12
|
-
| `--max-duration-minutes` rejected | The
|
|
14
|
+
| `--max-duration-minutes` rejected | The requested duration may not be supported by the account; inspect the CLI error | Use the default session limit when the custom duration is unavailable. |
|
|
15
|
+
| Appium or browser-preview session stops despite ongoing interaction | Only activity reported through `agent-device` and `argent` resets `--max-idle-time-minutes`; Appium commands and browser-preview activity do not | Use the maximum duration as the lifetime bound for Appium and user-driven previews. Customize it with `--max-duration-minutes` when supported by the account, and omit `--max-idle-time-minutes` unless inactivity from a supported controller is the intended stop condition. |
|
|
13
16
|
| `simulator:start` fails with `not enabled for this account` / not-allowlisted | EAS Simulator is limited-access and isn't enabled for this account | Don't retry. Confirm with `simulator:availability`, then hand off gracefully — tell the user and fall back to a local sim / EAS Build (see SKILL.md *Check availability first*). |
|
|
14
17
|
| `start` keeps "Waiting for … session to be ready" but it never returns | `start`'s readiness poll can miss a session that's actually live | Don't rely on it — poll `npx --yes eas-cli@latest simulator:get --id <id> --json` for `status: IN_PROGRESS` + a populated `remoteConfig`. |
|
|
15
18
|
| `ERR_NGROK_3200` / endpoint offline; `Remote daemon is unavailable` | The session's tunnel/daemon dropped — left idle and timed out, or the VM was torn down | A drop invalidates the **whole** session (installed app, `@e` refs, Metro). **Don't retry the failed verb** — start a fresh session, reset the dotenv, and re-run install→open→drive from the top, acting immediately. |
|
|
16
|
-
| Two sessions running / orphaned session
|
|
19
|
+
| Two sessions running / orphaned session | A second `start` (e.g. to "retry" a slow boot) creates another session and overwrites the dotenv id, orphaning the first | Poll the existing session instead. Find orphans with `simulator:list --status in-progress` and stop those you created with `simulator:stop --id <id>`. |
|
|
17
20
|
| A device verb hangs (no return for a minute+) | Slow daemon; `press`/`screenshot` can block ~90s | Bound it with agent-device's own `--timeout <ms>` (e.g. `--timeout 120000`) — **not** a shell `timeout` wrapper (macOS has no `timeout` binary, so `timeout 120 …` fails with `command not found` and skips the verb). On timeout `snapshot -i` to see if the action landed before retrying (taps can double-fire). Don't blind-retry. |
|
|
18
21
|
| `install requires an active session or an explicit device selector` | `install` can't infer the device | Pass `--platform ios` (or `open` something first to establish a session). |
|
|
19
22
|
| `DEVICE_NOT_FOUND: No device named <udid>` when targeting a non-default device (iPad, second sim) | In a remote session agent-device's `--device` resolves by **name**, not udid (despite the CLI docs) | Pass the device **name** from `agent-device devices` (e.g. `--device "iPad Pro 13-inch (M5)"`), not the udid. |
|
|
@@ -21,8 +24,8 @@ Concrete errors seen while validating this flow, and the fix.
|
|
|
21
24
|
| `SESSION_NOT_FOUND: No active session. Run open first.` | A verb (e.g. `screenshot`) ran before any app/session was opened — **or** you used Method 1 (`simulator:start --open-url`), which launches the app but creates NO agent-device session | `open <app\|url>` first (or pass `--platform ios`). After a Method-1 launch, attach without relaunching: `agent-device open <bundleId> --foreground --platform ios` (pass the bundle id — `--foreground` alone fails `AMBIGUOUS_MATCH`), then screenshot. |
|
|
22
25
|
| Screenshot looks plausible but the session/UI is wrong (e.g. Safari, an iPhone shot when you booted an iPad, or "incompatible Expo Go SDK") | agent-device **silently falls back to a LOCAL simulator** when `.env.eas-simulator` has no remote config — no error, believable-but-wrong output. Common cause: a **concurrent `simulator:start`** on the same account/machine overwrote the shared dotenv with its own id (the dotenv is a single file, NOT concurrency-safe). | Confirm you're on the REMOTE VM: `simulator:get --json` returns the id `start` printed, AND the verb's "Session state:" path is under **`/Users/expo/`** (remote), not `/Users/<you>/` (local); `devices --json` host is a `turtle-worker-*`. The `sessions/` vs `remote-diagnostics/` directory name is NOT a reliable tell. If concurrency is possible, drive by explicit id — load the daemon vars from `simulator:get --id <id> --json` — instead of trusting the dotenv. |
|
|
23
26
|
| `simulator:exec` / `build` / `simulator:stop`: "Run this command inside a project directory." | Run from the wrong cwd | Run from the Expo project directory (where `app.json`/`eas.json` live). |
|
|
24
|
-
| New session's id shows as the *previous* one; "Overwriting previous simulator session (id: …)" |
|
|
25
|
-
| No `.env.eas-simulator` written after `start` | `--
|
|
27
|
+
| New session's id shows as the *previous* one; "Overwriting previous simulator session (id: …)" | `.env.eas-simulator` names an earlier session | Inspect it with `simulator:get --json`. Reuse it when it belongs to this run; stop it only when it is in scope and no longer needed. An `IN_PROGRESS` session may be intentionally concurrent, so preserve its id/config before resetting the dotenv and drive sessions by explicit id/config. Replacing the file does not stop the remote session. |
|
|
28
|
+
| No `.env.eas-simulator` written after `start` | `--out-config-type env` was selected, or the CLI reported a file-write failure | Use the default `--out-config-type dotenv` for the `exec` flow. `--json` changes output and implies non-interactive mode, but does not by itself suppress the completed dotenv write. |
|
|
26
29
|
| `pod install` fails: `Unicode Normalization not appropriate for ASCII-8BIT` | Ruby 4 + CocoaPods with a non-UTF-8 locale | Re-run with `LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 pod install`. |
|
|
27
30
|
| (Mode C) Deep-link `open` lands on the dev-client launcher, not the app | The "Open in '<app>'?" system dialog wasn't accepted, so the deep link didn't take | Accept the dialog with `agent-device alert accept 2500 --platform ios` (not a UI tap). If it still lands on the launcher, fall back to "Enter URL manually" → `fill` the `https://<host>.on.expo.app` manifest URL → "Connect" (see run-your-app.md Mode C). |
|
|
28
31
|
| (Mode C) App shows expo-router "Unmatched Route" | The connect URL was parsed as a route path | `press 'label="Go back"'` (or navigate to `/`). |
|
|
@@ -34,6 +37,7 @@ Concrete errors seen while validating this flow, and the fix.
|
|
|
34
37
|
| `CommandError: WS-tunnel only supports tunneling over port 8081` | You're on the **legacy** ws-tunnel path — no v2 account URL (older CLI where `EXPO_UNSTABLE_TUNNEL_V2` is a no-op, not logged in, or `EXPO_FORCE_WEBCONTAINER_ENV` set) | Get onto the account-signed v2 path: set `EXPO_UNSTABLE_TUNNEL_V2=1` and log in / link the project — then any `--port` works. Otherwise use `--port 8081`, or the ngrok path (drop the flag; non-robot only). |
|
|
35
38
|
| Unexpected charges / a session you forgot | `start --non-interactive` does NOT auto-stop | Always `npx --yes eas-cli@latest simulator:stop --id <id>`. List leftovers with `npx --yes eas-cli@latest simulator:list`. |
|
|
36
39
|
| Screenshot shows **old content** / my recent edits don't appear | Running a **release build (Mode A/B)** whose JS was baked in *before* your edits — typically a reused/stale build | A/B reflect code at build time, not now. **Rebuild** (ensure the build's fingerprint matches current source), or use **Mode C** (dev + Metro) so live edits show via Fast Refresh. The screenshot itself is fresh — it's the build that's stale. (`9:41` in the status bar is the sim default, not staleness.) |
|
|
40
|
+
| (Android) The emulator stopped, and `agent-device boot` times out (`Daemon request timed out`) while the device stays `booted=false` | Without `--headless`, agent-device starts the emulator with a window. The EAS Linux image cannot run the windowed emulator, so it exits at once | Boot headless. Set `AGENT_DEVICE_HEADLESS=1` for the whole run, or pass `--headless` on each `boot`: `AGENT_DEVICE_HEADLESS=1 npx --yes eas-cli@latest simulator:exec npx agent-device@latest boot --platform android --device <avd-name>`. Get the AVD name from `agent-device devices --platform android`. The variable is read by the local client, so set it where you run the command. |
|
|
37
41
|
| (argent) Every `argent run`/`tools` call returns `401 Unauthorized` right after linking | `argent link` without `--yes` no-ops on an already-linked URL ("Already linked. No changes."), keeping a stale token from a previous session | Re-link with `--yes` so the new token is written — see the link command in [controllers.md](./controllers.md). |
|
|
38
42
|
|
|
39
43
|
## Performance expectations
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: eas-update
|
|
3
|
+
description: "EAS service (paid). Configure and use EAS Update for over-the-air JavaScript and asset updates with expo-updates and EAS CLI. Use when setting up OTA updates, running eas update:configure or eas update, publishing to preview/staging/production channels, explaining branches/channels/runtime versions, testing updates, or debugging why an installed build still shows old code. Load for TestFlight, preview, or production updates that do not appear, including questions about cold launches or reopening the app. Not for update health metrics; use eas-update-insights for adoption, crashes, and rollout monitoring."
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
license: MIT
|
|
6
|
+
allowed-tools: "Bash(npx expo *), Bash(npx *eas-cli@*), Bash(eas *)"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# EAS Update
|
|
10
|
+
|
|
11
|
+
> **EAS service - costs apply.** EAS Update is available on the Free plan; publishing and delivery use update, bandwidth, and storage allowances, with higher limits on paid plans. See https://expo.dev/pricing.
|
|
12
|
+
|
|
13
|
+
Use EAS Update to deliver compatible JavaScript, styling, and asset changes to installed apps without submitting a new native binary. Native-code changes still require a new build.
|
|
14
|
+
|
|
15
|
+
## Start with the supported configuration path
|
|
16
|
+
|
|
17
|
+
Before changing anything, inspect `package.json`, the Expo app config, `eas.json` if present, and whether `ios/` or `android/` are tracked. Use what you find when reviewing the CLI's changes:
|
|
18
|
+
|
|
19
|
+
- Preserve existing dynamic or platform-specific app configuration.
|
|
20
|
+
- If `eas.json` exists, preserve its profiles and existing channel assignments. The CLI adds a channel matching the profile name only to build profiles that do not already have one.
|
|
21
|
+
- If `eas.json` is absent, do not create it by hand. The CLI may direct the user to run `eas build:configure` separately.
|
|
22
|
+
- With tracked native projects, expect the CLI to synchronize the platform's native Update configuration. Without them, expect Continuous Native Generation to apply the native configuration during a later build.
|
|
23
|
+
|
|
24
|
+
Detect the Expo SDK version before installing packages or interpreting version-specific behavior.
|
|
25
|
+
|
|
26
|
+
If `expo-updates` is not installed, install the SDK-compatible version:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npx expo install expo-updates
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Configure from the project root:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npx eas-cli@latest update:configure
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Use `eas update:configure` rather than manually inventing `updates.url`, `runtimeVersion`, native metadata, or build-profile channels. The command understands EAS project linking, Continuous Native Generation, and projects with committed native directories. Review and explain its resulting diff.
|
|
39
|
+
|
|
40
|
+
If the command cannot proceed because the project is not linked or the user has not authorized the required remote operation, stop after any independently valid package installation and explain what remains. Do not partially reproduce `update:configure` by adding a runtime-version policy, config plugin, update URL, or channels by hand.
|
|
41
|
+
|
|
42
|
+
For dynamic app config, non-EAS builds, or a command that cannot complete automatically, follow the current setup documentation instead of guessing: https://docs.expo.dev/eas-update/getting-started.md.
|
|
43
|
+
|
|
44
|
+
## Keep the model straight
|
|
45
|
+
|
|
46
|
+
- **Build:** the installed native app. It contains native code, an embedded update, a platform, a runtime version, and normally a channel fixed at build time.
|
|
47
|
+
- **Update:** a published JavaScript bundle, assets, and metadata for one platform and runtime version.
|
|
48
|
+
- **Branch:** an ordered stream of updates. Its newest compatible update is active.
|
|
49
|
+
- **Channel:** a stable deployment target embedded in builds. On the server, it points to a branch.
|
|
50
|
+
- **Runtime version:** the compatibility boundary between an update and the native code in a build.
|
|
51
|
+
|
|
52
|
+
A build receives an update only when platform and runtime version match and the build's channel points to the branch containing that update:
|
|
53
|
+
|
|
54
|
+
```text
|
|
55
|
+
installed build (channel: production, runtime: 1.1.1, platform: ios)
|
|
56
|
+
-> production channel
|
|
57
|
+
-> production branch
|
|
58
|
+
-> newest update for runtime 1.1.1 and ios
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Channels and branches commonly have the same name, but they are separate objects. `eas channel:edit` changes a channel's server-side branch mapping for every build on that channel. It does not change an individual installation's embedded channel.
|
|
62
|
+
|
|
63
|
+
Use this model to make decisions, but explain only the concepts needed for the user's request rather than reciting the entire model every time.
|
|
64
|
+
|
|
65
|
+
## Decide whether an update is compatible
|
|
66
|
+
|
|
67
|
+
Use an update for changes to JavaScript, styling, and bundled assets that the installed native runtime already supports.
|
|
68
|
+
|
|
69
|
+
Create a new native build when a change adds or modifies native code or native configuration, including most native-library additions and SDK upgrades. Do not work around a runtime mismatch or imply that publishing can add native capabilities to an existing build. See https://docs.expo.dev/eas-update/runtime-versions.md.
|
|
70
|
+
|
|
71
|
+
Do not change the project's runtime-version policy as an incidental fix. Explain how the current policy affects compatibility; treat changing it as a separate decision because it changes which installed builds can receive future updates.
|
|
72
|
+
|
|
73
|
+
## Publish deliberately
|
|
74
|
+
|
|
75
|
+
Check the current CLI help before relying on remembered flags:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npx eas-cli@latest update --help
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
For the common channel-based flow:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
npx eas-cli@latest update \
|
|
85
|
+
--channel <channel> \
|
|
86
|
+
--message "<message>" \
|
|
87
|
+
--environment <environment>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
SDK 55 and later require an EAS environment for publishing. Choose the environment intentionally so exported code receives the intended variables.
|
|
91
|
+
|
|
92
|
+
Publishing changes remote state and can affect installed applications. Before running it, establish the exact project, channel, environment, platforms, runtime version, and message. Publish to production only when the user has explicitly requested or approved it; if the authorization or target is ambiguous, stop before the command and ask. Do not infer a production destination solely from the current Git branch.
|
|
93
|
+
|
|
94
|
+
Prefer a preview or staging channel for validation. When promoting a tested update, use the documented deployment flow so production receives the same artifact where possible: https://docs.expo.dev/eas-update/deployment.md.
|
|
95
|
+
|
|
96
|
+
## Test according to the build type
|
|
97
|
+
|
|
98
|
+
### Development builds
|
|
99
|
+
|
|
100
|
+
Preview updates with the development build's Extensions UI, the EAS dashboard, or Expo Orbit. A normal `expo-dev-client` development build does not behave like a release build's automatic startup update flow.
|
|
101
|
+
|
|
102
|
+
### Preview, TestFlight, and production builds
|
|
103
|
+
|
|
104
|
+
Release builds normally prioritize startup speed. With the default launch behavior, the app may start its current embedded or cached update while downloading a newly published update in the background. The downloaded update is applied on a later restart.
|
|
105
|
+
|
|
106
|
+
For manual QA, fully terminate the app rather than backgrounding it, reopen it, allow the update time to download, and, if the change is not visible, fully terminate and reopen it once more. Describe this as **up to two cold launches**, not a TestFlight-specific ritual:
|
|
107
|
+
|
|
108
|
+
1. One launch can discover and download the update.
|
|
109
|
+
2. The following launch can run the downloaded update.
|
|
110
|
+
|
|
111
|
+
Do not automatically change `fallbackToCacheTimeout` to avoid the second launch. Waiting at startup trades launch latency and reliability for faster update activation. If the app needs an intentional update UX, consider the `expo-updates` APIs for checking, fetching, and presenting a non-blocking restart action. Use the `expo-updates` API reference for the project's detected SDK version.
|
|
112
|
+
|
|
113
|
+
## Debug a build that did not update
|
|
114
|
+
|
|
115
|
+
Check these in order:
|
|
116
|
+
|
|
117
|
+
1. Confirm the update was published to the intended EAS project, channel or branch, platform, and environment.
|
|
118
|
+
2. Compare the installed build's platform and runtime version with the published update.
|
|
119
|
+
3. Confirm the build actually contains the expected update URL and channel; app-config changes take effect only in a newly compiled build.
|
|
120
|
+
4. Inspect the channel-to-branch mapping and the active update on that branch.
|
|
121
|
+
5. Fully terminate the release build and allow for the normal download-then-apply lifecycle.
|
|
122
|
+
6. Use the current debugging guide for native logs, export problems, and configuration checks: https://docs.expo.dev/eas-update/debug.md.
|
|
123
|
+
|
|
124
|
+
Never bypass a compatibility or anti-bricking safeguard merely to make an update appear.
|
|
125
|
+
|
|
126
|
+
## Advanced and adjacent workflows
|
|
127
|
+
|
|
128
|
+
- **Channel surfing:** an individual release build can override its `expo-channel-name` request header to request another compatible channel. This differs from changing the server-side channel-to-branch mapping. Follow https://docs.expo.dev/eas-update/channel-surfing.md and preserve its access-control, persistence, recovery, and compatibility constraints.
|
|
129
|
+
- **Update health:** load `eas-update-insights` for adoption, launch failures, crash rate, payload size, and rollout monitoring after publishing.
|
|
130
|
+
- **Store releases:** load `eas-app-stores` when native changes require a new TestFlight, App Store, or Play Store build.
|
|
131
|
+
|
|
132
|
+
## Official references
|
|
133
|
+
|
|
134
|
+
- Setup: https://docs.expo.dev/eas-update/getting-started.md
|
|
135
|
+
- Concepts and matching: https://docs.expo.dev/eas-update/how-it-works.md
|
|
136
|
+
- Deployment: https://docs.expo.dev/eas-update/deployment.md
|
|
137
|
+
- Debugging: https://docs.expo.dev/eas-update/debug.md
|
|
138
|
+
- Current EAS CLI reference: https://docs.expo.dev/eas/cli.md
|
|
139
|
+
|
|
140
|
+
## Submitting Feedback
|
|
141
|
+
If you encounter errors, misleading or outdated information in this skill, report it so Expo can improve:
|
|
142
|
+
```bash
|
|
143
|
+
npx --yes submit-expo-feedback@latest --category skills --subject "eas-update" "<actionable feedback>"
|
|
144
|
+
```
|
|
145
|
+
Only submit when you have something specific and actionable to report. Include as much relevant context as possible.
|
|
146
|
+
If an AI agent repeatedly failed or the user had to take over an Expo task, load the expo-skill-feedback skill and follow its eval-candidate flow instead of reusing the command above.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
interface:
|
|
2
|
+
display_name: "EAS Update"
|
|
3
|
+
short_description: "Paid EAS service. Configure, publish, test, and debug over-the-air updates with expo-updates and EAS CLI"
|
|
4
|
+
default_prompt: "Use $eas-update to configure EAS Update, publish a compatible OTA update to the intended channel, test it in development or release builds, and debug channel or runtime-version mismatches."
|