vybekiit 0.7.4 → 0.7.7
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 +10483 -1704
- package/dist/global-skills/aws-cdk/SKILL.md +2 -1
- package/dist/global-skills/aws-cloudformation/SKILL.md +2 -1
- package/dist/global-skills/aws-serverless/SKILL.md +45 -44
- package/dist/global-skills/aws-serverless/assets/powertools-handler.py +2 -1
- package/dist/global-skills/aws-serverless/references/api-gateway.md +50 -470
- package/dist/global-skills/aws-serverless/references/architecture.md +47 -186
- package/dist/global-skills/aws-serverless/references/concurrency.md +44 -158
- package/dist/global-skills/aws-serverless/references/deployment.md +1 -1
- package/dist/global-skills/aws-serverless/references/event-sources.md +72 -391
- package/dist/global-skills/aws-serverless/references/lambda.md +69 -428
- package/dist/global-skills/aws-serverless/references/orchestration.md +65 -384
- package/dist/global-skills/aws-serverless/references/production.md +78 -415
- package/dist/global-skills/aws-serverless/references/troubleshooting.md +92 -619
- package/dist/global-skills/claimable-postgres/SKILL.md +60 -49
- package/dist/global-skills/design-my-data/SKILL.md +2 -0
- package/dist/global-skills/eas-app-stores/SKILL.md +8 -0
- package/dist/global-skills/eas-app-stores/references/play-store.md +2 -0
- package/dist/global-skills/eas-hosting/SKILL.md +8 -0
- package/dist/global-skills/eas-observe/SKILL.md +30 -8
- package/dist/global-skills/eas-observe/agents/openai.yaml +1 -1
- package/dist/global-skills/eas-observe/references/metrics.md +54 -3
- package/dist/global-skills/eas-observe/references/queries.md +78 -17
- package/dist/global-skills/eas-observe/references/setup.md +164 -5
- package/dist/global-skills/eas-observe/references/third-party.md +136 -0
- package/dist/global-skills/eas-simulator/SKILL.md +63 -11
- package/dist/global-skills/eas-simulator/references/controllers.md +21 -2
- package/dist/global-skills/eas-simulator/references/run-your-app.md +16 -11
- package/dist/global-skills/eas-simulator/references/troubleshooting.md +8 -5
- package/dist/global-skills/eas-update-insights/SKILL.md +8 -0
- package/dist/global-skills/eas-workflows/SKILL.md +15 -10
- package/dist/global-skills/eas-workflows/scripts/package.json +2 -7
- package/dist/global-skills/email-best-practices/.github/workflows/sync-skills.yml +30 -0
- package/dist/global-skills/email-best-practices/README.md +63 -0
- package/dist/global-skills/email-best-practices/references/accessibility.md +189 -0
- package/dist/global-skills/email-best-practices/references/compliance.md +125 -0
- package/dist/global-skills/email-best-practices/references/deliverability.md +121 -0
- package/dist/global-skills/email-best-practices/references/email-capture.md +129 -0
- package/dist/global-skills/email-best-practices/references/email-types.md +173 -0
- package/dist/global-skills/email-best-practices/references/list-management.md +157 -0
- package/dist/global-skills/email-best-practices/references/marketing-emails.md +115 -0
- package/dist/global-skills/email-best-practices/references/sending-reliability.md +155 -0
- package/dist/global-skills/email-best-practices/references/transactional-email-catalog.md +418 -0
- package/dist/global-skills/email-best-practices/references/transactional-emails.md +92 -0
- package/dist/global-skills/email-best-practices/references/webhooks-events.md +167 -0
- package/dist/global-skills/email-best-practices/tests/README.md +35 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/01-spam-deliverability.md +46 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/02-multi-region-compliance.md +48 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/03-retry-idempotency.md +36 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/04-webhook-bounce-handling.md +52 -0
- package/dist/global-skills/email-best-practices/tests/scenarios/05-new-saas-email-plan.md +51 -0
- package/dist/global-skills/expo-animation/LICENSE +21 -0
- package/dist/global-skills/expo-animation/RECIPES.md +385 -0
- package/dist/global-skills/expo-animation/SKILL.md +267 -0
- package/dist/global-skills/expo-animation/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-app-clip/SKILL.md +8 -0
- package/dist/global-skills/expo-brownfield/SKILL.md +8 -0
- package/dist/global-skills/expo-brownfield/references/brownfield-isolated.md +53 -4
- package/dist/global-skills/expo-data-fetching/SKILL.md +8 -0
- package/dist/global-skills/expo-design-system/SKILL.md +356 -0
- package/dist/global-skills/expo-design-system/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-design-system/references/audit.md +185 -0
- package/dist/global-skills/expo-dev-client/SKILL.md +8 -0
- package/dist/global-skills/expo-dom/SKILL.md +8 -0
- package/dist/global-skills/expo-examples/SKILL.md +8 -0
- package/dist/global-skills/expo-migrate-module/SKILL.md +113 -0
- package/dist/global-skills/expo-migrate-module/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-migrate-module/references/compatibility.md +73 -0
- package/dist/global-skills/expo-migrate-module/references/example.md +212 -0
- package/dist/global-skills/expo-migrate-module/references/migration-map.md +306 -0
- package/dist/global-skills/expo-module/SKILL.md +11 -1
- package/dist/global-skills/expo-native-ui/SKILL.md +8 -0
- package/dist/global-skills/expo-project-structure/SKILL.md +114 -0
- package/dist/global-skills/expo-project-structure/agents/openai.yaml +4 -0
- package/dist/global-skills/expo-router/SKILL.md +8 -0
- package/dist/global-skills/expo-skill-feedback/SKILL.md +66 -33
- package/dist/global-skills/expo-skill-feedback/agents/openai.yaml +2 -2
- package/dist/global-skills/expo-tailwind-setup/SKILL.md +8 -0
- package/dist/global-skills/expo-ui/SKILL.md +8 -0
- package/dist/global-skills/expo-upgrade/SKILL.md +15 -1
- package/dist/global-skills/expo-web-to-native/SKILL.md +8 -0
- package/dist/global-skills/extension-to-functions-codebase/SKILL.md +129 -0
- package/dist/global-skills/extension-to-functions-codebase/references/configuration-migration.md +161 -0
- package/dist/global-skills/extension-to-functions-codebase/references/destructuring-shim.md +122 -0
- package/dist/global-skills/extension-to-functions-codebase/references/signature-mapping.md +84 -0
- package/dist/global-skills/firebase-ai-logic-basics/SKILL.md +61 -19
- package/dist/global-skills/firebase-ai-logic-basics/references/flutter_setup.md +6 -3
- package/dist/global-skills/firebase-app-hosting-basics/SKILL.md +5 -1
- package/dist/global-skills/firebase-auth-basics/SKILL.md +4 -2
- package/dist/global-skills/firebase-basics/SKILL.md +5 -5
- package/dist/global-skills/firebase-crashlytics/SKILL.md +2 -0
- package/dist/global-skills/firebase-data-connect/SKILL.md +2 -0
- package/dist/global-skills/firebase-firestore/SKILL.md +3 -6
- package/dist/global-skills/firebase-hosting-basics/SKILL.md +4 -1
- package/dist/global-skills/firebase-remote-config-basics/SKILL.md +5 -1
- package/dist/global-skills/firebase-security-rules-auditor/SKILL.md +4 -1
- package/dist/global-skills/harden/SKILL.md +2 -1
- package/dist/global-skills/instrument-feature-flags/SKILL.md +1 -0
- package/dist/global-skills/instrument-feature-flags/references/COMMANDMENTS.md +5 -0
- package/dist/global-skills/instrument-feature-flags/references/adding-feature-flag-code.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/android.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/api.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/best-practices.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/django.md +38 -5
- package/dist/global-skills/instrument-feature-flags/references/dotnet.md +10 -4
- package/dist/global-skills/instrument-feature-flags/references/elixir.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/flask.md +17 -5
- package/dist/global-skills/instrument-feature-flags/references/flutter.md +7 -5
- package/dist/global-skills/instrument-feature-flags/references/go.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/ios.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/java.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/laravel.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/next-js.md +74 -8
- package/dist/global-skills/instrument-feature-flags/references/nodejs.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/php.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/python.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/react-native.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/react.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/ruby-on-rails.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/ruby.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/rust.md +6 -4
- package/dist/global-skills/instrument-feature-flags/references/usage.md +41 -4
- package/dist/global-skills/instrument-feature-flags/references/web.md +7 -5
- package/dist/global-skills/instrument-product-analytics/SKILL.md +2 -1
- package/dist/global-skills/instrument-product-analytics/references/COMMANDMENTS.md +5 -0
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-hybrid.md +12 -14
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-astro-ssr.md +25 -21
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-django.md +75 -55
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-fastapi.md +3 -6
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-flask.md +26 -16
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-nuxt-3-6.md +8 -5
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-nuxt-4.md +4 -4
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-react-react-router-7-framework.md +3 -3
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-ruby-on-rails.md +8 -4
- package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-tanstack-start.md +20 -8
- package/dist/global-skills/instrument-product-analytics/references/android.md +46 -4
- package/dist/global-skills/instrument-product-analytics/references/angular.md +41 -5
- package/dist/global-skills/instrument-product-analytics/references/astro.md +41 -5
- package/dist/global-skills/instrument-product-analytics/references/configuration.md +7 -4
- package/dist/global-skills/instrument-product-analytics/references/django.md +38 -5
- package/dist/global-skills/instrument-product-analytics/references/dotnet.md +10 -4
- package/dist/global-skills/instrument-product-analytics/references/elixir.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/flask.md +17 -5
- package/dist/global-skills/instrument-product-analytics/references/flutter.md +49 -4
- package/dist/global-skills/instrument-product-analytics/references/go.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/identify-users.md +38 -7
- package/dist/global-skills/instrument-product-analytics/references/ios.md +14 -4
- package/dist/global-skills/instrument-product-analytics/references/laravel.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/next-js.md +74 -8
- package/dist/global-skills/instrument-product-analytics/references/nuxt-js-3-6.md +39 -7
- package/dist/global-skills/instrument-product-analytics/references/nuxt-js.md +40 -4
- package/dist/global-skills/instrument-product-analytics/references/php.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/posthog-python.md +21 -17
- package/dist/global-skills/instrument-product-analytics/references/python.md +15 -5
- package/dist/global-skills/instrument-product-analytics/references/react-native.md +41 -7
- package/dist/global-skills/instrument-product-analytics/references/react-router-v6.md +18 -4
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-data-mode.md +18 -4
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-declarative-mode.md +18 -4
- package/dist/global-skills/instrument-product-analytics/references/react-router-v7-framework-mode.md +18 -4
- package/dist/global-skills/instrument-product-analytics/references/ruby-on-rails.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/ruby.md +6 -4
- package/dist/global-skills/instrument-product-analytics/references/svelte.md +42 -6
- package/dist/global-skills/instrument-product-analytics/references/tanstack-start.md +31 -7
- package/dist/global-skills/instrument-product-analytics/references/usage.md +41 -4
- package/dist/global-skills/instrument-product-analytics/references/vue-js.md +42 -6
- package/dist/global-skills/manifest.json +6 -1
- package/dist/global-skills/neon/SKILL.md +235 -121
- package/dist/global-skills/neon-ai-gateway/SKILL.md +95 -16
- package/dist/global-skills/neon-functions/SKILL.md +242 -152
- package/dist/global-skills/neon-functions/references/ai-sdk.md +9 -3
- package/dist/global-skills/neon-functions/references/mastra-studio.md +1 -1
- package/dist/global-skills/neon-functions/references/mcp.md +13 -4
- package/dist/global-skills/neon-functions/references/sentry.md +165 -52
- package/dist/global-skills/neon-functions/references/sse.md +23 -6
- package/dist/global-skills/neon-object-storage/SKILL.md +40 -16
- package/dist/global-skills/neon-postgres/SKILL.md +63 -262
- package/dist/global-skills/neon-postgres-branches/SKILL.md +61 -50
- package/dist/global-skills/neon-postgres-egress-optimizer/SKILL.md +22 -3
- package/dist/global-skills/resend/SKILL.md +6 -6
- package/dist/global-skills/resend/references/automations.md +2 -2
- package/dist/global-skills/resend/references/broadcasts.md +11 -3
- package/dist/global-skills/resend/references/domains.md +25 -3
- package/dist/global-skills/resend/references/installation.md +7 -7
- package/dist/global-skills/setup-payments/SKILL.md +4 -5
- package/dist/global-skills/stripe-best-practices/SKILL.md +32 -7
- package/dist/global-skills/stripe-best-practices/references/billing.md +11 -1
- package/dist/global-skills/stripe-best-practices/references/payments.md +23 -2
- package/dist/global-skills/stripe-best-practices/references/security.md +21 -11
- package/dist/global-skills/stripe-best-practices/references/tax.md +116 -11
- package/dist/global-skills/supabase/CHANGELOG.md +25 -0
- package/dist/global-skills/supabase/SKILL.md +5 -1
- package/dist/global-skills/supabase-postgres-best-practices/CHANGELOG.md +30 -0
- package/dist/global-skills/supabase-postgres-best-practices/SKILL.md +1 -1
- package/dist/global-skills/use-kit-mcp/SKILL.md +5 -5
- package/dist/global-skills/use-railway/SKILL.md +4 -4
- package/dist/global-skills/use-railway/references/iac.md +206 -57
- package/dist/global-skills/use-railway/scripts/railway-api.sh +7 -2
- package/dist/global-skills/xcode-project-setup/SKILL.md +2 -0
- package/package.json +12 -9
- package/LICENSE.md +0 -47
- package/dist/global-skills/eas-workflows/scripts/validate.js +0 -84
- package/dist/global-skills/expo-skill-feedback/scripts/skill-feedback.cjs +0 -118
- package/dist/global-skills/neon-functions/references/hono-websockets.md +0 -145
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
# 1.0 to 2.0 Migration Map
|
|
2
|
+
|
|
3
|
+
Use this reference while editing. Preserve behavior first; macro adoption is secondary.
|
|
4
|
+
|
|
5
|
+
## Module and naming
|
|
6
|
+
|
|
7
|
+
Convert the module class and remove `Name(...)` only when the paired core reads the macro-synthesized name:
|
|
8
|
+
|
|
9
|
+
```swift
|
|
10
|
+
// 1.0
|
|
11
|
+
public final class CameraModule: Module {
|
|
12
|
+
public func definition() -> ModuleDefinition {
|
|
13
|
+
Name("Camera")
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// 2.0
|
|
18
|
+
@ExpoModule("Camera")
|
|
19
|
+
public final class CameraModule: Module {}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Always carry a custom 1.0 name into `@ExpoModule("...")`. A stale `Name(...)` can override or conflict with the 2.0 name depending on the core revision. In mixed mode, remove `Name(...)` only after verifying the installed `_jsName` contract.
|
|
23
|
+
|
|
24
|
+
## Functions
|
|
25
|
+
|
|
26
|
+
Move a DSL closure into a real method and use `@JS("wireName")` when the Swift method name is different:
|
|
27
|
+
|
|
28
|
+
```swift
|
|
29
|
+
// 1.0
|
|
30
|
+
Function("sum") { (a: Double, b: Double) -> Double in
|
|
31
|
+
return a + b
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// 2.0
|
|
35
|
+
@JS("sum")
|
|
36
|
+
func add(a: Double, b: Double) -> Double {
|
|
37
|
+
return a + b
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Preserve:
|
|
42
|
+
|
|
43
|
+
- the JS name
|
|
44
|
+
- positional arity
|
|
45
|
+
- optional arguments and Swift defaults
|
|
46
|
+
- thrown errors and return type
|
|
47
|
+
- whether the result is synchronous or a Promise
|
|
48
|
+
|
|
49
|
+
Do not migrate functions that resolve to the same JS name unless the checked-out macro has overload grouping and collision diagnostics. Older 2.0 implementations install one property per declaration, so the last overload silently wins.
|
|
50
|
+
|
|
51
|
+
Reject or keep in DSL any unsupported signature such as variadics, `inout`, unresolved generics, or closure parameters without verified callback support. A `Promise` parameter is also unsupported; refactor it as described under Async functions.
|
|
52
|
+
|
|
53
|
+
### Async functions
|
|
54
|
+
|
|
55
|
+
A `Promise` parameter is not supported in a `@JS` signature; 2.0 drops the trailing-`Promise` argument entirely. A Promise-returning function has three shapes in 2.0. Pick by how the underlying work produces its result.
|
|
56
|
+
|
|
57
|
+
**1. Standard `async` method.** The common case. Swift `async` maps to a JS Promise:
|
|
58
|
+
|
|
59
|
+
```swift
|
|
60
|
+
// 1.0
|
|
61
|
+
AsyncFunction("load") { (url: URL) -> String in
|
|
62
|
+
return try loadSynchronously(url)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// 2.0
|
|
66
|
+
@JS
|
|
67
|
+
func load(url: URL) async throws -> String {
|
|
68
|
+
return try await loadResource(url)
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**2. Checked continuation.** When the result arrives through a delegate or completion handler that fires once, wrap it with `withCheckedThrowingContinuation` (or `withCheckedContinuation` for non-throwing callbacks, or an `AsyncStream` for repeated values). This is the usual refactor for a 1.0 `AsyncFunction` that took a trailing `Promise` instance:
|
|
73
|
+
|
|
74
|
+
```swift
|
|
75
|
+
// 1.0
|
|
76
|
+
AsyncFunction("start") { (promise: Promise) in
|
|
77
|
+
scanner.start(
|
|
78
|
+
onSuccess: { result in promise.resolve(result) },
|
|
79
|
+
onFailure: { error in promise.reject(error) }
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// 2.0
|
|
84
|
+
@JS
|
|
85
|
+
func start() async throws -> ScanResult {
|
|
86
|
+
return try await withCheckedThrowingContinuation { continuation in
|
|
87
|
+
scanner.start(
|
|
88
|
+
onSuccess: { result in continuation.resume(returning: result) },
|
|
89
|
+
onFailure: { error in continuation.resume(throwing: error) }
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Resume the continuation exactly once on every path. If the callback API cannot guarantee that, or the refactor is otherwise unsafe, keep the function on the DSL instead of forcing it.
|
|
96
|
+
|
|
97
|
+
**3. Synchronous method returning a `Task`.** The `Task` encodes to a promise that settles with its result. Use it when the work is naturally a `Task`, or when a promise is needed as a value nested inside another encoded result rather than as the function's own return:
|
|
98
|
+
|
|
99
|
+
```swift
|
|
100
|
+
// 2.0
|
|
101
|
+
@JS
|
|
102
|
+
func download(url: URL) -> Task<DownloadResult, any Error> {
|
|
103
|
+
return Task {
|
|
104
|
+
try await self.downloader.download(url)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
This shape requires the `JavaScriptEncodable` conformance for `Task` in the checked-out core (encode-only; a JS promise does not decode back into a `Task`). Verify it exists before using this shape; prefer shape 1 or 2 when it is absent.
|
|
110
|
+
|
|
111
|
+
Do not assume scheduling is unchanged. 2.0 async members are `@JavaScriptActor`-isolated and begin on the JS thread until their first real suspension. A 1.0 `.runOnQueue(...)` function or a workload that relied on automatic background execution must not be migrated as-is. Never move blocking I/O directly onto the JS actor.
|
|
112
|
+
|
|
113
|
+
For a queue-pinned 1.0 function, prefer restructuring the work onto the Swift Concurrency model (structured concurrency, an actor, or a detached task for blocking work). When that is not feasible because the queue itself is the contract, for example a library that must be called from one serial queue, convert to an `async` method that dispatches to that queue inside a checked continuation:
|
|
114
|
+
|
|
115
|
+
```swift
|
|
116
|
+
// 1.0
|
|
117
|
+
AsyncFunction("process") { (input: String) -> String in
|
|
118
|
+
return try self.processor.process(input)
|
|
119
|
+
}
|
|
120
|
+
.runOnQueue(processingQueue)
|
|
121
|
+
|
|
122
|
+
// 2.0
|
|
123
|
+
@JS
|
|
124
|
+
func process(input: String) async throws -> String {
|
|
125
|
+
return try await withCheckedThrowingContinuation { continuation in
|
|
126
|
+
processingQueue.async {
|
|
127
|
+
do {
|
|
128
|
+
continuation.resume(returning: try self.processor.process(input))
|
|
129
|
+
} catch {
|
|
130
|
+
continuation.resume(throwing: error)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## Properties and constants
|
|
138
|
+
|
|
139
|
+
Map a getter to a getter-only `@JS var`; map a getter/setter pair to a settable stored or computed `@JS var`:
|
|
140
|
+
|
|
141
|
+
```swift
|
|
142
|
+
// 1.0
|
|
143
|
+
Property("volume") { self.volume }
|
|
144
|
+
.set { self.volume = $0 }
|
|
145
|
+
|
|
146
|
+
// 2.0
|
|
147
|
+
@JS
|
|
148
|
+
var volume: Double = 1
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Access control does not define JS mutability. Verify whether the declaration is syntactically settable; a stored `var` normally produces a JS setter.
|
|
152
|
+
|
|
153
|
+
Map a 1.0 `Constant` to a `@JS let`; a `let` property is a natural constant and produces a read-only JS property:
|
|
154
|
+
|
|
155
|
+
```swift
|
|
156
|
+
// 1.0
|
|
157
|
+
Constant("apiVersion") { 3 }
|
|
158
|
+
|
|
159
|
+
// 2.0
|
|
160
|
+
@JS
|
|
161
|
+
let apiVersion = 3
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Evaluation timing shifts: a 1.0 `Constant` closure runs lazily, while a `let` initializes with the module instance. When the value is expensive and must stay deferred, keep private lazy storage and expose a getter-only computed property (a `var` with a `{ }` getter body and no storage of its own), not a stored `lazy var`:
|
|
165
|
+
|
|
166
|
+
```swift
|
|
167
|
+
private lazy var cachedInfo = computeInfo()
|
|
168
|
+
|
|
169
|
+
@JS
|
|
170
|
+
var info: Info { // computed: recomputes nothing, just returns the cached value
|
|
171
|
+
return cachedInfo
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Do not expose a cached value as a settable `lazy @JS var`.
|
|
176
|
+
|
|
177
|
+
## Events
|
|
178
|
+
|
|
179
|
+
Replace `Events(...)` plus `sendEvent(...)` with a typed function property:
|
|
180
|
+
|
|
181
|
+
```swift
|
|
182
|
+
@Record
|
|
183
|
+
struct ProgressEvent {
|
|
184
|
+
var percent: Double
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Explicit string preserves the old wire name.
|
|
188
|
+
@Event("onProgress")
|
|
189
|
+
var onProgress: (ProgressEvent) -> Void
|
|
190
|
+
|
|
191
|
+
func report(percent: Double) {
|
|
192
|
+
onProgress(ProgressEvent(percent: percent))
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
The default `@Event` wire name strips a leading `on` and decapitalizes the remainder: Swift `onProgress` emits `progress`. 1.0 modules commonly expose `onProgress`. During migration, pass the original wire name explicitly unless an intentional JS breaking change was approved.
|
|
197
|
+
|
|
198
|
+
Use `() -> Void` for no-payload events. For payloads, create or reuse a `JavaScriptEncodable` type instead of preserving an untyped dictionary. Migrate `OnStartObserving` and `OnStopObserving` to the `didStartListening(event:)`/`didStopListening(event:)` lifecycle hooks (see Views and lifecycle).
|
|
199
|
+
|
|
200
|
+
Default `@Event` dispatch schedules onto the JS thread and is callable from other isolation contexts. Do not use `sync: true` unless core provides the matching `emitSync` overloads.
|
|
201
|
+
|
|
202
|
+
## Shared objects
|
|
203
|
+
|
|
204
|
+
Move instance behavior from a `Class(...)` block onto the `SharedObject` subclass:
|
|
205
|
+
|
|
206
|
+
```swift
|
|
207
|
+
// 2.0
|
|
208
|
+
@SharedObject
|
|
209
|
+
final class Download: SharedObject {
|
|
210
|
+
@JS
|
|
211
|
+
init(url: URL) {
|
|
212
|
+
self.url = url
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
@JS
|
|
216
|
+
func pause() {}
|
|
217
|
+
|
|
218
|
+
@JS
|
|
219
|
+
var progress: Double { currentProgress }
|
|
220
|
+
|
|
221
|
+
// Installs on the JS class (constructor) object, not the prototype.
|
|
222
|
+
@JS
|
|
223
|
+
static let maxConcurrent = 4
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
@ExpoModule(classes: [Download.self])
|
|
227
|
+
final class DownloadModule: Module {}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Drop the leading owner argument used by instance DSL closures; use `self` in the real instance method. Preserve constructor arity and JS member names.
|
|
231
|
+
|
|
232
|
+
Migrate only when the checked-out core supplies the shared-object decoration and construction hooks. Static properties migrate as Swift `static` or `class` properties and install on the JS class (constructor) object rather than the prototype; verify constructor-side routing for static functions before migrating them, since instance support does not imply static-function support. Never create both a 1.0 `Class(...)` entry and a 2.0 registration for the same class without confirming that core intentionally merges them.
|
|
233
|
+
|
|
234
|
+
Static members belong to shared objects, not modules: a module is exported to JS as an instance, so Swift `static` members on a `Module` class are not useful there. Keep module-level values as instance `@JS` members.
|
|
235
|
+
|
|
236
|
+
## Records
|
|
237
|
+
|
|
238
|
+
Attach `@Record`, remove field wrappers, and encode requiredness in the declaration:
|
|
239
|
+
|
|
240
|
+
```swift
|
|
241
|
+
@Record
|
|
242
|
+
struct Options {
|
|
243
|
+
var source: URL // required
|
|
244
|
+
var retries: Int = 3 // omittable; default applies
|
|
245
|
+
var label: String? // omittable and nullable
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Rules:
|
|
250
|
+
|
|
251
|
+
- non-optional with no default: required
|
|
252
|
+
- any property with a default: omittable
|
|
253
|
+
- optional type: omittable and nullable
|
|
254
|
+
|
|
255
|
+
Preserve the 1.0 contract exactly. For example, migrate `@Field var source: URL? = nil` to `var source: URL?`, not to `var source: URL`, unless the user approved a breaking change.
|
|
256
|
+
|
|
257
|
+
Every stored property is part of the 2.0 record surface. If the old type contains stored bookkeeping that was not a 1.0 field, move it out of the record or leave the type on 1.0; there is no field opt-out. Verify that each field supports the required `JavaScriptDecodable`/`JavaScriptEncodable` direction.
|
|
258
|
+
|
|
259
|
+
Do not adopt `@Union` until that macro and its coding witnesses exist in the target.
|
|
260
|
+
|
|
261
|
+
## Views and lifecycle
|
|
262
|
+
|
|
263
|
+
Keep UIKit `View`, `Prop`, view `Events`, and `OnViewDidUpdateProps` DSL entries until the target includes the complete `@ViewProps`/`@ExpoView` core contract. Macro declarations or expansion tests alone do not prove the runtime update path exists.
|
|
264
|
+
|
|
265
|
+
Module lifecycle is core-owned rather than macro-generated. The DSL components map to hook methods with no-op defaults:
|
|
266
|
+
|
|
267
|
+
| 1.0 | 2.0 |
|
|
268
|
+
| --- | --- |
|
|
269
|
+
| `OnCreate` | `didCreate()` |
|
|
270
|
+
| `OnDestroy` | `willDestroy()` |
|
|
271
|
+
| `OnStartObserving` | `didStartListening(event:)` |
|
|
272
|
+
| `OnStopObserving` | `didStopListening(event:)` |
|
|
273
|
+
|
|
274
|
+
Rules:
|
|
275
|
+
|
|
276
|
+
- Use the `override` keyword when the class inherits `Module`/`BaseModule`; define the hooks directly (no `override`) when the conformance comes only from `@ExpoModule`. Hooks added only in a subclass of a macro module are not called; keep them on the class that declares the conformance.
|
|
277
|
+
- The listening hooks receive the event name. A module-wide 1.0 `OnStartObserving` ignores the argument; a per-event `OnStartObserving("name")` becomes a comparison on it.
|
|
278
|
+
- `didCreate()` runs after the module is registered, slightly later than 1.0 `OnCreate`, which fires before registration; `willDestroy()` runs at holder teardown. Verify nothing depends on the earlier timing before migrating `OnCreate`.
|
|
279
|
+
- DSL lifecycle components can remain during an incremental migration and each fires exactly once, but do not implement a DSL component and its hook for the same behavior, or the work runs twice.
|
|
280
|
+
|
|
281
|
+
There is no 2.0 replacement for every lifecycle component; for example, retain app-context teardown handling when no matching hook exists.
|
|
282
|
+
|
|
283
|
+
## Mixed mode
|
|
284
|
+
|
|
285
|
+
`@ExpoModule` may coexist with a non-empty `definition()` when the paired core supports merging the two surfaces. Keep only unsupported entries in the DSL and avoid duplicate names across macro and DSL registrations.
|
|
286
|
+
|
|
287
|
+
Before deleting `definition()`, verify that it contains no:
|
|
288
|
+
|
|
289
|
+
- views or view events
|
|
290
|
+
- lifecycle or app-context listeners
|
|
291
|
+
- queue-pinned functions
|
|
292
|
+
- shared-object static functions or other unsupported definitions
|
|
293
|
+
|
|
294
|
+
## Contract checklist
|
|
295
|
+
|
|
296
|
+
For every migrated member compare before and after:
|
|
297
|
+
|
|
298
|
+
| Concern | Must remain stable |
|
|
299
|
+
| --- | --- |
|
|
300
|
+
| Module | registration name and `requireNativeModule` key |
|
|
301
|
+
| Function | JS name, accepted arity, omitted/default behavior, sync/Promise result |
|
|
302
|
+
| Property | JS name, read/write behavior, evaluation/caching |
|
|
303
|
+
| Event | listener string, payload shape, timing |
|
|
304
|
+
| Record | field names, requiredness, nullability, defaults |
|
|
305
|
+
| Shared object | constructor shape, prototype vs constructor placement, identity |
|
|
306
|
+
| Execution | JS actor, main actor, background queue, ordering |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: expo-module
|
|
3
|
-
description: Framework (OSS). Guide for creating and writing Expo native modules and views using the Expo Modules API (Swift, Kotlin, TypeScript). Covers module definition DSL, native views, shared objects, config plugins, lifecycle hooks, autolinking, and type system. Use when building or modifying native modules for Expo.
|
|
3
|
+
description: Framework (OSS). Guide for creating and writing Expo native modules and views using the Expo Modules API (Swift, Kotlin, TypeScript). Covers module definition DSL, native views, shared objects, config plugins, lifecycle hooks, autolinking, and type system. Use when building or modifying native modules for Expo. Not for migrating an existing Swift module from the definition DSL to the Expo Modules API 2.0 macros; use expo-migrate-module (from the expo-experiments plugin) for that.
|
|
4
4
|
version: 1.0.0
|
|
5
5
|
license: MIT
|
|
6
6
|
---
|
|
@@ -18,6 +18,8 @@ Complete reference for building native modules and views using the Expo Modules
|
|
|
18
18
|
- Adding Android, Apple, or web support to an existing Expo module
|
|
19
19
|
- Editing `expo-module.config.json`, config plugins, or lifecycle hooks
|
|
20
20
|
|
|
21
|
+
To migrate an existing Swift module from the definition DSL to the Expo Modules API 2.0 macros (`@ExpoModule`, `@JS`, `@Event`), use the `expo-migrate-module` skill (from the `expo-experiments` plugin) instead.
|
|
22
|
+
|
|
21
23
|
## References
|
|
22
24
|
|
|
23
25
|
Consult these resources as needed:
|
|
@@ -139,3 +141,11 @@ export function hello(name: string): string {
|
|
|
139
141
|
```
|
|
140
142
|
|
|
141
143
|
Note: iOS uses just the class name; Android uses the fully-qualified class name (package + class). See `references/module-config.md` for all fields.
|
|
144
|
+
|
|
145
|
+
## Submitting Feedback
|
|
146
|
+
If you encounter errors, misleading or outdated information in this skill, report it so Expo can improve:
|
|
147
|
+
```bash
|
|
148
|
+
npx --yes submit-expo-feedback@latest --category skills --subject "expo-module" "<actionable feedback>"
|
|
149
|
+
```
|
|
150
|
+
Only submit when you have something specific and actionable to report. Include as much relevant context as possible.
|
|
151
|
+
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.
|
|
@@ -179,3 +179,11 @@ Use CSS `boxShadow` style prop. NEVER use legacy React Native shadow or elevatio
|
|
|
179
179
|
```
|
|
180
180
|
|
|
181
181
|
'inset' shadows are supported.
|
|
182
|
+
|
|
183
|
+
## Submitting Feedback
|
|
184
|
+
If you encounter errors, misleading or outdated information in this skill, report it so Expo can improve:
|
|
185
|
+
```bash
|
|
186
|
+
npx --yes submit-expo-feedback@latest --category skills --subject "expo-native-ui" "<actionable feedback>"
|
|
187
|
+
```
|
|
188
|
+
Only submit when you have something specific and actionable to report. Include as much relevant context as possible.
|
|
189
|
+
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,114 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: expo-project-structure
|
|
3
|
+
description: Framework (OSS). Folder structure for a new Expo app. Use when scaffolding or laying out a new Expo project with Expo Router, or deciding where a file should live in one. For new projects only — never restructure an existing app to match.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
license: MIT
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Expo Project Structure
|
|
9
|
+
|
|
10
|
+
A starting skeleton for a **new** Expo app — one with no committed folder structure yet.
|
|
11
|
+
|
|
12
|
+
**Apply only to new projects.** If the app already has a layout, follow its existing conventions and leave files where they are — a default to start from, never a standard to enforce or migrate toward. When unsure whether a project is new, ask before moving anything.
|
|
13
|
+
|
|
14
|
+
The whole layout, assembled from the rules below:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
├── assets/
|
|
18
|
+
├── scripts/
|
|
19
|
+
├── src/
|
|
20
|
+
│ ├── app/ # Expo Router routes ONLY — every file is a route
|
|
21
|
+
│ │ ├── api/ # server API routes, grouped here
|
|
22
|
+
│ │ │ ├── user+api.ts
|
|
23
|
+
│ │ │ └── settings+api.ts
|
|
24
|
+
│ │ ├── _layout.tsx
|
|
25
|
+
│ │ ├── _layout.web.tsx # platform-specific layout
|
|
26
|
+
│ │ ├── index.tsx
|
|
27
|
+
│ │ └── settings.tsx
|
|
28
|
+
│ ├── components/ # reusable UI: button, card, table…
|
|
29
|
+
│ │ ├── table/ # complex component → folder + index.tsx
|
|
30
|
+
│ │ │ ├── cell.tsx
|
|
31
|
+
│ │ │ └── index.tsx
|
|
32
|
+
│ │ ├── bar-chart.tsx
|
|
33
|
+
│ │ ├── bar-chart.web.tsx # platform-specific variant
|
|
34
|
+
│ │ └── button.tsx
|
|
35
|
+
│ ├── screens/ # screen bodies that route files render
|
|
36
|
+
│ │ ├── home/
|
|
37
|
+
│ │ │ ├── card.tsx # used only by Home — not shared
|
|
38
|
+
│ │ │ └── index.tsx # rendered by src/app/index.tsx
|
|
39
|
+
│ │ └── settings.tsx
|
|
40
|
+
│ ├── server/ # server-only helpers used by app/api
|
|
41
|
+
│ │ ├── auth.ts
|
|
42
|
+
│ │ └── db.ts
|
|
43
|
+
│ ├── utils/ # standalone helpers + colocated tests
|
|
44
|
+
│ │ ├── format-date.ts
|
|
45
|
+
│ │ └── format-date.test.ts
|
|
46
|
+
│ ├── hooks/ # reusable hooks: use-theme.ts…
|
|
47
|
+
│ ├── constants.ts
|
|
48
|
+
│ └── theme.ts
|
|
49
|
+
├── app.json
|
|
50
|
+
├── eas.json
|
|
51
|
+
└── package.json
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## `src/` and `src/app`
|
|
55
|
+
|
|
56
|
+
Keep app code under `src/` to separate it from config files. Expo Router supports both `app/` and `src/app/` out of the box — to switch, move the folder and restart the bundler. The default template aliases `@/*` to `./src/*` in `tsconfig.json`.
|
|
57
|
+
|
|
58
|
+
`src/app` is **routes-only**: every file there becomes a route, so nothing else belongs in it. Everything below lives in sibling folders.
|
|
59
|
+
|
|
60
|
+
## components/ — reusable UI
|
|
61
|
+
|
|
62
|
+
Generic, reused UI (button, card, table) with one named export each. Name files in **kebab-case** (`bar-chart.tsx`), matching the default `create-expo-app` template. When a component grows, give it its own folder with the root in `index.tsx` and **colocate** its private sub-components beside it — the import path (`@/components/table`) stays unchanged.
|
|
63
|
+
|
|
64
|
+
## screens/ — screen bodies
|
|
65
|
+
|
|
66
|
+
Because `app/` files must be routes, complex screen UI that isn't reused has no home there. Once a screen grows big enough to need breaking out to separate components, put it in `screens/` and let each route just render its screen:
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
import { Home } from "@/screens/home";
|
|
70
|
+
|
|
71
|
+
export default function HomeScreen() {
|
|
72
|
+
// route-specific concerns only — e.g. read url params here
|
|
73
|
+
return <Home />;
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
**Colocate** a screen's private components inside its folder (`screens/home/components/`). A bonus: the same screen can render under multiple routes.
|
|
78
|
+
|
|
79
|
+
## server/ + app/api/ — separate server code
|
|
80
|
+
|
|
81
|
+
Appending `+api` to a file in `app/` makes it a server **API route**. Server code is different from frontend code — it runs in a Node-like server environment (deployed with EAS Hosting or on [third-party services](https://docs.expo.dev/router/web/api-routes/#hosting-on-third-party-services)) and can read secret env vars (`process.env.X`, not just `EXPO_PUBLIC_*`). Keep it apart:
|
|
82
|
+
|
|
83
|
+
- Group all routes under `app/api/` → `/api/user`, `/api/settings`. This colocates them and avoids collisions (e.g. a `/user` screen and a `/user` route).
|
|
84
|
+
- Put shared server-only helpers in `src/server/`.
|
|
85
|
+
- Consider ESLint rules that fence `+api` files and `server/` off from frontend-only checks.
|
|
86
|
+
|
|
87
|
+
## Platform-specific code
|
|
88
|
+
|
|
89
|
+
Small differences: use `Platform.select` / `Platform.OS`. For larger ones, split into platform files instead of inline `if/else` — `bar-chart.tsx` + `bar-chart.web.tsx`, imported extension-free (`@/components/bar-chart`); Metro picks the right file per target.
|
|
90
|
+
|
|
91
|
+
- Props must be identical across variants.
|
|
92
|
+
- A default file (no platform extension) is always required — make it a no-op if the component is single-platform.
|
|
93
|
+
- Supported extensions: `.ios`, `.android`, `.native`, `.web`.
|
|
94
|
+
|
|
95
|
+
## Colocate styles and tests
|
|
96
|
+
|
|
97
|
+
- **Styles:** keep the `StyleSheet.create({ ... })` object at the bottom of the component file rather than in a separate `.styles` file.
|
|
98
|
+
- **Tests:** put `format-date.test.ts` next to `format-date.ts` (preferred over a separate `__tests__/` folder) so tested files are obvious at a glance.
|
|
99
|
+
|
|
100
|
+
## AI and config files
|
|
101
|
+
|
|
102
|
+
Agent instructions live at the repo root — `AGENTS.md` / `CLAUDE.md`, with project skills under `.claude/`. Other config and assets stay outside `src/`: `app.json` / `app.config.ts`, `eas.json`, `package.json`, `assets/`, and `scripts/`.
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
Based on [Expo app folder structure best practices](https://expo.dev/blog/expo-app-folder-structure-best-practices) by Kadi Kraman. For `src/` precedence and alias mechanics, see the [Expo docs](https://docs.expo.dev/router/reference/src-directory/).
|
|
107
|
+
|
|
108
|
+
## Submitting Feedback
|
|
109
|
+
If you encounter errors, misleading or outdated information in this skill, report it so Expo can improve:
|
|
110
|
+
```bash
|
|
111
|
+
npx --yes submit-expo-feedback@latest --category skills --subject "expo-project-structure" "<actionable feedback>"
|
|
112
|
+
```
|
|
113
|
+
Only submit when you have something specific and actionable to report. Include as much relevant context as possible.
|
|
114
|
+
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: "Expo Project Structure"
|
|
3
|
+
short_description: "Recommended folder structure for new Expo apps"
|
|
4
|
+
default_prompt: "Use $expo-project-structure to lay out a new Expo app: the src/ layout, routes-only app/ directory, screens, components, server code separation, and platform-specific files."
|
|
@@ -228,3 +228,11 @@ export default function Layout({ segment }) {
|
|
|
228
228
|
);
|
|
229
229
|
}
|
|
230
230
|
```
|
|
231
|
+
|
|
232
|
+
## Submitting Feedback
|
|
233
|
+
If you encounter errors, misleading or outdated information in this skill, report it so Expo can improve:
|
|
234
|
+
```bash
|
|
235
|
+
npx --yes submit-expo-feedback@latest --category skills --subject "expo-router" "<actionable feedback>"
|
|
236
|
+
```
|
|
237
|
+
Only submit when you have something specific and actionable to report. Include as much relevant context as possible.
|
|
238
|
+
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.
|
|
@@ -1,54 +1,87 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: expo-skill-feedback
|
|
3
|
-
description:
|
|
3
|
+
description: 'Submit feedback on an Expo skill—or Expo itself—and control bundled anonymous usage telemetry (off by default / opt-in). Submit feedback with: npx --yes submit-expo-feedback@latest "ACTIONABLE_FEEDBACK". Optionally add either or both: --category "CATEGORY" and --subject "SUBJECT". Replace the uppercase placeholders before running. Use when a skill was useful, confusing, broken, missing context, or worth improving; when Expo, Expo CLI, EAS CLI, docs, or MCP worked well or fell short; when an AI agent repeatedly failed, got stuck, or needed the user to take over an Expo task (report it as an eval candidate); or when the user explicitly asks to enable or disable telemetry (tracking), check its status, or understand what it collects.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Expo Skill Feedback
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
enabled. Feedback goes to the Expo team via PostHog. Only the skill name, your rating + note,
|
|
11
|
-
platform, and a hash of a random local install id are sent — never code, prompts, file paths,
|
|
12
|
-
secrets, or personal data. (A separate automatic `skill_invoked` event fires when a skill runs
|
|
13
|
-
*once enabled*; the switch below controls both.)
|
|
8
|
+
Help Expo improve by sharing specific feedback about what worked well or what fell short. Feedback
|
|
9
|
+
submission is independent of usage telemetry and does not require enabling it.
|
|
14
10
|
|
|
15
|
-
##
|
|
11
|
+
## Submit feedback
|
|
16
12
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
```bash
|
|
14
|
+
npx --yes submit-expo-feedback@latest "<ACTIONABLE_FEEDBACK>"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Add either optional flag independently when it provides useful context:
|
|
20
18
|
|
|
21
19
|
```bash
|
|
22
|
-
|
|
23
|
-
--skill eas-app-stores --rating useful \
|
|
24
|
-
--text "TestFlight steps were clear and worked first try."
|
|
20
|
+
npx --yes submit-expo-feedback@latest --category "<CATEGORY>" --subject "<SUBJECT>" "<ACTIONABLE_FEEDBACK>"
|
|
25
21
|
```
|
|
26
22
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
- `--dry-run` prints the payload without sending
|
|
23
|
+
`--category` defaults to `unknown`, and `--subject` may be omitted when there is no specific target.
|
|
24
|
+
When including them, choose the values that most precisely identify what the feedback is about:
|
|
30
25
|
|
|
31
|
-
|
|
26
|
+
| Category | Subject |
|
|
27
|
+
| --- | --- |
|
|
28
|
+
| `skills` | Exact skill name from its frontmatter, such as `expo-router` |
|
|
29
|
+
| `docs` | Full Expo documentation URL |
|
|
30
|
+
| `mcp` | Exact MCP tool name used |
|
|
31
|
+
| `expo-cli` | Full Expo CLI command, such as `npx expo install` |
|
|
32
|
+
| `eas-cli` | Full EAS CLI command, such as `eas build` |
|
|
33
|
+
| `evals` | Expo package or command the failed task involves, else a capability phrase, such as `expo-router` or `eas build` |
|
|
34
|
+
| `unknown` | Concise Expo product, package, feature, or other topic |
|
|
32
35
|
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
In the final argument, say what helped and why, or provide the relevant context, expected behavior,
|
|
37
|
+
and what happened instead. Do not include secrets, source code, personal data, long prompts, or stack traces.
|
|
35
38
|
|
|
36
|
-
##
|
|
39
|
+
## Eval candidates: tasks that broke the model
|
|
37
40
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
Expo turns hard real-world tasks into agent evals: anything Expo an agent can attempt — framework,
|
|
42
|
+
EAS, tooling — qualifies, whether or not a skill was involved. The signal worth sending is a task an
|
|
43
|
+
AI agent could not complete cleanly despite real effort: several failed attempts, a build or screen
|
|
44
|
+
that never worked, or the user stepping in to fix it manually. Never submit quick slips the agent
|
|
45
|
+
corrected itself, more than one candidate per session, or a task already reported.
|
|
46
|
+
|
|
47
|
+
When such a failure happens — or the user says a model failed at an Expo task — show the user the exact
|
|
48
|
+
submission you intend to send and get approval; the Task field must describe the Expo-technical
|
|
49
|
+
shape of the task, never the user's product or business context. Without a user to approve it
|
|
50
|
+
(headless or CI runs), do not submit. Then run from the failing app's directory (the CLI attaches
|
|
51
|
+
the SDK and package versions, agent harness, and platform automatically) with `--category evals`,
|
|
52
|
+
`--subject` naming the Expo package or command involved (a capability phrase only when no single
|
|
53
|
+
package fits), and this structure in the final argument:
|
|
54
|
+
|
|
55
|
+
```text
|
|
56
|
+
Task: <what was asked, self-contained>.
|
|
57
|
+
Expected: <observable success criteria>.
|
|
58
|
+
Actual: <what the agent did instead>.
|
|
59
|
+
Wrong approach: <the specific mistake, such as a wrong API, hallucinated prop, or bad pattern>.
|
|
60
|
+
Evidence: <model name, attempts, how it was solved — or never was; omit what you cannot verify>.
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
A good candidate is solvable (eventually done or clearly doable), verifiable (success is
|
|
64
|
+
observable), and specific. Mention only environment details the CLI cannot see, such as other key
|
|
65
|
+
packages or a freshly created app. Describe code; do not paste it. If the command fails with an
|
|
66
|
+
error naming `evals` as an invalid category, resend once with `--category unknown` and the same
|
|
67
|
+
subject prefixed `eval-candidate: `; on any other error, do not resend.
|
|
68
|
+
|
|
69
|
+
## Usage telemetry
|
|
70
|
+
|
|
71
|
+
Automatic skill usage telemetry is separate from feedback and **off by default**. Never enable it
|
|
72
|
+
without an explicit user request. Use the following script with `--on`, `--off`, or `--status`:
|
|
42
73
|
|
|
43
74
|
```bash
|
|
44
|
-
node "${CLAUDE_PLUGIN_ROOT}/skills/expo-skill-feedback/scripts/telemetry.cjs" --
|
|
75
|
+
node "${CLAUDE_PLUGIN_ROOT}/skills/expo-skill-feedback/scripts/telemetry.cjs" --status
|
|
45
76
|
```
|
|
46
77
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
state. Env equivalents: `EXPO_SKILLS_TELEMETRY=1` to enable, `=0` or `DO_NOT_TRACK=1` to
|
|
50
|
-
disable; CI never sends.
|
|
78
|
+
Environment equivalents are `EXPO_SKILLS_TELEMETRY=1` to enable and
|
|
79
|
+
`EXPO_SKILLS_TELEMETRY=0` or `DO_NOT_TRACK=1` to disable. CI never sends telemetry.
|
|
51
80
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
81
|
+
## Submitting Feedback
|
|
82
|
+
If you encounter errors, misleading or outdated information in this skill, report it so Expo can improve:
|
|
83
|
+
```bash
|
|
84
|
+
npx --yes submit-expo-feedback@latest --category skills --subject "expo-skill-feedback" "<actionable feedback>"
|
|
85
|
+
```
|
|
86
|
+
Only submit when you have something specific and actionable to report. Include as much relevant context as possible.
|
|
87
|
+
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.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
interface:
|
|
2
2
|
display_name: "Expo Skill Feedback"
|
|
3
|
-
short_description: "
|
|
4
|
-
default_prompt: "Use $expo-skill-feedback to
|
|
3
|
+
short_description: "Help Expo improve with feedback, eval candidates, and usage telemetry"
|
|
4
|
+
default_prompt: "Use $expo-skill-feedback to help Expo improve by submitting feedback, reporting an Expo task an AI agent failed at as an eval candidate, or controlling Expo skills telemetry."
|
|
@@ -478,3 +478,11 @@ Add className to component props:
|
|
|
478
478
|
```tsx
|
|
479
479
|
type Props = React.ComponentProps<typeof RNView> & { className?: string };
|
|
480
480
|
```
|
|
481
|
+
|
|
482
|
+
## Submitting Feedback
|
|
483
|
+
If you encounter errors, misleading or outdated information in this skill, report it so Expo can improve:
|
|
484
|
+
```bash
|
|
485
|
+
npx --yes submit-expo-feedback@latest --category skills --subject "expo-tailwind-setup" "<actionable feedback>"
|
|
486
|
+
```
|
|
487
|
+
Only submit when you have something specific and actionable to report. Include as much relevant context as possible.
|
|
488
|
+
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.
|
|
@@ -45,3 +45,11 @@ references/
|
|
|
45
45
|
swift-ui.md Platform-specific iOS UI: @expo/ui/swift-ui components, modifiers, RNHostView, useNativeState
|
|
46
46
|
jetpack-compose.md Platform-specific Android UI: @expo/ui/jetpack-compose components, modifiers, LazyColumn caveat, icons, useNativeState
|
|
47
47
|
```
|
|
48
|
+
|
|
49
|
+
## Submitting Feedback
|
|
50
|
+
If you encounter errors, misleading or outdated information in this skill, report it so Expo can improve:
|
|
51
|
+
```bash
|
|
52
|
+
npx --yes submit-expo-feedback@latest --category skills --subject "expo-ui" "<actionable feedback>"
|
|
53
|
+
```
|
|
54
|
+
Only submit when you have something specific and actionable to report. Include as much relevant context as possible.
|
|
55
|
+
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.
|