vybekiit 0.7.16 → 0.7.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/dist/bin.js +46 -11
  2. package/dist/global-skills/expo-native-ui/SKILL.md +3 -0
  3. package/dist/global-skills/expo-native-ui/references/controls.md +2 -0
  4. package/dist/global-skills/expo-overview/SKILL.md +110 -0
  5. package/dist/global-skills/expo-overview/agents/openai.yaml +4 -0
  6. package/dist/global-skills/expo-skill-feedback/scripts/telemetry_common.cjs +6 -6
  7. package/dist/global-skills/expo-ui/SKILL.md +52 -6
  8. package/dist/global-skills/expo-ui/references/universal.md +31 -0
  9. package/dist/global-skills/instrument-feature-flags/references/adding-feature-flag-code.md +4 -0
  10. package/dist/global-skills/instrument-feature-flags/references/android.md +4 -0
  11. package/dist/global-skills/instrument-feature-flags/references/api.md +4 -0
  12. package/dist/global-skills/instrument-feature-flags/references/best-practices.md +4 -0
  13. package/dist/global-skills/instrument-feature-flags/references/django.md +4 -0
  14. package/dist/global-skills/instrument-feature-flags/references/dotnet.md +4 -0
  15. package/dist/global-skills/instrument-feature-flags/references/elixir.md +4 -0
  16. package/dist/global-skills/instrument-feature-flags/references/flask.md +4 -0
  17. package/dist/global-skills/instrument-feature-flags/references/flutter.md +4 -0
  18. package/dist/global-skills/instrument-feature-flags/references/go.md +4 -0
  19. package/dist/global-skills/instrument-feature-flags/references/ios.md +4 -0
  20. package/dist/global-skills/instrument-feature-flags/references/java.md +4 -0
  21. package/dist/global-skills/instrument-feature-flags/references/laravel.md +4 -0
  22. package/dist/global-skills/instrument-feature-flags/references/next-js.md +4 -0
  23. package/dist/global-skills/instrument-feature-flags/references/nodejs.md +4 -0
  24. package/dist/global-skills/instrument-feature-flags/references/php.md +4 -0
  25. package/dist/global-skills/instrument-feature-flags/references/python.md +4 -0
  26. package/dist/global-skills/instrument-feature-flags/references/react-native.md +4 -0
  27. package/dist/global-skills/instrument-feature-flags/references/react.md +4 -0
  28. package/dist/global-skills/instrument-feature-flags/references/ruby-on-rails.md +4 -0
  29. package/dist/global-skills/instrument-feature-flags/references/ruby.md +4 -0
  30. package/dist/global-skills/instrument-feature-flags/references/rust.md +4 -0
  31. package/dist/global-skills/instrument-feature-flags/references/usage.md +4 -0
  32. package/dist/global-skills/instrument-feature-flags/references/web.md +4 -0
  33. package/dist/global-skills/instrument-product-analytics/references/EXAMPLE-swift.md +0 -1
  34. package/dist/global-skills/instrument-product-analytics/references/android.md +4 -0
  35. package/dist/global-skills/instrument-product-analytics/references/angular.md +4 -0
  36. package/dist/global-skills/instrument-product-analytics/references/astro.md +4 -0
  37. package/dist/global-skills/instrument-product-analytics/references/configuration.md +4 -0
  38. package/dist/global-skills/instrument-product-analytics/references/django.md +4 -0
  39. package/dist/global-skills/instrument-product-analytics/references/dotnet.md +4 -0
  40. package/dist/global-skills/instrument-product-analytics/references/elixir.md +4 -0
  41. package/dist/global-skills/instrument-product-analytics/references/flask.md +4 -0
  42. package/dist/global-skills/instrument-product-analytics/references/flutter.md +4 -0
  43. package/dist/global-skills/instrument-product-analytics/references/go.md +4 -0
  44. package/dist/global-skills/instrument-product-analytics/references/identify-users.md +4 -0
  45. package/dist/global-skills/instrument-product-analytics/references/ios.md +4 -0
  46. package/dist/global-skills/instrument-product-analytics/references/laravel.md +4 -0
  47. package/dist/global-skills/instrument-product-analytics/references/next-js.md +4 -0
  48. package/dist/global-skills/instrument-product-analytics/references/nuxt-js-3-6.md +4 -0
  49. package/dist/global-skills/instrument-product-analytics/references/nuxt-js.md +4 -0
  50. package/dist/global-skills/instrument-product-analytics/references/php.md +4 -0
  51. package/dist/global-skills/instrument-product-analytics/references/posthog-python.md +52 -5
  52. package/dist/global-skills/instrument-product-analytics/references/python.md +4 -0
  53. package/dist/global-skills/instrument-product-analytics/references/react-native.md +4 -0
  54. package/dist/global-skills/instrument-product-analytics/references/react-router-v6.md +4 -0
  55. package/dist/global-skills/instrument-product-analytics/references/react-router-v7-data-mode.md +4 -0
  56. package/dist/global-skills/instrument-product-analytics/references/react-router-v7-declarative-mode.md +4 -0
  57. package/dist/global-skills/instrument-product-analytics/references/react-router-v7-framework-mode.md +4 -0
  58. package/dist/global-skills/instrument-product-analytics/references/ruby-on-rails.md +4 -0
  59. package/dist/global-skills/instrument-product-analytics/references/ruby.md +4 -0
  60. package/dist/global-skills/instrument-product-analytics/references/svelte.md +4 -0
  61. package/dist/global-skills/instrument-product-analytics/references/tanstack-start.md +4 -0
  62. package/dist/global-skills/instrument-product-analytics/references/usage.md +4 -0
  63. package/dist/global-skills/instrument-product-analytics/references/vue-js.md +4 -0
  64. package/dist/global-skills/manifest.json +2 -1
  65. package/dist/global-skills/neon/SKILL.md +2 -2
  66. package/dist/global-skills/neon-ai-gateway/SKILL.md +13 -13
  67. package/dist/global-skills/neon-functions/SKILL.md +3 -3
  68. package/dist/global-skills/neon-functions/references/ai-sdk.md +1 -1
  69. package/dist/global-skills/neon-object-storage/SKILL.md +1 -1
  70. package/dist/global-skills/resend/SKILL.md +1 -1
  71. package/dist/global-skills/resend/references/automations.md +10 -1
  72. package/package.json +8 -8
package/dist/bin.js CHANGED
@@ -11140,9 +11140,10 @@ var defaultStartDetached = (cwd, bin, args) => {
11140
11140
  return false;
11141
11141
  }
11142
11142
  };
11143
+ var claudeTerminalCommand = (appPath, prompt) => `cd ${JSON.stringify(appPath)} && claude ${JSON.stringify(prompt)}; exec "\${SHELL:-/bin/zsh}" -l`;
11143
11144
  var openClaudeWithSeed = async (appPath, prompt, platform = process7.platform) => {
11144
11145
  if (platform === "darwin") {
11145
- const shellCommand = `cd ${JSON.stringify(appPath)} && claude ${JSON.stringify(prompt)}`;
11146
+ const shellCommand = claudeTerminalCommand(appPath, prompt);
11146
11147
  const osa = makeExec("osascript");
11147
11148
  const result = await osa([
11148
11149
  "-e",
@@ -11190,7 +11191,7 @@ var defaultPnpmCommand = async () => {
11190
11191
  return null;
11191
11192
  };
11192
11193
  var wait = async (milliseconds) => await new Promise((resolve19) => setTimeout(resolve19, milliseconds));
11193
- var defaultWaitForPreview = async (url) => {
11194
+ var waitForPreview = async (url) => {
11194
11195
  const attemptPreview = async (remainingAttempts) => {
11195
11196
  try {
11196
11197
  const response = await fetch(url, { redirect: "follow" });
@@ -11242,7 +11243,7 @@ var defaultDeps = () => ({
11242
11243
  runCommand: defaultRunCommand,
11243
11244
  startDetached: defaultStartDetached,
11244
11245
  openClaude: (appPath, prompt) => openClaudeWithSeed(appPath, prompt, process7.platform),
11245
- waitForPreview: defaultWaitForPreview,
11246
+ waitForPreview,
11246
11247
  openBrowser: defaultOpenBrowser,
11247
11248
  prepareProjectTools: async (appPath) => {
11248
11249
  try {
@@ -11429,6 +11430,7 @@ Creating your first web app at ${appPath}\u2026
11429
11430
  // src/commands/createUiLibrary.ts
11430
11431
  var DEFAULT_UI_LIBRARY_DIR_NAME = "vybekiit-ui-library";
11431
11432
  var UI_LIBRARY_GALLERY_URL = "https://ui.vybekiit.com";
11433
+ var UI_LIBRARY_LOCAL_URL = "http://127.0.0.1:3000/en";
11432
11434
  var UI_LIBRARY_SEED_PROMPT = `I opened my VybeKiit UI library workspace.
11433
11435
 
11434
11436
  Work ONLY in this folder (the kit workspace). Do not claim the UI library is missing.
@@ -11552,6 +11554,7 @@ var defaultDeps2 = () => ({
11552
11554
  isEmptyDir: defaultIsEmptyDir2,
11553
11555
  runCommand: defaultRunCommand2,
11554
11556
  startDetached: defaultStartDetached2,
11557
+ waitForPreview,
11555
11558
  openClaude: (appPath, prompt) => openClaudeWithSeed(appPath, prompt, process8.platform),
11556
11559
  openUrl: defaultOpenUrl,
11557
11560
  pnpmCommand: defaultPnpmCommand2,
@@ -11589,7 +11592,11 @@ var formatCreateUiLibraryLines = (result) => {
11589
11592
  lines.push(" \u2022 Build packages: pnpm build:packages");
11590
11593
  }
11591
11594
  if (result.devStarted) {
11592
- lines.push(" \u2022 Local app preview starting (http://localhost:3000)");
11595
+ if (result.localPreviewOpened) {
11596
+ lines.push(` \u2022 Local app opened: ${UI_LIBRARY_LOCAL_URL}`);
11597
+ } else {
11598
+ lines.push(` \u2022 Open your local app: ${UI_LIBRARY_LOCAL_URL}`);
11599
+ }
11593
11600
  }
11594
11601
  if (result.galleryOpened) {
11595
11602
  lines.push(` \u2022 UI gallery opened: ${UI_LIBRARY_GALLERY_URL}`);
@@ -11627,6 +11634,8 @@ var runCreateUiLibrary = async (args = [], deps = defaultDeps2()) => {
11627
11634
  depsInstalled: false,
11628
11635
  packagesBuilt: false,
11629
11636
  devStarted: false,
11637
+ previewReady: false,
11638
+ localPreviewOpened: false,
11630
11639
  galleryOpened: false,
11631
11640
  claudeOpened: false
11632
11641
  };
@@ -11654,6 +11663,8 @@ Creating UI library kit workspace at ${appPath}\u2026
11654
11663
  depsInstalled: false,
11655
11664
  packagesBuilt: false,
11656
11665
  devStarted: false,
11666
+ previewReady: false,
11667
+ localPreviewOpened: false,
11657
11668
  galleryOpened: false,
11658
11669
  claudeOpened: false
11659
11670
  };
@@ -11679,6 +11690,8 @@ Creating UI library kit workspace at ${appPath}\u2026
11679
11690
  devStarted = deps.startDetached(appPath, pnpmBin, [...pnpmPrefix, "dev"]);
11680
11691
  }
11681
11692
  }
11693
+ const previewReady = devStarted ? await deps.waitForPreview(UI_LIBRARY_LOCAL_URL) : false;
11694
+ const localPreviewOpened = previewReady ? await deps.openUrl(UI_LIBRARY_LOCAL_URL) : false;
11682
11695
  let galleryOpened = false;
11683
11696
  if (inputs.openGallery) {
11684
11697
  process8.stdout.write(`
@@ -11697,6 +11710,8 @@ Opening UI gallery: ${UI_LIBRARY_GALLERY_URL}
11697
11710
  depsInstalled,
11698
11711
  packagesBuilt,
11699
11712
  devStarted,
11713
+ previewReady,
11714
+ localPreviewOpened,
11700
11715
  galleryOpened,
11701
11716
  claudeOpened
11702
11717
  };
@@ -26488,22 +26503,42 @@ var tools = [
26488
26503
  }
26489
26504
  ];
26490
26505
  var automationProjectRoot2 = () => process.env.VYBEKIIT_PROJECT_ROOT || process.cwd();
26491
- var uiCatalogIndexPath = () => {
26506
+ var uiCatalogIndexPaths = () => {
26492
26507
  const configuredCatalogPath = process.env.VYBEKIIT_UI_CATALOG_PATH;
26493
26508
  if (configuredCatalogPath) {
26494
- return configuredCatalogPath;
26509
+ return [configuredCatalogPath];
26495
26510
  }
26496
- return join35(automationProjectRoot2(), ".vybekiit/agent/ui-catalog-index.json");
26511
+ const projectRoot = automationProjectRoot2();
26512
+ return [
26513
+ join35(projectRoot, ".vybekiit/agent/ui-catalog-index.json"),
26514
+ join35(projectRoot, "templates/web/.vybekiit/agent/ui-catalog-index.json")
26515
+ ];
26497
26516
  };
26498
26517
  var cachedCatalog;
26499
26518
  var loadUiCatalog = async () => {
26500
- const catalogPath = uiCatalogIndexPath();
26501
- if (cachedCatalog !== void 0 && cachedCatalog.path === catalogPath) {
26519
+ const catalogPaths = uiCatalogIndexPaths();
26520
+ const cached = catalogPaths.find((candidatePath) => cachedCatalog?.path === candidatePath);
26521
+ if (cached !== void 0 && cachedCatalog !== void 0) {
26502
26522
  return cachedCatalog.catalog;
26503
26523
  }
26524
+ const catalogReads = await Promise.allSettled(
26525
+ catalogPaths.map((candidatePath) => readFile18(candidatePath, "utf8"))
26526
+ );
26527
+ const availableIndex = catalogReads.findIndex(
26528
+ (candidateRead) => candidateRead.status === "fulfilled"
26529
+ );
26530
+ if (availableIndex === -1) {
26531
+ const [firstFailure] = catalogReads;
26532
+ const reason = firstFailure?.status === "rejected" ? firstFailure.reason : "Catalog not found";
26533
+ return { error: reason instanceof Error ? reason.message : String(reason) };
26534
+ }
26535
+ const catalogRead = catalogReads[availableIndex];
26536
+ const catalogPath = catalogPaths[availableIndex];
26537
+ if (catalogRead?.status !== "fulfilled" || catalogPath === void 0) {
26538
+ return { error: "Catalog not found" };
26539
+ }
26504
26540
  try {
26505
- const json = await readFile18(catalogPath, "utf8");
26506
- const catalog = loadCatalog(json);
26541
+ const catalog = loadCatalog(catalogRead.value);
26507
26542
  cachedCatalog = { path: catalogPath, catalog };
26508
26543
  return catalog;
26509
26544
  } catch (error) {
@@ -9,6 +9,8 @@ license: MIT
9
9
 
10
10
  For routes, links, stacks, tabs, modals, sheets, and headers, use the `expo-router` skill.
11
11
 
12
+ > **Before picking any UI component, check `expo-ui` first.** `@expo/ui` provides native equivalents — BottomSheet, Button, Picker, Slider, Menu, Section, Switch, SegmentedControl, and more — rendered as real SwiftUI on iOS and Jetpack Compose on Android, available in Expo Go on SDK 56+ with no custom build. Load the **`expo-ui`** skill to find the right component before falling back to React Native built-ins or community libraries. This skill (`expo-native-ui`) covers the surrounding structure: Expo Router navigation, layout, styling, and animations.
13
+
12
14
  ## References
13
15
 
14
16
  Consult these resources as needed:
@@ -65,6 +67,7 @@ Expo Go supports a huge range of features out of the box:
65
67
 
66
68
  ## Library Preferences
67
69
 
70
+ - **For any sheet, picker, slider, toggle, menu, or grouped-form section: use `@expo/ui` (see `expo-ui` skill) before reaching for a React Native built-in or community library** — it renders native SwiftUI/Compose and works in Expo Go on SDK 56+. For grouped/settings-style rows (short, fixed-length), use `@expo/ui`'s `List` + `ListItem`. For large or unknown-length scrolling lists (feeds, search results, catalogs), use `FlatList` or `FlashList` — `@expo/ui`'s `List` is not virtualized.
68
71
  - Never use modules removed from React Native such as Picker, WebView, SafeAreaView, or AsyncStorage
69
72
  - Never use legacy expo-permissions
70
73
  - `expo-audio` not `expo-av`
@@ -2,6 +2,8 @@
2
2
 
3
3
  Native iOS controls provide built-in haptics, accessibility, and platform-appropriate styling.
4
4
 
5
+ > **Prefer `@expo/ui` for these controls.** Its `Slider`, `Switch`, `DateTimePicker`, `Menu`, and segmented pickers render as real SwiftUI / Jetpack Compose and follow platform design conventions automatically — recommended over the React Native controls below. See the **`expo-ui`** skill; use the React Native controls below as a fallback when you're not using `@expo/ui`.
6
+
5
7
  ## Switch
6
8
 
7
9
  Use for binary on/off settings. Has built-in haptics.
@@ -0,0 +1,110 @@
1
+ ---
2
+ name: expo-overview
3
+ description: "Framework (OSS). Entry point and router for every Expo or EAS task. Load this skill first — before writing code and before choosing another expo-* / eas-* skill — when the request, PRD, or spec mentions Expo, EAS, Expo Go, or an expo-* package, or the project has an `expo` dependency in `package.json`. Within that gate it also covers app specs and designs to implement (tabs, stacks, maps, lists, navigation, building from a screenshot), and phrasings like 'implement a mobile app', 'make my app look native', 'add navigation', 'fetch some data', 'upgrade my SDK', 'add Expo to my existing native app', 'ship to the App Store', or 'I'm new to Expo, where do I start'. A fully specified request (SDK pinned, libraries named, layout given) still routes through here — the shared setup rules still apply. Do NOT load it when neither signal is present: a bare React Native project with no `expo` dependency is not Expo work. Detects the real goal, routes to the right expo-* / eas-* skill, and owns the shared setup rules."
4
+ version: 1.0.0
5
+ license: MIT
6
+ ---
7
+
8
+ # `expo-overview` — router & shared rules for Expo / EAS
9
+
10
+ ## Start Here — read before doing anything
11
+
12
+ **Do not guess the skill from project files alone.** Many Expo goals look similar from
13
+ the filesystem but need different skills.
14
+
15
+ 1. **Confirm this is Expo work** — the request mentions Expo, or `package.json` has an
16
+ `expo` dependency. If neither holds, stop: this skill does not apply. A bare React
17
+ Native project with no `expo` dependency is not Expo work.
18
+ 2. **Read the user's goal** — what outcome do they want, in plain terms?
19
+ 3. **Classify it** using the Skill Map below, translating casual phrasing to a goal.
20
+ 4. **Confirm intent** if ambiguous ("Sounds like you want to ship to the stores — that's
21
+ `eas-app-stores`. Right?"), then load that skill's `SKILL.md` and follow it.
22
+ 5. **Trust the leaf skill** — it has its own detection logic and steps. Don't improvise.
23
+
24
+ ## Skill Map (by goal)
25
+
26
+ Match the goal to a category, then the skill, then load that leaf's `SKILL.md`.
27
+
28
+ **Build the app**
29
+ - `expo-project-structure` — folder layout for a **new** Expo Router project: where screens, components, and config live (never restructure an existing app to match)
30
+ - `expo-native-ui` — screens, styling, semantic colors, native controls, SF Symbols, media, animations, layout
31
+ - `expo-router` — navigation: file-based routes, tabs / stacks / modals / sheets, links, headers
32
+ - `expo-animation` — motion and gestures: Reanimated worklets, Gesture Handler, screen transitions, sheet and press feedback, haptics, and fixing animation that stutters on device
33
+ - `expo-ui` — native UI components via `@expo/ui`: BottomSheet, Picker, Slider, Switch, Menu, Button, FieldGroup (grouped form sections), List / ListItem, and more — real SwiftUI on iOS, Jetpack Compose on Android. The universal layer needs SDK 56+ and runs in Expo Go; the drop-in replacements (`@gorhom/bottom-sheet`, `datetimepicker`, …) and platform-specific layers also exist on SDK 55.
34
+ - `expo-design-system` — one visual source of truth: design tokens (color, spacing, typography, radius, shadow, motion), reusable component conventions, and audits for drift (hardcoded colors, spacing, fonts)
35
+ - `expo-tailwind-setup` — Tailwind / NativeWind styling
36
+ - `expo-data-fetching` — network requests, React Query / SWR, caching, offline, route loaders
37
+ - `expo-dom` — run web code or reuse a web library inside native
38
+ - `expo-web-to-native` — migrate an existing web / React app to a native iOS / Android app
39
+
40
+ > **Component selection rule:** whenever you need a UI component (list rows, bottom sheets, pickers, sliders, menus, buttons, segmented controls, toggles), **consult `expo-ui` first** to check whether `@expo/ui` has a native equivalent before reaching for a React Native built-in or a community library. Native `@expo/ui` components give the best platform fit, and on SDK 56+ the universal ones run in Expo Go with no custom build. Load `expo-ui` alongside `expo-native-ui` for any app that renders lists, detail sheets, or form controls. One exception: `@expo/ui` `List` renders native grouped rows (an iOS Settings screen), **not** a virtualized list — use `FlatList` / `FlashList` for large datasets.
41
+
42
+ **Ship & operate**
43
+ - `eas-app-stores` — build and submit to the App Store / Play Store / TestFlight, versions, and store metadata
44
+ - `eas-hosting` — deploy the web bundle to EAS Hosting; also author Expo Router API routes (`+api.ts` handlers) and their environments / domains
45
+ - `eas-workflows` — EAS Workflow YAML and CI/CD pipelines
46
+ - `eas-simulator` — run and drive the app on a remote iOS / Android simulator on EAS cloud
47
+ - `expo-dev-client` — custom development builds
48
+ - `eas-update-insights` — OTA update health: crash rate, adoption, payload size
49
+ - `eas-observe` — startup / launch / TTI performance with EAS Observe
50
+
51
+ **Extend natively**
52
+ - `expo-module` — native modules and views (Swift / Kotlin) with the Expo Modules API
53
+ - `expo-brownfield` — embed Expo / React Native in an existing native app
54
+ - `expo-app-clip` — iOS App Clip target (AASA, smart app banner)
55
+
56
+ **Maintain & learn**
57
+ - `expo-upgrade` — upgrade the Expo SDK and fix dependency conflicts
58
+ - `expo-examples` — canonical, version-matched integration examples (Stripe, Clerk, Supabase, …)
59
+ - `expo-skill-feedback` — send feedback on an Expo skill or on Expo itself; enable / disable the anonymous usage telemetry
60
+
61
+ ### Translating vague asks
62
+
63
+ Some everyday phrasings don't obviously map to a skill name — translate before routing:
64
+
65
+ - "Make it look native" → grouped controls / settings forms = `expo-ui`; screens, styling, animations = `expo-native-ui`; navigation = `expo-router`.
66
+ - "Make the screens consistent" / "clean up the styling" / "set up a theme or design tokens" → `expo-design-system`.
67
+ - "Ship it" / "get an .ipa or .apk" / "release to the stores" → `eas-app-stores` (build + submit, TestFlight, versions, store metadata).
68
+ - "I'm new / where do I start" → scaffold first (see Shared setup rules), then route by goal.
69
+
70
+ ## Shared setup rules
71
+
72
+ These apply across every Expo skill, so handle them here once instead of repeating them
73
+ in each leaf.
74
+
75
+ - **No Expo project yet?** Start one the standard way before routing to a feature skill:
76
+ `npx create-expo-app@latest`, laying out folders per `expo-project-structure`. Then
77
+ classify the user's goal and route.
78
+ - **Detect the SDK version** before giving version-specific advice: read the `expo`
79
+ version in `package.json` (and `app.json` / `app.config.{js,ts}`). Many APIs and
80
+ defaults differ by SDK.
81
+ - **Read the docs for that SDK, not `latest`.** Use the version-pinned URL, e.g.
82
+ `https://docs.expo.dev/versions/v56.0.0/sdk/ui/` on SDK 56 instead of
83
+ `https://docs.expo.dev/versions/latest/sdk/ui/` — the `latest` pages track the newest
84
+ SDK and can document APIs the project does not have yet.
85
+ - **Moving to a newer SDK is its own task** — load `expo-upgrade` instead of bumping
86
+ versions by hand.
87
+ - **Managed vs. bare/prebuild**: the presence of committed `ios/` and `android/`
88
+ directories means native projects exist (prebuild or bare). Config-plugin and
89
+ native-setup steps differ — note which one the project is in.
90
+ - **Install packages with `npx expo install <pkg>`**, not raw `npm`/`yarn`/`pnpm add`,
91
+ so versions stay compatible with the project's SDK.
92
+ - **EAS auth & linking** (only needed for build/submit/update/observe/workflows): check
93
+ login with `eas whoami`, log in with `eas login`. A project is linked when
94
+ `extra.eas.projectId` exists in the app config; create it with `eas init` if missing.
95
+
96
+ ## When to skip the router hop
97
+
98
+ - Only when the user explicitly named a specific `expo-*` / `eas-*` skill → load that
99
+ skill directly.
100
+ - A fully-specified task (SDK version pinned, file layout given, libraries named) is
101
+ **not** a reason to skip: the shared rules above still apply — check them, then route
102
+ to the matching leaf skill.
103
+
104
+ ## Submitting Feedback
105
+ If you encounter errors, misleading or outdated information in this skill, report it so Expo can improve:
106
+ ```bash
107
+ npx --yes submit-expo-feedback@latest --category skills --subject "expo-overview" "<actionable feedback>"
108
+ ```
109
+ Only submit when you have something specific and actionable to report. Include as much relevant context as possible.
110
+ 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 Overview"
3
+ short_description: "Entry point and router for Expo / EAS tasks: load first when the request mentions Expo or the project has an expo dependency, classify the goal, route to the right expo-* / eas-* skill, and apply shared setup rules"
4
+ default_prompt: "Use $expo-overview first when a task mentions Expo, EAS, or an expo-* package, or the project has an `expo` dependency in package.json — even when the stack or SDK version is already fully specified. Classify the user's goal, route to the right expo-* / eas-* skill, and apply the shared environment and setup rules the other Expo skills rely on."
@@ -13,10 +13,9 @@ const path = require("path");
13
13
 
14
14
  const POSTHOG_HOST = "https://us.i.posthog.com";
15
15
 
16
- // PostHog project API key. Supply it explicitly when telemetry is enabled with
17
- // EXPO_SKILLS_POSTHOG_KEY; the bundled skill never carries a live project token.
18
- // NOTE: never put a PostHog *personal* API key (phx_...) here — those are secret.
19
- const POSTHOG_PROJECT_API_KEY = process.env.EXPO_SKILLS_POSTHOG_KEY || "";
16
+ // Telemetry stays disabled unless the buyer explicitly enables it and supplies
17
+ // a project ingestion key. Never bundle a project or personal key in the kit.
18
+ const POSTHOG_PROJECT_API_KEY = process.env.EXPO_SKILLS_POSTHOG_KEY;
20
19
 
21
20
  const SOURCE = "expo-skills";
22
21
  const INSTALLATION_ID_PATH = path.join(os.homedir(), ".expo-skills", "installation-id");
@@ -77,10 +76,11 @@ function telemetryActive() {
77
76
  return DEFAULT_ON;
78
77
  }
79
78
 
80
- // Keep telemetry inert until the user supplies a project token explicitly.
79
+ // A real key ships in this file, so this check passes by default. This guard only
80
+ // makes the scripts inert if someone strips the key (e.g. a fork or private build).
81
81
  function telemetryConfigured() {
82
82
  const key = String(POSTHOG_PROJECT_API_KEY || "").trim();
83
- return key.length > 0;
83
+ return key.length > 0 && key !== "phc_REPLACE_ME";
84
84
  }
85
85
 
86
86
  // Best-effort agent-harness label for the event (default when --agent-harness isn't passed).
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: expo-ui
3
- description: "Framework (OSS). Build native UI with the @expo/ui package: real SwiftUI on iOS and Jetpack Compose on Android rendered from React in an Expo or React Native app. Covers universal cross-platform components (Host, Column, Row, Button, Text, List, and more imported from @expo/ui), drop-in replacements for popular React Native community libraries (BottomSheet, DateTimePicker, Slider, Menu, etc.), and platform-specific SwiftUI (@expo/ui/swift-ui, iOS only) and Jetpack Compose (@expo/ui/jetpack-compose, Android only) trees and modifiers. Use when adding or reviewing @expo/ui Host/RNHostView trees, building native-feeling UI where standard React Native components fall short (grouped settings forms with toggles, sections, menus, sheets, pickers, sliders), choosing between universal and platform-specific components, or replacing an RN community UI library with a native @expo/ui equivalent. Not for custom native modules, Expo Router navigation, Reanimated, or data fetching."
3
+ description: "Framework (OSS). Build native UI with the @expo/ui package: real SwiftUI on iOS and Jetpack Compose on Android. Default to @expo/ui for sheets (BottomSheet), pickers, sliders, toggles, menus, and grouped-form sections do NOT reach for Reanimated, @gorhom/bottom-sheet, or RN built-in Picker/Switch; use @expo/ui instead. Fall back to RN built-ins only when @expo/ui is missing the component. NOTE: @expo/ui List renders native grouped rows like an iOS Settings screen it is NOT a virtualized list; use FlatList/FlashList for large datasets. Covers universal components (Host, Column, Row, Button, Text, List, BottomSheet, FieldGroup, Switch, Slider, Picker, Menu), drop-in replacements for RN community libraries, and platform-specific SwiftUI/Jetpack Compose trees. Not for Expo Router navigation, Reanimated, or data fetching."
4
4
  version: 1.0.0
5
5
  license: MIT
6
6
  allowed-tools: "Bash(node *expo-ui/scripts/list-components.js *)"
@@ -8,9 +8,9 @@ allowed-tools: "Bash(node *expo-ui/scripts/list-components.js *)"
8
8
 
9
9
  # Expo UI (`@expo/ui`)
10
10
 
11
- `@expo/ui` renders real native UI from React: SwiftUI on iOS, Jetpack Compose on Android. Start with its universal components (one tree for iOS, Android, and web) and drop to platform-specific SwiftUI/Jetpack Compose only when the universal layer falls short. It also ships drop-in replacements for migrating off RN community UI libraries.
11
+ `@expo/ui` renders real native UI from React: SwiftUI on iOS, Jetpack Compose on Android. It also ships drop-in replacements for migrating off RN community UI libraries.
12
12
 
13
- > These instructions track the latest Expo SDK. The **universal** layer requires **SDK 56+**. Drop-in replacements and the platform-specific layers also exist on SDK 55. For component details on a specific SDK, refer to the Expo UI docs for that version.
13
+ > These instructions track the latest Expo SDK. The **universal** layer requires **SDK 56+** and works in Expo Go — no custom build needed. Drop-in replacements and the platform-specific layers also exist on SDK 55. For component details on a specific SDK, refer to the Expo UI docs for that version.
14
14
 
15
15
  ## Installation
16
16
 
@@ -18,11 +18,57 @@ allowed-tools: "Bash(node *expo-ui/scripts/list-components.js *)"
18
18
  npx expo install @expo/ui
19
19
  ```
20
20
 
21
- On SDK 56, `@expo/ui` works in Expo Go, so `npx expo start` runs it directly — no custom build required. On older SDKs, build a dev client first (`npx expo run:ios` / `npx expo run:android`).
22
-
23
21
  Every `@expo/ui` tree — universal or platform-specific — must be wrapped in `Host`.
24
22
 
25
- ## Choosing an approach (read this first)
23
+ ## Use @expo/ui by default don't reach for RN alternatives first
24
+
25
+ **Before using Reanimated, `@gorhom/bottom-sheet`, React Native's built-in `Switch`/`Picker`, or any community UI library for the items below, use `@expo/ui` instead.** Only fall back to RN built-ins when `@expo/ui` is missing the component.
26
+
27
+ | Need | Use |
28
+ |------|-----|
29
+ | Slide-up sheet / bottom sheet | `BottomSheet` from `@expo/ui` — **not** Reanimated or `@gorhom/bottom-sheet` |
30
+ | Grouped native list rows (settings/form-style) | `List` + `ListItem` from `@expo/ui` — **not** `FlatList` (see note below) |
31
+ | Toggle | `Switch` from `@expo/ui` |
32
+ | Slider | `Slider` from `@expo/ui` |
33
+ | Date/time picker | `@expo/ui/community/datetimepicker` |
34
+ | Menu | `Menu` from `@expo/ui` |
35
+ | Form section with label | `FieldGroup` from `@expo/ui` |
36
+ | Collapsible section | `Collapsible` from `@expo/ui` |
37
+
38
+ > **`List` is NOT a virtualized scrolling list.** It renders native grouped table rows — the visual look of an iOS Settings screen or a form section, with disclosure indicators and native row styling. Each `ListItem` is a native node on the JS thread; rows are not recycled. For any list with large or unknown-length data (feeds, search results, catalogs), use **`FlatList`** or **`FlashList`** instead. `List` is the right choice for short, fixed-length groups: a settings screen, a detail panel's rows, a fixed menu.
39
+
40
+ **`BottomSheet` example** (use this for map pin details, action sheets, detail panels — not Reanimated):
41
+
42
+ ```tsx
43
+ import { Host, BottomSheet, Column, Text } from '@expo/ui';
44
+ import { useState } from 'react';
45
+
46
+ export default function MapScreen() {
47
+ const [isOpen, setIsOpen] = useState(false);
48
+
49
+ return (
50
+ <View style={{ flex: 1 }}>
51
+ <MapView onMarkerPress={() => setIsOpen(true)} />
52
+ <Host>
53
+ <BottomSheet
54
+ isPresented={isOpen}
55
+ onDismiss={() => setIsOpen(false)}
56
+ snapPoints={['half', 'full']}
57
+ >
58
+ <Column>
59
+ <Text>Café name</Text>
60
+ <Text>Address</Text>
61
+ </Column>
62
+ </BottomSheet>
63
+ </Host>
64
+ </View>
65
+ );
66
+ }
67
+ ```
68
+
69
+ `BottomSheet` uses `isPresented`/`onDismiss` — **not** `isOpened`, `isOpen`, `onIsOpenedChange`, or `onChange` (those are `@gorhom/bottom-sheet` props and will silently do nothing). `snapPoints` accepts `'half'`, `'full'`, `{ fraction: 0.5 }`, or `{ height: 400 }` and is optional (auto-sizes to content when omitted).
70
+
71
+ ## Choosing an approach
26
72
 
27
73
  Work down this list and stop at the first layer that meets the need:
28
74
 
@@ -61,6 +61,37 @@ export default function MyInput() {
61
61
 
62
62
  Docs — https://docs.expo.dev/versions/latest/sdk/ui/universal/textinput/index.md
63
63
 
64
+ ## BottomSheet
65
+
66
+ `BottomSheet` is a universal slide-up sheet. Control it with `isPresented` / `onDismiss` — **not** `isOpen`, `isOpened`, `onIsOpenedChange`, or `onChange` (those belong to other sheet APIs; the universal `BottomSheet` does not accept them). `snapPoints` is optional and accepts `'half'`, `'full'`, `{ fraction }`, or `{ height }`; when omitted the sheet auto-sizes to its content.
67
+
68
+ ```tsx
69
+ import { Host, BottomSheet, Column, Button, Text } from '@expo/ui';
70
+ import { useState } from 'react';
71
+
72
+ export default function MapScreen() {
73
+ const [isOpen, setIsOpen] = useState(false);
74
+
75
+ return (
76
+ <Host>
77
+ <Button onPress={() => setIsOpen(true)}>Show details</Button>
78
+ <BottomSheet
79
+ isPresented={isOpen}
80
+ onDismiss={() => setIsOpen(false)}
81
+ snapPoints={['half', 'full']}
82
+ >
83
+ <Column>
84
+ <Text>Sheet content</Text>
85
+ <Button onPress={() => setIsOpen(false)}>Close</Button>
86
+ </Column>
87
+ </BottomSheet>
88
+ </Host>
89
+ );
90
+ }
91
+ ```
92
+
93
+ > **Don't confuse the universal `BottomSheet` with the drop-in `@gorhom/bottom-sheet` replacement** (`@expo/ui/community/bottom-sheet`). They are different components with different APIs. Use the universal one when building new UI; use the drop-in only when migrating an existing `@gorhom/bottom-sheet` integration. See `./drop-in-replacements.md`.
94
+
64
95
  ## Confirming the API
65
96
 
66
97
  `@expo/ui` is versioned with the Expo SDK (e.g. `56.0.x` for SDK 56) and its API can change between SDK versions, so the **installed package's TypeScript types (`.d.ts`) are the most reliable source of truth** — they match the version in your project, while the docs track latest. Read the relevant component's `.d.ts` from the installed `@expo/ui` package in `node_modules`. Use the docs as the human-readable reference:
@@ -3575,6 +3575,10 @@ The list of properties that this overrides:
3575
3575
  6. `$geoip_postal_code`
3576
3576
  7. `$geoip_time_zone`
3577
3577
 
3578
+ ### Still have questions?
3579
+
3580
+ Ask PostHog AI
3581
+
3578
3582
  ### Was this page useful?
3579
3583
 
3580
3584
  HelpfulCould be better
@@ -143,6 +143,10 @@ Copy page
143
143
  | [How to do a phased rollout](/tutorials/phased-rollout.md) | Gradually roll out features to minimize risk |
144
144
  | [More tutorials](/docs/feature-flags/tutorials.md) | Other real-world examples and use cases |
145
145
 
146
+ ### Still have questions?
147
+
148
+ Ask PostHog AI
149
+
146
150
  ### Was this page useful?
147
151
 
148
152
  HelpfulCould be better
@@ -191,6 +191,10 @@ Copy page
191
191
  | [How to do a phased rollout](/tutorials/phased-rollout.md) | Gradually roll out features to minimize risk |
192
192
  | [More tutorials](/docs/feature-flags/tutorials.md) | Other real-world examples and use cases |
193
193
 
194
+ ### Still have questions?
195
+
196
+ Ask PostHog AI
197
+
194
198
  ### Was this page useful?
195
199
 
196
200
  HelpfulCould be better
@@ -228,6 +228,10 @@ Stale flags are the most common source of unnecessary cost. Beyond cleaning up f
228
228
  - [Local evaluation](/docs/feature-flags/local-evaluation.md) – server-side evaluation for explicit input control
229
229
  - [Bootstrapping](/docs/feature-flags/bootstrapping.md) – having flag values before the page renders
230
230
 
231
+ ### Still have questions?
232
+
233
+ Ask PostHog AI
234
+
231
235
  ### Was this page useful?
232
236
 
233
237
  HelpfulCould be better
@@ -291,6 +291,10 @@ Everything on this page works the same way on `6.9.3`. Event capture, the contex
291
291
 
292
292
  Later `7.x` releases add what the 6.x line does not receive, such as the Celery integration, tracing header sanitization, and `set_context_device_id`. They also changed the middleware's own captured properties: `7.x` sends the request IP as `$ip`, where `6.9.3` sends it as `$ip_address`, and `7.x` additionally captures `$request_path`, `$raw_user_agent`, and the authenticated user's `email`.
293
293
 
294
+ ### Still have questions?
295
+
296
+ Ask PostHog AI
297
+
294
298
  ### Was this page useful?
295
299
 
296
300
  HelpfulCould be better
@@ -764,6 +764,10 @@ By default, the library buffers events before sending them to the `/batch` endpo
764
764
 
765
765
  To avoid this, call `await posthog.FlushAsync()` after processing every request by adding it as a middleware to your server. This allows `posthog.Capture()` to remain asynchronous for better performance.
766
766
 
767
+ ### Still have questions?
768
+
769
+ Ask PostHog AI
770
+
767
771
  ### Was this page useful?
768
772
 
769
773
  HelpfulCould be better
@@ -44,6 +44,10 @@ Optionally, you might want to enable the [Plug integration](https://hexdocs.pm/p
44
44
 
45
45
  For a test environment, you can pass in `test_mode: true` value to the config. This causes events to be dropped instead of sent to PostHog.
46
46
 
47
+ ### Still have questions?
48
+
49
+ Ask PostHog AI
50
+
47
51
  ### Was this page useful?
48
52
 
49
53
  HelpfulCould be better
@@ -138,6 +138,10 @@ Everything on this page works the same way on `6.9.3`. Event capture, the contex
138
138
 
139
139
  Later `7.x` releases add what the 6.x line does not receive, such as the Celery integration, tracing header sanitization, and `set_context_device_id`. They also changed the middleware's own captured properties: `7.x` sends the request IP as `$ip`, where `6.9.3` sends it as `$ip_address`, and `7.x` additionally captures `$request_path`, `$raw_user_agent`, and the authenticated user's `email`.
140
140
 
141
+ ### Still have questions?
142
+
143
+ Ask PostHog AI
144
+
141
145
  ### Was this page useful?
142
146
 
143
147
  HelpfulCould be better
@@ -209,6 +209,10 @@ Copy page
209
209
  | [How to do a phased rollout](/tutorials/phased-rollout.md) | Gradually roll out features to minimize risk |
210
210
  | [More tutorials](/docs/feature-flags/tutorials.md) | Other real-world examples and use cases |
211
211
 
212
+ ### Still have questions?
213
+
214
+ Ask PostHog AI
215
+
212
216
  ### Was this page useful?
213
217
 
214
218
  HelpfulCould be better
@@ -205,6 +205,10 @@ Copy page
205
205
  | [How to do a phased rollout](/tutorials/phased-rollout.md) | Gradually roll out features to minimize risk |
206
206
  | [More tutorials](/docs/feature-flags/tutorials.md) | Other real-world examples and use cases |
207
207
 
208
+ ### Still have questions?
209
+
210
+ Ask PostHog AI
211
+
208
212
  ### Was this page useful?
209
213
 
210
214
  HelpfulCould be better
@@ -143,6 +143,10 @@ Copy page
143
143
  | [How to do a phased rollout](/tutorials/phased-rollout.md) | Gradually roll out features to minimize risk |
144
144
  | [More tutorials](/docs/feature-flags/tutorials.md) | Other real-world examples and use cases |
145
145
 
146
+ ### Still have questions?
147
+
148
+ Ask PostHog AI
149
+
146
150
  ### Was this page useful?
147
151
 
148
152
  HelpfulCould be better
@@ -91,6 +91,10 @@ PostHogConfig config = PostHogConfig
91
91
  .build();
92
92
  ```
93
93
 
94
+ ### Still have questions?
95
+
96
+ Ask PostHog AI
97
+
94
98
  ### Was this page useful?
95
99
 
96
100
  HelpfulCould be better
@@ -167,6 +167,10 @@ PostHog::init(
167
167
 
168
168
  See the [PHP SDK docs](/docs/libraries/php.md) for usage examples and the full API reference.
169
169
 
170
+ ### Still have questions?
171
+
172
+ Ask PostHog AI
173
+
170
174
  ### Was this page useful?
171
175
 
172
176
  HelpfulCould be better
@@ -444,6 +444,10 @@ To improve the reliability of client-side tracking and make requests less likely
444
444
  - [How to set up Next.js pages router analytics, feature flags, and more](/tutorials/nextjs-pages-analytics.md)
445
445
  - [How to set up Next.js A/B tests](/tutorials/nextjs-ab-tests.md)
446
446
 
447
+ ### Still have questions?
448
+
449
+ Ask PostHog AI
450
+
447
451
  ### Was this page useful?
448
452
 
449
453
  HelpfulCould be better
@@ -213,6 +213,10 @@ Copy page
213
213
  | [How to do a phased rollout](/tutorials/phased-rollout.md) | Gradually roll out features to minimize risk |
214
214
  | [More tutorials](/docs/feature-flags/tutorials.md) | Other real-world examples and use cases |
215
215
 
216
+ ### Still have questions?
217
+
218
+ Ask PostHog AI
219
+
216
220
  ### Was this page useful?
217
221
 
218
222
  HelpfulCould be better
@@ -184,6 +184,10 @@ Copy page
184
184
  | [How to do a phased rollout](/tutorials/phased-rollout.md) | Gradually roll out features to minimize risk |
185
185
  | [More tutorials](/docs/feature-flags/tutorials.md) | Other real-world examples and use cases |
186
186
 
187
+ ### Still have questions?
188
+
189
+ Ask PostHog AI
190
+
187
191
  ### Was this page useful?
188
192
 
189
193
  HelpfulCould be better