@getrheo/rheo-skill 1.0.0

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 (39) hide show
  1. package/README.md +76 -0
  2. package/package.json +51 -0
  3. package/rheo/SKILL.md +32 -0
  4. package/rheo/rheo-best-practices/SKILL.md +46 -0
  5. package/rheo/rheo-best-practices/examples/react-native-install-snippet.md +23 -0
  6. package/rheo/rheo-best-practices/examples/swiftui-install-snippet.md +20 -0
  7. package/rheo/rheo-best-practices/references/implement-workflow.md +27 -0
  8. package/rheo/rheo-best-practices/references/integrations.md +51 -0
  9. package/rheo/rheo-best-practices/references/react-native-bare.md +36 -0
  10. package/rheo/rheo-best-practices/references/react-native-expo.md +49 -0
  11. package/rheo/rheo-best-practices/references/swiftui.md +52 -0
  12. package/rheo/rheo-best-practices/references/troubleshooting.md +57 -0
  13. package/rheo/rheo-flow-import/SKILL.md +68 -0
  14. package/rheo/rheo-flow-import/examples/branching-onboarding.manifest.json +155 -0
  15. package/rheo/rheo-flow-import/examples/flow-spec.example.json +56 -0
  16. package/rheo/rheo-flow-import/examples/linear-onboarding.manifest.json +104 -0
  17. package/rheo/rheo-flow-import/examples/revenuecat-paywall.manifest.json +154 -0
  18. package/rheo/rheo-flow-import/references/animation-import.md +79 -0
  19. package/rheo/rheo-flow-import/references/capabilities.md +107 -0
  20. package/rheo/rheo-flow-import/references/carousel-import.md +64 -0
  21. package/rheo/rheo-flow-import/references/flow-spec.md +214 -0
  22. package/rheo/rheo-flow-import/references/font-import.md +67 -0
  23. package/rheo/rheo-flow-import/references/import-workflow.md +240 -0
  24. package/rheo/rheo-flow-import/references/layer-schema-pitfalls.md +179 -0
  25. package/rheo/rheo-flow-import/references/localization-import.md +128 -0
  26. package/rheo/rheo-flow-import/references/manifest-agent-profile-fallback.md +74 -0
  27. package/rheo/rheo-flow-import/references/manifest-rules.md +197 -0
  28. package/rheo/rheo-flow-import/references/publish-gates.md +91 -0
  29. package/rheo/rheo-flow-import/references/react-native-source-patterns.md +99 -0
  30. package/rheo/rheo-flow-import/references/swiftui-source-patterns.md +99 -0
  31. package/rheo/rheo-flow-import/scripts/audit-import.mjs +4 -0
  32. package/rheo/rheo-flow-import/scripts/audit-publish-manifest.mjs +4 -0
  33. package/rheo/rheo-flow-import/scripts/fetch-profile.mjs +4 -0
  34. package/rheo/rheo-flow-import/scripts/lib/rheo-cli.mjs +12753 -0
  35. package/rheo/rheo-flow-import/scripts/normalize-manifest.mjs +4 -0
  36. package/rheo/rheo-flow-import/scripts/print-manifest-summary.mjs +4 -0
  37. package/rheo/rheo-flow-import/scripts/scaffold-manifest.mjs +4 -0
  38. package/rheo/rheo-flow-import/scripts/validate-manifest.mjs +4 -0
  39. package/src/index.ts +32 -0
@@ -0,0 +1,99 @@
1
+ # Reading React Native / Expo flows
2
+
3
+ How to trace an existing onboarding/paywall/setup flow in a React Native or Expo
4
+ codebase and map each source construct to a Rheo manifest concept. Run
5
+ `node scripts/audit-import.mjs --entry <entry>` first — this guide explains how
6
+ to interpret and extend its findings.
7
+
8
+ ## Find the entry point
9
+
10
+ | Signal | Where |
11
+ |--------|-------|
12
+ | Expo Router | `app/onboarding.tsx`, `app/(onboarding)/_layout.tsx`, `app/(auth)/...` route groups |
13
+ | React Navigation | `createNativeStackNavigator`, `<Stack.Navigator>`, an `OnboardingStack`/`OnboardingNavigator` |
14
+ | Manual gate | A root component branching on `hasOnboarded` / `firstLaunch` from storage |
15
+ | Names | `Onboarding*`, `Welcome*`, `Paywall*`, `Intro*`, `Setup*`, `Step*` screens/components |
16
+
17
+ Ask the user to confirm the entry file if it is not obvious; do not guess.
18
+
19
+ ## Map step order and navigation → screens + edges
20
+
21
+ - Each navigator screen or routed page → one Rheo **screen** (`scr_*`).
22
+ - `navigation.navigate('Next')`, `router.push('/next')`, `setStep(step + 1)`,
23
+ index into a `steps[]` array, or a `<Pager>` page change → a `next.default`
24
+ edge to the next screen.
25
+ - A "Continue"/"Next" button that advances → a `button` with `action: "continue"`.
26
+ - "Skip" → `action: "skip"`; finishing/closing the flow → `action: "end_flow"`.
27
+ - Conditional navigation (`if (plan === 'pro') navigate('X')`, A/B flags, platform
28
+ checks, stored answers) → a **decision node**, with the keys added to
29
+ `sdkAttributeKeys` when they are `sdk.*` attributes.
30
+
31
+ ## Map UI primitives → layers
32
+
33
+ | React Native source | Rheo layer |
34
+ |---------------------|------------|
35
+ | `<Text>`, `<Heading>`, typography components | `text` (copy in `text.default`, color in `style.color`) |
36
+ | `<Image source={require(...)}>`, `<ImageBackground>`, `expo-image` | `image` with `media.mediaAssetId` (bundle the asset) |
37
+ | `lottie-react-native` `<LottieView>` | `lottie` |
38
+ | `react-native-video` / `expo-video` | `video` |
39
+ | `<Pressable>`/`<TouchableOpacity>` acting as CTA | `button` (label = nested `text` child) |
40
+ | Header back chevron / close (`<HeaderBackButton>`, a back `Pressable` in a top bar) | `back_button` in `regions.header`, `icon.family: "ionicons"`, no `action` |
41
+ | `<View style={{ flexDirection, alignItems, gap }}>` | `stack` (`direction`, `align`, `justify`, `gap`) |
42
+ | Vector icons (`react-native-vector-icons`, `@expo/vector-icons` Ionicons) | `icon` (`family: "ionicons"`) |
43
+ | External `Linking.openURL(...)` / `<A href>` | `hyperlink` |
44
+ | Progress bar / step dots tied to step index | `progress` (header) |
45
+
46
+ Hero images that render through wrapper components (`<Illustration>`, `<Logo>`,
47
+ `<Mascot>`, `<Avatar>`) are easy to miss — follow the component to its `require`.
48
+
49
+ ## Inputs and choices
50
+
51
+ - Selectable option grids/lists (mapped `options.map(...)` with a `selected`
52
+ state and a `selected ? styleA : styleB` ternary) → `single_choice` /
53
+ `multiple_choice`. Each option becomes an option `stack`; map the unselected
54
+ branch to `style` and the selected branch to `selectedStyle`.
55
+ - `<TextInput>` collecting a value → `text_input` with a snake_case `fieldKey`;
56
+ mark password/email/PII as `classification: "sensitive"`.
57
+ - Sliders / rating rows → `scale_input`. Consent toggles → `checkbox`.
58
+ - Screens with a manual-submit input need a `continue` button.
59
+
60
+ ## Theme, colors, gradients, fonts
61
+
62
+ - Style tokens live in NativeWind/Tailwind config, `theme.ts`, design-token
63
+ files, `StyleSheet.create`, or shared `Button`/`Text`/`Screen` primitives. Map
64
+ primary/background/foreground/accent into `manifest.theme`.
65
+ - `expo-linear-gradient` / `react-native-linear-gradient` →
66
+ `screen.containerStyle.backgroundFill.color` as a `linear-gradient(...)` CSS
67
+ string. NativeWind classes like `bg-red-600 text-white` → solid screen fill +
68
+ `#FFFFFF` text color.
69
+ - `expo-font` `useFonts(...)` / `Font.loadAsync(...)` / Tailwind `fontFamily` →
70
+ custom fonts. Copy the `.ttf`/`.otf` files and emit `rheo-import.fonts.json`;
71
+ set `manifest.theme.fontFamily` ([font-import.md](font-import.md)).
72
+
73
+ ## Carousels / pagers
74
+
75
+ `react-native-pager-view`, a `FlatList horizontal pagingEnabled`, a
76
+ `ScrollView horizontal` snap pager, `Animated` `translateX` paging, or an
77
+ `infoSteps`/`currentStep` index → `kind: "carousel"` with one slide per page.
78
+ Carousels are swipe-only; do not turn the pager's own next button into a footer
79
+ button ([carousel-import.md](carousel-import.md)).
80
+
81
+ ## Integrations and native steps
82
+
83
+ - `react-native-purchases` / `react-native-purchases-ui` / `Purchases.configure`
84
+ / a `<Paywall>` → a RevenueCat **external surface** (`provider: "revenuecat"`,
85
+ required `fallback`). See [integrations](../../rheo-best-practices/references/integrations.md).
86
+ - `react-native-appsflyer` → represent stable attribution branches via decision
87
+ nodes; add keys to `sdkAttributeKeys`. Never include AppsFlyer/RevenueCat secrets.
88
+ - OAuth / email-password screens → `oauth_login` / `email_password_auth` (host
89
+ owns the actual auth logic).
90
+ - `react-native-permissions` prompts → a `request_os_permission` button action.
91
+ - Signature pads, camera capture, custom WebViews → confirm with the user whether
92
+ to keep native (host-owned) or approximate; flag unmappable behavior in chat.
93
+
94
+ ## i18n
95
+
96
+ `i18next`/`react-i18next` (`t('key')`), `react-intl` (`formatMessage`), Lingui, or
97
+ locale JSON under `locales/` → resolve each key against the **default-locale**
98
+ JSON and put the resolved string in `text.default` (never the raw key). Set
99
+ `manifest.defaultLocale` ([localization-import.md](localization-import.md)).
@@ -0,0 +1,99 @@
1
+ # Reading SwiftUI flows
2
+
3
+ How to trace an existing onboarding/paywall/setup flow in a SwiftUI codebase and
4
+ map each source construct to a Rheo manifest concept. Run
5
+ `node scripts/audit-import.mjs --entry <entry>` first (point `--entry` at the root
6
+ onboarding view or coordinator) — this guide explains how to interpret findings.
7
+
8
+ ## Find the entry point
9
+
10
+ | Signal | Where |
11
+ |--------|-------|
12
+ | App root | `@main struct …App: App`, the root `WindowGroup` view that branches on a stored `hasOnboarded` flag (`@AppStorage`, `UserDefaults`) |
13
+ | Navigation | `NavigationStack { … }` with a `path` binding, `NavigationLink`, or a coordinator pushing views |
14
+ | Step state | A `@State`/`@Published` step index or an `enum OnboardingStep` switched in the body |
15
+ | Names | `Onboarding*View`, `Welcome*View`, `Paywall*View`, `Intro*`, `Setup*`, `*Coordinator` |
16
+
17
+ Ask the user to confirm the entry view/coordinator if it is not obvious.
18
+
19
+ ## Map step order and navigation → screens + edges
20
+
21
+ - Each pushed view / `enum` case / `TabView` page → one Rheo **screen** (`scr_*`).
22
+ - `path.append(...)`, `NavigationLink(value:)`, `step += 1`, `withAnimation { step = .next }`,
23
+ or a `selection` change in a paging `TabView` → a `next.default` edge.
24
+ - A primary "Continue"/"Get Started" `Button` that advances → `button` with
25
+ `action: "continue"`; "Skip" → `"skip"`; dismissing/finishing → `"end_flow"`.
26
+ - `if`/`switch` on a stored value, entitlement, A/B flag, or `#if os(...)` that
27
+ changes the next view → a **decision node**; add `sdk.*` keys to `sdkAttributeKeys`.
28
+
29
+ ## Map SwiftUI views → layers
30
+
31
+ | SwiftUI source | Rheo layer |
32
+ |----------------|------------|
33
+ | `Text(...)`, `Label` text | `text` (copy in `text.default`, color in `style.color`) |
34
+ | `Image("asset")`, `AsyncImage`, `Image(uiImage:)` from the asset catalog | `image` with `media.mediaAssetId` (bundle the asset) |
35
+ | Lottie via `lottie-ios` (`LottieView`/`AnimationView`) | `lottie` |
36
+ | `VideoPlayer` / `AVPlayer` | `video` |
37
+ | `Button { … } label: { … }` acting as CTA | `button` (label = nested `text` child) |
38
+ | Toolbar back/close (`.toolbar { ToolbarItem(placement: .navigationBarLeading) }`, a chevron `Button`) | `back_button` in `regions.header`, `icon.family: "ionicons"`, no `action` |
39
+ | `VStack`/`HStack`/`ZStack` with `spacing`, `alignment` | `stack` (`direction`, `align`, `justify`, `gap`) |
40
+ | SF Symbol `Image(systemName:)` | `icon` — **remap to a valid `ionicons` name** (SF Symbols are not allowed on `icon`) |
41
+ | `Link(destination:)` / `openURL` | `hyperlink` |
42
+ | `ProgressView(value:)` / step dots | `progress` (header) |
43
+
44
+ Custom view structs (`HeroIllustration`, `LogoView`, `MascotView`) often wrap the
45
+ real asset — follow the struct to its `Image("…")` to find the asset name.
46
+
47
+ ## Inputs and choices
48
+
49
+ - A list/grid of selectable option views with `@State var selected` and a
50
+ `selected == option ? colorA : colorB` modifier → `single_choice` /
51
+ `multiple_choice`. Each option becomes an option `stack`; map the unselected
52
+ modifiers to `style` and the selected modifiers to `selectedStyle`.
53
+ - `TextField`/`SecureField` → `text_input` with a snake_case `fieldKey`
54
+ (`SecureField` / email / PII → `classification: "sensitive"`).
55
+ - `Slider` / star rating → `scale_input`. `Toggle` consent → `checkbox`.
56
+ - Manual-submit input screens need a `continue` button.
57
+
58
+ ## Theme, colors, gradients, fonts
59
+
60
+ - Style tokens live in `Color` extensions / an asset-catalog color set, `Font`
61
+ extensions, and reusable `ButtonStyle`/`ViewModifier` types. Map primary/
62
+ background/foreground/accent into `manifest.theme`.
63
+ - `LinearGradient(gradient:startPoint:endPoint:)` used as a background →
64
+ `screen.containerStyle.backgroundFill.color` as a `linear-gradient(...)` CSS
65
+ string. A solid `.background(Color("Brand"))` → solid screen fill + matching
66
+ text color.
67
+ - Custom fonts registered in `Info.plist` (`UIAppFonts`) and used via
68
+ `.font(.custom("Name", size:))` → copy the font files, emit
69
+ `rheo-import.fonts.json`, and set `manifest.theme.fontFamily`
70
+ ([font-import.md](font-import.md)).
71
+
72
+ ## Carousels / pagers
73
+
74
+ A paging `TabView { … }.tabViewStyle(.page)`, a horizontal `ScrollView` with snap
75
+ paging, or an `infoSteps`/`currentStep` index → `kind: "carousel"`, one slide per
76
+ page, swipe-only (no in-pager button) ([carousel-import.md](carousel-import.md)).
77
+
78
+ ## Integrations and native steps
79
+
80
+ - RevenueCat (`Purchases.configure`, `RevenueCatUI` `PaywallView`, `.presentPaywall`)
81
+ → a RevenueCat **external surface** (`provider: "revenuecat"`, required
82
+ `fallback`). See [integrations](../../rheo-best-practices/references/integrations.md).
83
+ - AppsFlyer (`AppsFlyerLib`) → represent stable attribution branches via decision
84
+ nodes; add keys to `sdkAttributeKeys`. Never include secrets.
85
+ - "Sign in with Apple" (`SignInWithAppleButton`) / OAuth / email-password →
86
+ `oauth_login` / `email_password_auth` (host owns the auth logic).
87
+ - Permission prompts (`AVCaptureDevice.requestAccess`, `CLLocationManager`,
88
+ `UNUserNotificationCenter`) → a `request_os_permission` button action; the host
89
+ must declare the matching `Info.plist` usage strings.
90
+ - `PencilKit` signature, camera capture, custom `WKWebView` → confirm whether to
91
+ keep native (host-owned) or approximate; flag unmappable behavior in chat.
92
+
93
+ ## Localization
94
+
95
+ `String(localized:)`, `Text("key")` resolved from `Localizable.strings`/
96
+ `.xcstrings`, or `NSLocalizedString` → resolve each key against the
97
+ **default-locale** strings file and put the resolved string in `text.default`
98
+ (never the raw key). Set `manifest.defaultLocale`
99
+ ([localization-import.md](localization-import.md)).
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { runCli } from './lib/rheo-cli.mjs';
3
+
4
+ process.exitCode = await runCli('audit', process.argv.slice(2));
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { runCli } from './lib/rheo-cli.mjs';
3
+
4
+ process.exitCode = await runCli('audit-publish', process.argv.slice(2));
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { runCli } from './lib/rheo-cli.mjs';
3
+
4
+ process.exitCode = await runCli('profile', process.argv.slice(2));