diff --git a/skills/brownfield-navigation/SKILL.md b/skills/brownfield-navigation/SKILL.md new file mode 100644 index 00000000..28407bc0 --- /dev/null +++ b/skills/brownfield-navigation/SKILL.md @@ -0,0 +1,46 @@ +--- +name: brownfield-navigation +description: Allows presenting existing native screens from React Native. Define the schema in TypeScript, run codegen to generate the bindings, invoke the function on the JS side, generate the XCFramework/AAR, and integrate native bindings such as the delegate into the host app. +license: MIT +metadata: + author: Callstack + tags: react-native, expo, brownfield, navigation +--- + +# Overview + +Brownfield Navigation flows from a TypeScript contract (`brownfield.navigation.ts`) through `npx brownfield navigation:codegen`, which generates JS bindings, native stubs, and delegate protocols. Host apps implement `BrownfieldNavigationDelegate`, register it with `BrownfieldNavigationManager` at startup, then React Native code calls the generated `@callstack/brownfield-navigation` module. + +# When to Apply + +Reference these skills when: +- App uses brownfield setup +- Presenting existing native screen from React Native +- Configuring schema for brownfield navigation +- Implementing the brownfield navigation delegate + +# Quick Reference + +- Generate the files using codegen script: +```bash +npx brownfield navigation:codegen +``` +- Brownfield packaging commands also run the same navigation codegen as part of packaging workflows: +```bash +# iOS +npx brownfield package:ios + +# android +npx brownfield package:android +npx brownfield publish:android +``` + +## Routing (concern → file) + +Concern | Read +--------|------ +JS call sites, `BrownfieldNavigation.*` usage, `undefined is not a function`, params vs generated API | [`javascript-usage.md`](references/javascript-usage.md) +`BrownfieldNavigationDelegate`, `setDelegate` / `shared.setDelegate`, startup crashes, no-op / wrong native route | [`native-integration.md`](references/native-integration.md) +Contract placement, `BrownfieldNavigationSpec` / `Spec`, `navigation:codegen`, generated artifacts, stale or missing outputs | [`setup-codegen.md`](references/setup-codegen.md) + + diff --git a/skills/brownfield-navigation/references/javascript-usage.md b/skills/brownfield-navigation/references/javascript-usage.md new file mode 100644 index 00000000..99d06b70 --- /dev/null +++ b/skills/brownfield-navigation/references/javascript-usage.md @@ -0,0 +1,95 @@ +# Brownfield Navigation JavaScript Usage + +## Discoverability triggers + +- "how to call BrownfieldNavigation from JS" +- "`undefined is not a function` on a Brownfield method" +- "JS method missing after updating `brownfield.navigation.ts`" +- "Brownfield JS method exists but opens wrong destination" + +## Scope + +In scope: +- Calling `BrownfieldNavigation.()` from React Native code. +- JS call-site patterns for buttons/screens and parameter passing. +- Runtime troubleshooting for JS-facing failures (`undefined is not a function`, missing methods, API drift signals). +- Reminding users when contract changes require codegen and native rebuild. + +Out of scope: +- Authoring `brownfield.navigation.ts` and codegen mechanics. For that, read [`setup-codegen.md`](setup-codegen.md) in this folder. +- Android/iOS delegate implementation and startup registration details. For that, read [`native-integration.md`](native-integration.md) in this folder. + +## Procedure + +1. Confirm readiness before discussing JS calls + - Native delegate registration must already be in place before JS uses the module. + - If registration/startup order is uncertain, read [`native-integration.md`](native-integration.md) in this folder. + +2. Provide the default JS invocation pattern + - Import `BrownfieldNavigation` from `@callstack/brownfield-navigation`. + - Call generated methods directly from handlers (for example, button `onPress`). + - Keep method names and argument shape aligned with the generated API. + +3. Recommend call-site best practices + - Pass stable explicit params (`userId`, IDs, flags), not transient UI-derived data. + - Keep each JS method call mapped to a clearly named native destination. + - Use simple direct calls first; avoid wrapping in unnecessary abstractions while debugging. + +4. Apply troubleshooting flow for runtime failures + - `undefined is not a function`: method changed in spec but codegen/rebuild not reapplied. + - Native crash on call: likely delegate registration/startup ordering issue; hand off implementation details to [`native-integration.md`](native-integration.md) in this folder. + - Method exists but wrong route/no-op: generated method present, but native delegate wiring likely incorrect; route delegate fixes to [`native-integration.md`](native-integration.md) in this folder. + +5. Enforce regeneration rule when JS/native API drift appears + - If method names, params, or return types changed in `brownfield.navigation.ts`, rerun: + `npx brownfield navigation:codegen` + - Then rebuild native apps before retesting JS calls. + +6. Route non-JS root causes quickly + - Spec placement/signature/codegen output questions → [`setup-codegen.md`](setup-codegen.md) in this folder. + - Delegate implementation/registration/lifecycle questions → [`native-integration.md`](native-integration.md) in this folder. + +## Minimal TSX example + +Assume the generated contract includes a method like `openNativeProfile(userId: string): void`. The exact method names and params come from the generated `@callstack/brownfield-navigation` module after running codegen. + +```tsx +import React from 'react'; +import {Button, SafeAreaView} from 'react-native'; +import BrownfieldNavigation from '@callstack/brownfield-navigation'; + +export function ProfileLauncherScreen(): React.JSX.Element { + return ( + +