@wireai/activation 0.14.2 → 0.14.3
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/CHANGELOG.md +71 -0
- package/README.md +12 -2
- package/dist/coachmarks/index.d.mts +12 -4
- package/dist/coachmarks/index.d.ts +12 -4
- package/dist/coachmarks/index.js +205 -56
- package/dist/coachmarks/index.js.map +1 -1
- package/dist/coachmarks/index.mjs +157 -7
- package/dist/coachmarks/index.mjs.map +1 -1
- package/dist/showcase/index.js +235 -46
- package/dist/showcase/index.js.map +1 -1
- package/dist/showcase/index.mjs +201 -10
- package/dist/showcase/index.mjs.map +1 -1
- package/metro/index.js +16 -5
- package/package.json +1 -1
- package/src/coachmarks/GestureHint.tsx +16 -7
- package/src/coachmarks/SpotlightOverlay.tsx +19 -13
- package/src/coachmarks/index.ts +7 -2
- package/src/coachmarks/reanimated.ts +342 -0
- package/src/showcase/FeatureShowcase.tsx +25 -9
- package/src/showcase/blazejOnboarding.ts +136 -0
- package/src/showcase/index.ts +8 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/features/defaults.ts","../../src/features/cache.ts","../../src/features/fetchWireFeatures.ts","../../src/features/useWireFeatures.ts","../../src/features/WireFeaturesProvider.tsx","../../src/coachmarks/runtime.ts","../../src/coachmarks/coachmarkOverlayStore.ts","../../src/theme/defaultTheme.ts","../../src/theme/ThemeContext.tsx","../../src/coachmarks/expoBlur.ts","../../src/coachmarks/GestureHint.tsx","../../src/coachmarks/SpotlightOverlay.tsx","../../src/coachmarks/CoachmarkOverlayHost.tsx","../../src/coachmarks/CoachmarkProvider.tsx","../../src/coachmarks/coachmarkAnchorRegistry.ts","../../src/coachmarks/useCoachmarkAnchor.ts","../../src/coachmarks/useCoachmarkTour.ts","../../src/coachmarks/selectTourSteps.ts"],"names":["cached","useRef","useState","useEffect","createContext","useContext","listeners","useSyncExternalStore","useMemo","jsxs","View","jsx","useSharedValue","useReducedMotion","withRepeat","withSequence","withTiming","withDelay","useAnimatedStyle","Animated","Fragment","StyleSheet","React","useWindowDimensions","useAnimatedProps","styles","FadeIn","FadeOut","Pressable","Text","useCallback","_a","_b","_c"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * The fail-open defaults + a tolerant parser for the server's flags payload.\n *\n * THE CONTRACT: fail-open, never fail-dark. An absent server object, a missing module key, a\n * malformed value, or an unreachable endpoint must resolve to the MOST PERMISSIVE state — every\n * module ON, onboarding `ai` — so a control-plane outage can only ever be more permissive than\n * the dashboard intends. It can never dark a tenant's activation. Matches the server's own\n * documented fail-open default (FEATURES.md: \"local defaults — every module on, onboarding ai\").\n */\nimport type { OnboardingMode, WireFeatures } from \"./types\";\n\n/**\n * ALL ON, onboarding `ai`. Frozen + module-level so its reference is stable across every call\n * (consumers that list resolved flags in an effect dep array never loop on a fresh identity).\n */\nexport const defaultWireFeatures: WireFeatures = Object.freeze({\n coachmarks: Object.freeze({ enabled: true }),\n showcase: Object.freeze({ enabled: true }),\n onboarding: Object.freeze({ mode: \"ai\" as OnboardingMode }),\n review: Object.freeze({ enabled: true }),\n questionnaire: Object.freeze({ enabled: true }),\n announcements: Object.freeze({ enabled: true }),\n}) as WireFeatures;\n\nconst VALID_MODES: readonly OnboardingMode[] = [\"ai\", \"static\", \"off\"];\n\n/** Read a `{ enabled: boolean }` module, defaulting to ON when absent/malformed (fail-open). */\nconst readEnabled = (raw: unknown): { enabled: boolean } => {\n if (raw && typeof raw === \"object\" && typeof (raw as { enabled?: unknown }).enabled === \"boolean\") {\n return { enabled: (raw as { enabled: boolean }).enabled };\n }\n return { enabled: true };\n};\n\n/**\n * Narrow the server's (untrusted) JSON to a complete `WireFeatures`. Every field is filled with\n * its fail-open default when the server omits it or sends the wrong type, so a partial or\n * malformed payload degrades PERMISSIVELY rather than throwing. A non-object input (null, array,\n * string) → the full defaults. Never throws.\n */\nexport const parseWireFeatures = (raw: unknown): WireFeatures => {\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw)) return defaultWireFeatures;\n const src = raw as Record<string, unknown>;\n const modeRaw = (src.onboarding as { mode?: unknown } | undefined)?.mode;\n const mode: OnboardingMode =\n typeof modeRaw === \"string\" && VALID_MODES.includes(modeRaw as OnboardingMode)\n ? (modeRaw as OnboardingMode)\n : \"ai\";\n return {\n coachmarks: readEnabled(src.coachmarks),\n showcase: readEnabled(src.showcase),\n onboarding: { mode },\n review: readEnabled(src.review),\n questionnaire: readEnabled(src.questionnaire),\n announcements: readEnabled(src.announcements),\n };\n};\n\n/** Value-equality of two resolved flags — lets the hook hold a stable reference across churn. */\nexport const featuresEqual = (a: WireFeatures, b: WireFeatures): boolean =>\n a === b ||\n (a.coachmarks.enabled === b.coachmarks.enabled &&\n a.showcase.enabled === b.showcase.enabled &&\n a.onboarding.mode === b.onboarding.mode &&\n a.review.enabled === b.review.enabled &&\n a.questionnaire.enabled === b.questionnaire.enabled &&\n a.announcements.enabled === b.announcements.enabled);\n","/**\n * The last-known-flags cache — persisted through the host's optional `storage`.\n *\n * WHY: the fetch is best-effort and fail-open. When the control plane is unreachable we serve the\n * LAST value we saw rather than snapping to defaults, so a tenant that intentionally disabled a\n * module during an incident keeps it disabled across an outage instead of flapping back on. That\n * is \"stale-while-error\": a fresh cache (< TTL) is trusted, and on a fetch error even a STALE\n * cache is served (any age beats a guess). Every operation is best-effort — a broken/hung storage\n * degrades to defaults, never a throw and never a stuck gate (mirrors persistedSession).\n */\nimport { parseWireFeatures } from \"./defaults\";\nimport type { WireFeatures } from \"./types\";\nimport type { WireOnboardingStorage } from \"../session/persistedSession\";\n\n/**\n * TTL for a cached flags entry, aligned to the server's `Cache-Control: private, max-age=300`.\n * A cache younger than this is \"fresh\"; older is \"stale\" (still served on a fetch error).\n */\nexport const DEFAULT_FEATURES_TTL_MS = 300_000;\n\n/** Ceiling on the storage read so a hung adapter degrades to defaults, never a stuck resolve. */\nconst READ_TIMEOUT_MS = 1_500;\n\n/** Storage key for a tenant's cached flags, e.g. `wireai:features:acme`. */\nexport const featuresCacheKey = (appId?: string): string =>\n `wireai:features:${appId && appId.length > 0 ? appId : \"default\"}`;\n\n/** A cached flags entry: the resolved flags + the epoch-ms they were fetched. */\nexport interface CachedFeatures {\n features: WireFeatures;\n /** Age of the entry in ms at read time. */\n ageMs: number;\n}\n\nconst withTimeout = <T>(p: Promise<T>, ms: number): Promise<T | undefined> => {\n let timer: ReturnType<typeof setTimeout>;\n const timeout = new Promise<undefined>((resolve) => {\n timer = setTimeout(() => resolve(undefined), ms);\n });\n return Promise.race([p, timeout]).finally(() => clearTimeout(timer));\n};\n\n/** Whether a cache entry is still within the TTL (server max-age aligned). */\nexport const isFeaturesFresh = (ageMs: number, ttlMs: number = DEFAULT_FEATURES_TTL_MS): boolean =>\n ageMs >= 0 && ageMs < ttlMs;\n\n/**\n * Read the cached flags for `key`, or `undefined` when absent/corrupt/timed-out. Returns the\n * value AND its age so a caller can apply a TTL (fresh) or ignore it (stale-while-error). Never\n * throws; never hangs past the read timeout. The stored value is re-parsed through\n * `parseWireFeatures`, so a partially-corrupt entry still degrades fail-open.\n */\nexport const readCachedFeatures = async (\n storage: WireOnboardingStorage,\n key: string,\n): Promise<CachedFeatures | undefined> => {\n let raw: string | null | undefined;\n try {\n raw = await withTimeout(storage.getItem(key), READ_TIMEOUT_MS);\n } catch {\n return undefined;\n }\n if (!raw) return undefined;\n try {\n const parsed: unknown = JSON.parse(raw);\n if (parsed && typeof parsed === \"object\" && typeof (parsed as { ts?: unknown }).ts === \"number\") {\n const ts = (parsed as { ts: number }).ts;\n return {\n features: parseWireFeatures((parsed as { features?: unknown }).features),\n ageMs: Date.now() - ts,\n };\n }\n } catch {\n // Corrupt entry → treat as absent; the caller falls back to defaults / a fresh fetch.\n }\n return undefined;\n};\n\n/** Persist `{ features, ts }` under `key` — fire-and-forget, all errors swallowed. */\nexport const writeCachedFeatures = (\n storage: WireOnboardingStorage,\n key: string,\n features: WireFeatures,\n): void => {\n try {\n void storage\n .setItem(key, JSON.stringify({ features, ts: Date.now() }))\n .catch(() => {});\n } catch {\n // Best-effort: a failed write just means the next launch has no cache to fall back to.\n }\n};\n","/**\n * fetchWireFeatures — read the per-module kill switches from `GET {serverUrl}/v1/features`.\n *\n * Contract (server: chohra-med/wireai-onboarding-server, routers/onboarding.py):\n * GET {serverUrl}/v1/features\n * Authorization: Bearer {apiKey}\n * 200 → { coachmarks:{enabled}, showcase:{enabled}, onboarding:{mode}, review:{enabled},\n * announcements:{enabled} } (Cache-Control: private, max-age=300)\n *\n * THE CONTRACT — fail-open, never fail-dark. Unreachable, timed-out, unauthorized (401),\n * server-error (5xx), or malformed JSON all resolve to the LAST CACHED value, else the\n * all-on defaults. No throw ever reaches the host: this is timeout-capped and swallows every\n * error, exactly like the session's best-effort reads. A control-plane outage can only ever be\n * MORE permissive than the dashboard intends — it can never dark a tenant's activation.\n */\nimport { readCachedFeatures, featuresCacheKey, writeCachedFeatures } from \"./cache\";\nimport { defaultWireFeatures, parseWireFeatures } from \"./defaults\";\nimport type { WireFeatures, WireFeaturesConfig } from \"./types\";\nimport type { WireOnboardingStorage } from \"../session/persistedSession\";\n\nconst DEFAULT_TIMEOUT_MS = 4_000;\n\n/** The fail-open fallback: last cached value (any age — stale-while-error), else defaults. */\nconst failOpen = async (\n storage: WireOnboardingStorage | undefined,\n key: string,\n): Promise<WireFeatures> => {\n if (!storage) return defaultWireFeatures;\n const cached = await readCachedFeatures(storage, key);\n return cached?.features ?? defaultWireFeatures;\n};\n\n/** GET with a hard timeout via AbortController (falls back to no-abort where unsupported). */\nconst fetchWithTimeout = async (\n url: string,\n apiKey: string,\n timeoutMs: number,\n): Promise<Response> => {\n const controller =\n typeof AbortController !== \"undefined\" ? new AbortController() : undefined;\n const timer = setTimeout(() => controller?.abort(), timeoutMs);\n try {\n return await fetch(url, {\n method: \"GET\",\n headers: { Accept: \"application/json\", Authorization: `Bearer ${apiKey}` },\n signal: controller?.signal,\n });\n } finally {\n clearTimeout(timer);\n }\n};\n\n/**\n * Resolve the tenant's feature flags. Attempts the network once; on ANY failure returns the\n * cached value (any age), else the all-on defaults. On success, persists the fresh value to the\n * cache (fire-and-forget) and returns it. Never throws.\n *\n * const flags = await fetchWireFeatures({ serverUrl, apiKey, appId, storage });\n * if (!flags.coachmarks.enabled) { /* skip the tour * / }\n */\nexport const fetchWireFeatures = async (\n config?: WireFeaturesConfig,\n): Promise<WireFeatures> => {\n const key = featuresCacheKey(config?.appId);\n const storage = config?.storage;\n\n // Nothing to fetch (no creds) → cache, else defaults. Lets a host mount the provider before\n // its config is ready without ever darking.\n if (!config?.serverUrl || !config?.apiKey) return failOpen(storage, key);\n\n const url = `${config.serverUrl.replace(/\\/$/, \"\")}/v1/features`;\n const timeoutMs = config.timeoutMs && config.timeoutMs > 0 ? config.timeoutMs : DEFAULT_TIMEOUT_MS;\n\n try {\n const res = await fetchWithTimeout(url, config.apiKey, timeoutMs);\n // 401 (bad/rotated key), 5xx, any non-2xx → last-known, never dark.\n if (!res || !res.ok) return failOpen(storage, key);\n const json: unknown = await res.json(); // throws on malformed body → caught below\n const features = parseWireFeatures(json);\n if (storage) writeCachedFeatures(storage, key, features);\n return features;\n } catch {\n // Timeout/abort, network error, missing fetch, or malformed JSON — all fail open.\n return failOpen(storage, key);\n }\n};\n","/**\n * useWireFeatures — resolve the tenant's feature flags for a component tree, once per mount.\n *\n * Returns the all-on defaults immediately (fail-open), then swaps to the fetched value when the\n * network resolves. When no `serverUrl`+`apiKey` is supplied it never fetches and just returns\n * defaults, so a host that never adopts flags sees ZERO behavior change and ZERO network calls.\n *\n * frequent_rules #11 (unstable inline props): the config is idiomatically passed inline\n * (`config={{ serverUrl, apiKey }}`), a fresh identity every render. We stabilize the fetch key\n * by VALUE so the effect fires once per real credential change, and we only swap the returned\n * flags object when its VALUES change — so a host that lists the returned flags in an effect dep\n * array settles in a bounded number of commits instead of looping (enforced by the canary suite).\n */\nimport { useEffect, useRef, useState } from \"react\";\n\nimport { defaultWireFeatures, featuresEqual } from \"./defaults\";\nimport { fetchWireFeatures } from \"./fetchWireFeatures\";\nimport type { WireFeatures, WireFeaturesConfig } from \"./types\";\n\n/** Hold a stable reference for a value while its CONTENT is unchanged (see reviews/equality.ts). */\nconst useStableValue = <T,>(value: T, isEqual: (a: T, b: T) => boolean): T => {\n const ref = useRef(value);\n if (!isEqual(ref.current, value)) ref.current = value;\n return ref.current;\n};\n\n/** The credential slice that actually drives a refetch — stabilized by value. */\nconst sameFetchKey = (a: WireFeaturesConfig | undefined, b: WireFeaturesConfig | undefined): boolean =>\n a?.serverUrl === b?.serverUrl && a?.apiKey === b?.apiKey && a?.appId === b?.appId;\n\nexport const useWireFeatures = (config?: WireFeaturesConfig): WireFeatures => {\n const stableConfig = useStableValue(config, sameFetchKey);\n const [flags, setFlags] = useState<WireFeatures>(defaultWireFeatures);\n\n const canFetch = !!stableConfig?.serverUrl && !!stableConfig?.apiKey;\n\n useEffect(() => {\n if (!canFetch) {\n // No creds → stay on the all-on defaults (and reset if creds were removed).\n setFlags((prev) => (featuresEqual(prev, defaultWireFeatures) ? prev : defaultWireFeatures));\n return;\n }\n let alive = true;\n // fetchWireFeatures never throws — the .then always runs with a fail-open value.\n void fetchWireFeatures(stableConfig).then((next) => {\n if (!alive) return;\n // Only adopt a NEW reference on a real value change, so a host effect keyed on the\n // returned flags doesn't loop (frequent_rules #11).\n setFlags((prev) => (featuresEqual(prev, next) ? prev : next));\n });\n return () => {\n alive = false;\n };\n }, [canFetch, stableConfig]);\n\n return flags;\n};\n","/**\n * WireFeaturesProvider + useResolvedFeatures — the OPTIONAL one-fetch-serves-all-modules layer.\n *\n * Mount `WireFeaturesProvider` once near your app root with the tenant `config` and it fetches the\n * flags ONCE; every gated surface below it (coachmarks / showcase / reviews) reads the same\n * resolved value from context instead of each fetching its own. It is entirely optional: with no\n * provider, every surface falls back to its own lazy fetch (when given a config) or to the all-on\n * defaults, so modules work with zero setup and a host that never adopts flags is unchanged.\n *\n * NOTE on the built npm subpaths: React context is shared across the kit's subpath entries in the\n * SOURCE-consumption path (the monorepo apps) and in this test suite — one module instance, one\n * context. If you consume the built `@wireai/activation/*` subpaths as separate bundles, pass the\n * resolved flags (or a `featuresConfig`) to each surface explicitly instead of relying on context.\n */\nimport React, { createContext, useContext, useMemo } from \"react\";\n\nimport { defaultWireFeatures } from \"./defaults\";\nimport { useWireFeatures } from \"./useWireFeatures\";\nimport type { WireFeatures, WireFeaturesConfig } from \"./types\";\n\n/**\n * @globalSlot LATCH — the React context object is minted by the first copy of this module to load\n * and every later copy ADOPTS it (the `if (!…)` guard below). A second write would re-split the\n * identity the guard exists to keep whole: the provider would publish into one context while a\n * subpath bundle's `useContext` read another, and `useResolvedFeatures`' null fallback would serve\n * the all-on defaults with no crash and no warning. Because it is a latch, and only because of\n * that, the module-local `const WireFeaturesContext` below may cache it.\n */\nconst CONTEXT_SYMBOL = Symbol.for(\"wireai.features.context\");\n// `globalThis`, not `global`: the other nine `Symbol.for` slots in this kit all use it, and `global`\n// simply does not exist in a plain browser (RN-web / SSR-in-the-browser), where this line would\n// throw a ReferenceError before the provider could render anything.\nconst globalObj = globalThis as any;\n\nif (!globalObj[CONTEXT_SYMBOL]) {\n globalObj[CONTEXT_SYMBOL] = createContext<WireFeatures | null>(null);\n}\nconst WireFeaturesContext = globalObj[CONTEXT_SYMBOL];\n\nexport interface WireFeaturesProviderProps {\n /** Tenant creds (+ optional storage) to fetch the flags once for the whole tree. */\n config?: WireFeaturesConfig;\n /**\n * Pre-resolved flags to provide directly instead of fetching (e.g. you already have them, or\n * you drive them from your own remote-config). Takes precedence over `config`.\n */\n flags?: WireFeatures;\n children: React.ReactNode;\n}\n\n/**\n * Fetch (or accept) the flags once and broadcast them to descendants. The provider VALUE is\n * memoized (performance rule #6) so a fresh object each render doesn't re-render every consumer.\n */\nexport const WireFeaturesProvider: React.FC<WireFeaturesProviderProps> = ({\n config,\n flags,\n children,\n}) => {\n // Always call the hook (rules of hooks); when `flags` is supplied we pass no config so it\n // never fetches and the explicit flags win below.\n const fetched = useWireFeatures(flags ? undefined : config);\n const value = flags ?? fetched;\n const stable = useMemo(() => value, [value]);\n return <WireFeaturesContext.Provider value={stable}>{children}</WireFeaturesContext.Provider>;\n};\n\nWireFeaturesProvider.displayName = \"WireFeaturesProvider\";\n\n/** Raw context read — `null` when no `WireFeaturesProvider` is mounted above. */\nexport const useWireFeaturesContext = (): WireFeatures | null =>\n useContext(WireFeaturesContext);\n\n/** Options for `useResolvedFeatures`: an explicit override and/or a lazy-fetch config. */\nexport interface ResolveFeaturesOptions {\n /** Explicit flags — win over everything (a surface's own `features` prop). */\n flags?: WireFeatures;\n /** Lazy-fetch config, used ONLY when there is no explicit `flags` and no provider above. */\n config?: WireFeaturesConfig;\n}\n\n/**\n * The resolution every gated surface uses. Precedence:\n * 1. explicit `options.flags` (a surface's own prop) →\n * 2. the nearest `WireFeaturesProvider` (context) →\n * 3. a lazy fetch from `options.config` (serverUrl + apiKey) →\n * 4. the all-on defaults.\n * Always fail-open, always a stable reference for a given value (so it's safe in effect deps).\n */\nexport const useResolvedFeatures = (options?: ResolveFeaturesOptions): WireFeatures => {\n const ctx = useWireFeaturesContext();\n // Only lazily fetch when nothing else provides the flags — otherwise pass no config so the\n // hook stays inert (defaults, no network). The hook is always called (rules of hooks).\n const shouldFetch = !options?.flags && ctx == null;\n const fetched = useWireFeatures(shouldFetch ? options?.config : undefined);\n return options?.flags ?? ctx ?? fetched ?? defaultWireFeatures;\n};\n","/**\n * Module-level runtime for the coachmark engine: the injected sync storage, the\n * global `isTestingCoachmark` flag, and the seen-gate helpers built on top.\n *\n * WHY module singletons (not just context): the tour hooks and the anchor\n * registry are driven imperatively from anywhere in the tree (a screen deep\n * under the navigator), while the storage + testing flag are configured once at\n * the root by `CoachmarkProvider`. Singletons let a hook read the gate without\n * every call site threading the storage through props. The provider is still the\n * single writer — it calls `setCoachmarkStorage` / `setCoachmarkTesting` on mount.\n *\n * ── WHY A globalThis SLOT, NOT PLAIN MODULE VARIABLES ─────────────────────────────────────────\n * These three values used to be plain module `let`s, and this module is inlined by tsup into FOUR\n * dist bundles (`./coachmarks`, `./reviews`, `./questionnaire`, `./showcase`). Under `dist`\n * resolution — node `import`/`require`, SSR, jest, RN-web, anything that is not Metro — a host that\n * mounts `CoachmarkProvider` from `@wireai/activation/coachmarks` wrote the COACHMARKS copy, while\n * `useReviewGate` from `@wireai/activation/reviews` read the REVIEWS copy, which was still `null`.\n * Everything downstream then failed silently: `readInt(null, …)` returns 0, so `bumpSessionCount`\n * returns 1 forever and the fail-closed `minSessions: 2` default is unsatisfiable (the gate NEVER\n * fires); the `seen` once-gate never persists; and a tenant's coachmarks kill switch never reaches\n * the reviews bundle. Metro masked it by collapsing every subpath back to one `src/` file through\n * the `react-native` export condition, which is a bundler accident, not a guarantee.\n *\n * Same remedy this repo already applies to `currentSession`, the auto device-key registry and the\n * activation revalidation counter: ONE record in a `globalThis` slot keyed by `Symbol.for(...)`, so\n * every inlined copy of this module addresses the SAME state.\n */\nimport type { CoachmarkStorage } from \"./types\";\n\n/**\n * Well-known key into the runtime-global symbol registry — one coachmark runtime across bundles.\n *\n * @globalSlot LATCH — the RUNTIME RECORD is created once and its identity is then stable. A second\n * write replaces the record `subscribeCoachmarksEnabled` registered its listeners on, so a\n * kill-switch flip notifies an orphaned set while a tour that believes it is running paints nothing\n * — the exact limbo `coachmarkKillSwitch` canaries. Its FIELDS (`storage`, `testing`,\n * `coachmarksEnabled`, `listeners`) are live, which is why every accessor calls `coachmarkRuntime()`\n * instead of holding the record, and why `coachmarksEnabled` is subscribable rather than sampled.\n */\nconst COACHMARK_RUNTIME_SLOT: unique symbol = Symbol.for(\"@wireai/activation:coachmarkRuntime\");\n\n/** The shared runtime: the provider-injected storage, the QA replay flag, and the kill switch. */\ntype CoachmarkRuntime = {\n storage: CoachmarkStorage | null;\n testing: boolean;\n // The coachmarks feature kill switch (from GET /v1/features). Default true = fail-open: with no\n // flags fetched, coachmarks behave exactly as before. CoachmarkProvider writes it from the\n // resolved flags. Disabled → the tour never ARMS and the overlay `show()` is a no-op, so nothing\n // paints and — critically — no once-gate is written, so re-enabling replays the tour correctly.\n coachmarksEnabled: boolean;\n // Subscribers to the kill switch. OPTIONAL on the type (never on the behaviour) so a record left\n // in the registry by an inlined copy from an OLDER kit version — which had no listener set — is\n // upgraded in place rather than read as corrupt.\n listeners?: Set<() => void>;\n};\n\ntype GlobalWithCoachmarkRuntime = typeof globalThis & {\n [COACHMARK_RUNTIME_SLOT]?: CoachmarkRuntime;\n};\n\nconst runtimeGlobal = globalThis as GlobalWithCoachmarkRuntime;\n\nconst coachmarkRuntime = (): CoachmarkRuntime => {\n const existing = runtimeGlobal[COACHMARK_RUNTIME_SLOT];\n if (existing) return existing;\n const created: CoachmarkRuntime = { storage: null, testing: false, coachmarksEnabled: true };\n runtimeGlobal[COACHMARK_RUNTIME_SLOT] = created;\n return created;\n};\n\nconst enabledListeners = (): Set<() => void> => {\n const runtime = coachmarkRuntime();\n if (!runtime.listeners) runtime.listeners = new Set();\n return runtime.listeners;\n};\n\n/**\n * Wake the subscribers on a MICROTASK, never synchronously.\n *\n * `CoachmarkProvider` writes this flag during its RENDER phase on purpose (so a child's mount\n * effect already sees the resolved value). Notifying from there synchronously would schedule a\n * React update while a *different* component is rendering. Every subscriber reads the value\n * through `areCoachmarksEnabled()` at render time anyway, so the notification only has to wake\n * the components that are not already re-rendering — one microtask later is soon enough, and it\n * keeps the write side legal from anywhere.\n */\nconst notifyCoachmarksEnabled = (): void => {\n if (enabledListeners().size === 0) return;\n void Promise.resolve().then(() => {\n for (const listener of [...enabledListeners()]) {\n try {\n listener();\n } catch {\n // A broken subscriber must never break the kill switch for the others.\n }\n }\n });\n};\n\n/**\n * Set the coachmarks master switch (from the resolved feature flags). Default true (fail-open).\n * Written by CoachmarkProvider; read imperatively by the tour arm + the overlay store, and\n * SUBSCRIBED to by `useCoachmarkTour` (see `subscribeCoachmarksEnabled`).\n *\n * No-ops when the value is unchanged, which matters because the provider writes it on every\n * render — without that guard every render would fan out a notification.\n */\nexport const setCoachmarksEnabled = (value: boolean): void => {\n const runtime = coachmarkRuntime();\n if (runtime.coachmarksEnabled === value) return;\n runtime.coachmarksEnabled = value;\n notifyCoachmarksEnabled();\n};\n\n/** Whether the coachmarks module is enabled. False → tours/overlays are silently skipped. */\nexport const areCoachmarksEnabled = (): boolean => coachmarkRuntime().coachmarksEnabled;\n\n/**\n * Subscribe to kill-switch flips. Returns the unsubscribe function — the `useSyncExternalStore`\n * contract, and deliberately the SAME shape as `coachmarkOverlay.subscribe` next door rather than\n * a second pattern to keep correct.\n *\n * WHY IT EXISTS: the flag is a mutable `globalThis` value, so on its own it can only be SAMPLED.\n * A tour that samples it cannot notice a tenant flipping it off mid-flight — the overlay's\n * `show()` quietly becomes a no-op while the tour still believes it is running, so nothing paints,\n * nothing can be tapped to advance, and no terminal path is reachable. `useCoachmarkTour`\n * subscribes instead. The listener set lives in the SAME `globalThis` record as the flag, so every\n * inlined copy of this module shares one subscriber list.\n */\nexport const subscribeCoachmarksEnabled = (listener: () => void): (() => void) => {\n const listeners = enabledListeners();\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n};\n\n/** Set (or clear) the injected sync gate storage. Called by CoachmarkProvider. */\nexport const setCoachmarkStorage = (storage: CoachmarkStorage | null): void => {\n coachmarkRuntime().storage = storage;\n};\n\n/** The currently-injected gate storage, or null if no provider is mounted. */\nexport const getCoachmarkStorage = (): CoachmarkStorage | null => coachmarkRuntime().storage;\n\n/**\n * Toggle the global QA replay flag. When true, EVERY seen-gate reads as unseen\n * and every seen-write is suppressed, so every tour + showcase replays on each\n * mount. The app flips ONE boolean to QA the whole coachmark surface.\n */\nexport const setCoachmarkTesting = (value: boolean): void => {\n coachmarkRuntime().testing = value;\n};\n\n/** Whether replay-everything QA mode is on. */\nexport const isCoachmarkTesting = (): boolean => coachmarkRuntime().testing;\n\n/** Gate key for a tour: `wire_coachmark_<tourId>_seen`. */\nexport const coachmarkGateKey = (tourId: string): string =>\n `wire_coachmark_${tourId}_seen`;\n\n/** Gate key for a feature showcase: `wire_showcase_<id>_seen`. */\nexport const showcaseGateKey = (showcaseId: string): string =>\n `wire_showcase_${showcaseId}_seen`;\n\n/** Marker value written for a seen gate. */\nconst SEEN_VALUE = \"1\";\n\n/**\n * Read a seen gate. Testing mode ALWAYS reports unseen (so everything replays).\n * A missing storage (no provider) also reports unseen — the safe default is to\n * show the hint rather than silently swallow it. `storageOverride` /\n * `testingOverride` let a self-contained component (e.g. FeatureShowcase) pass\n * its own storage without relying on the provider singleton.\n */\nexport const hasSeenGate = (\n key: string,\n storageOverride?: CoachmarkStorage | null,\n testingOverride?: boolean,\n): boolean => {\n if (testingOverride ?? isCoachmarkTesting()) return false;\n const storage = storageOverride ?? getCoachmarkStorage();\n if (!storage) return false;\n try {\n return storage.getItem(key) === SEEN_VALUE;\n } catch {\n return false;\n }\n};\n\n/**\n * Mark a gate seen. Suppressed in testing mode (so replay never persists) and a\n * no-op without storage. Best-effort — a throwing adapter never breaks the tour.\n */\nexport const markSeenGate = (\n key: string,\n storageOverride?: CoachmarkStorage | null,\n testingOverride?: boolean,\n): void => {\n if (testingOverride ?? isCoachmarkTesting()) return;\n const storage = storageOverride ?? getCoachmarkStorage();\n if (!storage) return;\n try {\n storage.setItem(key, SEEN_VALUE);\n } catch {\n // Best-effort: a failed write just means the hint may show once more.\n }\n};\n","import { useSyncExternalStore } from \"react\";\n\nimport { areCoachmarksEnabled } from \"./runtime\";\nimport type { GestureKind, Placement, TargetRect } from \"./types\";\n\n/**\n * A tiny module-level store for the single active coachmark overlay. The host\n * (CoachmarkOverlayHost, mounted once by CoachmarkProvider at the app root)\n * subscribes and renders whatever is active; the tour controller drives it\n * imperatively via show()/hide(). No React context is needed for the overlay\n * itself — the host reaches the root so the ring can paint above the tab bar.\n *\n * Only ONE overlay is ever active (steps never stack), per the engine's\n * one-overlay-at-a-time rule.\n */\nexport interface CoachmarkOverlayState {\n message: string;\n targetRect: TargetRect | null;\n gesture: GestureKind;\n placement: Placement;\n onEngage: () => void;\n onDismiss: () => void;\n}\n\nlet current: CoachmarkOverlayState | null = null;\nconst listeners = new Set<() => void>();\n\nconst emit = () => {\n for (const listener of listeners) listener();\n};\n\nexport const coachmarkOverlay = {\n show(state: CoachmarkOverlayState) {\n // Feature kill switch: when coachmarks are disabled, a show() request is a silent no-op —\n // no ring paints, and because nothing shows the user can't advance/dismiss a tour, so no\n // once-gate is ever written and re-enabling replays it. hide() still works (see below).\n if (!areCoachmarksEnabled()) return;\n current = state;\n emit();\n },\n hide() {\n if (current === null) return;\n current = null;\n emit();\n },\n subscribe(listener: () => void) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n getSnapshot(): CoachmarkOverlayState | null {\n return current;\n },\n};\n\n/** Subscribe a component to the active overlay (or null). */\nexport const useCoachmarkOverlay = (): CoachmarkOverlayState | null =>\n useSyncExternalStore(\n coachmarkOverlay.subscribe,\n coachmarkOverlay.getSnapshot,\n coachmarkOverlay.getSnapshot,\n );\n","/**\n * defaultOnboardingTheme — a neutral, light, brand-agnostic baseline. Consumers\n * pass a `Partial<OnboardingTheme>` that is deep-merged over this (see\n * `mergeTheme`), so they only override what differs from neutral.\n */\nimport type { OnboardingTheme } from \"./types\";\n\nexport const defaultOnboardingTheme: OnboardingTheme = {\n colors: {\n background: \"#FFFFFF\",\n surface: \"#F7F7F8\",\n text: \"#101114\",\n textMuted: \"#6B7280\",\n primary: \"#111111\",\n onPrimary: \"#FFFFFF\",\n primarySoft: \"rgba(17,17,17,0.06)\",\n border: \"#E4E4E7\",\n borderStrong: \"#C7C7CC\",\n disabled: \"#EBEBEB\",\n success: \"#16A34A\",\n warning: \"#D97706\",\n error: \"#DC2626\",\n info: \"#2563EB\",\n },\n fonts: {\n regular: undefined,\n medium: undefined,\n bold: undefined,\n baseSize: 16,\n scale: 1,\n },\n radius: {\n sm: 8,\n md: 12,\n lg: 16,\n full: 9999,\n },\n spacing: {\n xs: 4,\n sm: 8,\n md: 16,\n lg: 24,\n xl: 32,\n },\n // Circled (pill) CTA by default; an app can pass `button: { radius: 12 }` for\n // a rounded rectangle, or override height/paddingX to match its design system.\n button: {\n radius: 9999,\n height: 52,\n paddingX: 24,\n },\n};\n\n/**\n * Deep-merge a partial theme over the default. Two levels deep is enough — the\n * theme is intentionally shallow (colors/fonts/radius/spacing), so we merge each\n * known sub-object and leave scalars to overwrite.\n */\nexport const mergeTheme = (\n override?: Partial<OnboardingTheme>,\n): OnboardingTheme => {\n if (!override) return defaultOnboardingTheme;\n return {\n colors: { ...defaultOnboardingTheme.colors, ...override.colors },\n fonts: { ...defaultOnboardingTheme.fonts, ...override.fonts },\n radius: { ...defaultOnboardingTheme.radius, ...override.radius },\n spacing: { ...defaultOnboardingTheme.spacing, ...override.spacing },\n button: { ...defaultOnboardingTheme.button, ...override.button },\n };\n};\n","/**\n * ThemeContext — provides the resolved OnboardingTheme to every shell element and\n * themed card via `useOnboardingTheme()`. WHY a context rather than prop-drilling:\n * the cards are mounted by the SDK's ComponentRenderer (not by us), so we can't\n * pass them props directly — they must read the theme from context.\n *\n * ── WHY THE CONTEXT LIVES ON A `Symbol.for` SLOT ───────────────────────────────────────────────\n *\n * It was a plain `createContext(...)`, and tsup inlines this module into FIVE dist bundles\n * (`.`, `./reviews`, `./questionnaire`, `./coachmarks`, `./showcase`) — so each one carried its own\n * context instance. `OnboardingThemeProvider` is exported ONLY from the root barrel, so on any\n * `dist` resolution path (plain RN CLI, `unstable_enablePackageExports: false`, node, jest, SSR) a\n * host that wrapped its tree in `<OnboardingThemeProvider>` and rendered `<ReviewGate>` from\n * `@wireai/activation/reviews` was writing one context and reading another. Nothing crashed and\n * nothing warned: `useOnboardingTheme`'s `ctx ?? mergeTheme()` fallback quietly served the NEUTRAL\n * default theme, so the tenant's brand simply did not apply to the gate. On-device this was masked\n * only because Metro's `react-native` export condition collapses every subpath back to this one\n * `src/` file — the same \"bundler accident, not a guarantee\" the `currentSession` header names, and\n * the same root cause as the optional-peers bug 0.13.3 fixed.\n *\n * The bundler-agnostic fix, exactly as `coachmarks/runtime`, `analytics/currentSession`,\n * `context/deviceId` and `features/WireFeaturesProvider` already do it: park the ONE context on a\n * well-known `globalThis` slot keyed by `Symbol.for(...)`. `Symbol.for` uses the runtime-global\n * symbol registry, so every inlined copy of this module resolves the SAME symbol, finds the slot\n * already filled, and reuses that instance — one context identity however many copies exist.\n * `globalThis` is present and identical in Hermes/React Native, Node and SSR (we never touch\n * `window`), so this is safe on every host. `test/canary/themeContextIdentity.test.tsx` measures it\n * in the BUILT artifact, because the defect is invisible in source.\n */\nimport React, { createContext, useContext, useMemo } from \"react\";\nimport { mergeTheme } from \"./defaultTheme\";\nimport type { OnboardingTheme } from \"./types\";\n\n/**\n * Well-known key into the runtime-global symbol registry. `Symbol.for` (NOT a plain `Symbol()`) is\n * what makes this cross-bundle: it returns the SAME symbol for the same string across every copy of\n * this module, so duplicated inlined copies all address one slot.\n *\n * @globalSlot LATCH — the React context object is minted by the first copy of this module to load\n * and every later copy ADOPTS it (the `if (!…)` guard below says so in one line). A second write\n * re-splits the identity: `<OnboardingThemeProvider>` (root barrel only) publishes into one context\n * while `<ReviewGate>` from a subpath reads another, and `useOnboardingTheme`'s `ctx ?? mergeTheme()`\n * fallback quietly serves the NEUTRAL theme. Because it is a latch, and only because of that, the\n * module-local `const OnboardingThemeContext` below may cache it.\n */\nconst THEME_CONTEXT_SLOT: unique symbol = Symbol.for(\"@wireai/activation:themeContext\");\n\ntype GlobalWithThemeContext = typeof globalThis & {\n [THEME_CONTEXT_SLOT]?: React.Context<OnboardingTheme | null>;\n};\n\nconst themeGlobal = globalThis as GlobalWithThemeContext;\n\n// First copy to load creates the context; every later copy adopts it. Never overwrite an existing\n// slot — a second `createContext` here would re-split the identity this guard exists to keep whole.\nif (!themeGlobal[THEME_CONTEXT_SLOT]) {\n themeGlobal[THEME_CONTEXT_SLOT] = createContext<OnboardingTheme | null>(null);\n}\nconst OnboardingThemeContext = themeGlobal[THEME_CONTEXT_SLOT] as React.Context<OnboardingTheme | null>;\n\nexport type OnboardingThemeProviderProps = {\n /** Partial overrides merged over the neutral default theme. */\n theme?: Partial<OnboardingTheme>;\n children: React.ReactNode;\n};\n\nexport const OnboardingThemeProvider: React.FC<OnboardingThemeProviderProps> = ({\n theme,\n children,\n}) => {\n const resolved = useMemo(() => mergeTheme(theme), [theme]);\n return (\n <OnboardingThemeContext.Provider value={resolved}>\n {children}\n </OnboardingThemeContext.Provider>\n );\n};\n\n/**\n * Read the active theme. Falls back to the default theme when used outside a\n * provider so a stray card never crashes — it just renders neutral.\n */\nexport const useOnboardingTheme = (): OnboardingTheme => {\n const ctx = useContext(OnboardingThemeContext);\n return ctx ?? mergeTheme();\n};\n","/**\n * expoBlur — resolve `expo-blur`'s `BlurView`, lazily and optionally.\n *\n * ── WHY THIS DOES NOT BREAK THE NO-NATIVE-DEPENDENCY POLICY ──────────────────────────────\n *\n * `expo-blur` is an OPTIONAL peer of the coachmarks subpath. The spotlight overlay frosts the\n * screen with it WHEN it is installed, and degrades to a plain dimmed scrim when it is not — the\n * ring, tooltip and gestures behave identically either way (see SpotlightOverlay). So a host that\n * never installs `expo-blur` can still run the guided tour, and the free tier that must load under\n * Expo Go is not forced into a native module it cannot take.\n *\n * Before this file, `SpotlightOverlay` did `import { BlurView } from \"expo-blur\"` at module scope,\n * and `coachmarks/index.ts` re-exports the overlay with no wildcard escape — so importing ANYTHING\n * from `@wireai/activation/coachmarks`, even `setCoachmarkStorage`, dragged the peer in and a host\n * without it hit a Metro resolution failure. This resolver removes that static edge.\n *\n * ── THE SPECIFIER MUST BE A STRING LITERAL, INSIDE A TRY/CATCH ───────────────────────────\n *\n * This follows `icons/expoIcons.ts` exactly, and its header carries the full autopsy. In short:\n *\n * • Metro collects dependencies STATICALLY, matching a call whose callee is literally the\n * identifier `require` and whose argument is a STRING LITERAL. A variable specifier\n * (`const req = require; req(name)`) is collected NOWHERE, so the module never enters the\n * bundle — and the aliased `require` is Metro's own numeric-id-keyed `metroRequire`, which can\n * never resolve a package-name string. That shape shipped broken once; do not restore it.\n * • The call sitting inside a TRY/CATCH is literally how Metro marks the dependency `isOptional`:\n * when the peer is absent Metro puts `null` in the dependencyMap and the require throws \"Cannot\n * find module\" straight into the catch below. Do NOT \"simplify\" the try/catch away — it is what\n * keeps the peer optional, not just tidy. (`withWireOnboarding` in metro/index.js adds a\n * stub-to-empty-module safety net for hosts that disable Metro's `allowOptionalDependencies`.)\n */\nimport type { ComponentType } from \"react\";\n\n// Metro injects a module-scoped `require`; it is ABSENT in a pure-ESM runtime (the kit's own\n// tests run under `node --test` as ESM). Declared locally so this type-checks without ambient\n// Node types; the `typeof` guard keeps the reference ESM-safe.\ndeclare const require: ((id: string) => unknown) | undefined;\n\n/** A `require`-like resolver. Injectable in tests; production uses the guarded literal require. */\nexport type OptionalRequire = (moduleName: string) => unknown;\n\n/** The minimal prop shape the overlay uses from `expo-blur`'s `BlurView`. */\nexport type BlurViewComponent = ComponentType<{\n intensity?: number;\n tint?: \"light\" | \"dark\" | \"default\";\n style?: unknown;\n children?: unknown;\n}>;\n\n/**\n * The production resolver. The specifier is a LITERAL so Metro collects it (see the header); the\n * `moduleName` parameter exists only to keep the `OptionalRequire` seam shape, so anything other\n * than the one module this file owns resolves to undefined.\n */\nconst runtimeRequire: OptionalRequire = (moduleName) => {\n if (moduleName !== \"expo-blur\") return undefined;\n if (typeof require !== \"function\") return undefined;\n try {\n return require(\"expo-blur\");\n } catch {\n return undefined;\n }\n};\n\n/**\n * TEST-ONLY seam. `SpotlightOverlay`'s public props are frozen, so it cannot take a `requireModule`\n * the way `WireIcon` does — this lets a component render exercise the PRESENT path without the\n * native peer installed. Production never sets it; `runtimeRequire` is the only resolver.\n */\nlet testRequire: OptionalRequire | undefined;\nexport const __setBlurRequireForTests = (fn: OptionalRequire | undefined): void => {\n testRequire = fn;\n cached = undefined;\n};\n\n/** Read a module's `default` (Expo modules are consumed as default exports) or the namespace. */\nconst interop = (mod: unknown): Record<string, unknown> | undefined => {\n if (!mod || typeof mod !== \"object\") return undefined;\n const ns = mod as Record<string, unknown>;\n // `expo-blur` exposes `BlurView` as a NAMED export; prefer the namespace when it already carries\n // it, and only fall back to `default` for a CJS-interop wrapper.\n if (ns.BlurView) return ns;\n const def = (mod as { default?: unknown }).default;\n if (def && typeof def === \"object\") return def as Record<string, unknown>;\n return ns;\n};\n\n/**\n * Narrow an unknown export to something mountable. `BlurView` is a real React component (function\n * or class across versions), and React.memo / forwardRef wrappers are objects carrying `$$typeof`.\n * Reject anything else rather than handing the reconciler a non-component.\n */\nconst asComponent = (value: unknown): BlurViewComponent | undefined => {\n if (typeof value === \"function\") return value as BlurViewComponent;\n if (value && typeof value === \"object\" && \"$$typeof\" in (value as object)) {\n return value as BlurViewComponent;\n }\n return undefined;\n};\n\n/**\n * Module-level memo. `null` = \"we looked and it is not there\" (distinct from \"not looked yet\"),\n * so an absent peer costs exactly one failed require per process, not one per overlay mount.\n */\nlet cached: BlurViewComponent | null | undefined;\n\n/** Reset the memo. TEST-ONLY seam — production never calls it. */\nexport const resetBlurModuleCache = (): void => {\n cached = undefined;\n};\n\n/**\n * Resolve the `BlurView` component, or undefined when the peer is absent/unresolvable.\n * Never throws: an absent blur must degrade to a plain scrim, never break the tour.\n *\n * `requireModule` is injectable so tests can exercise BOTH the found and absent paths without\n * installing the native peer (same convention as `resolveIconFamily` / `detectAppVersion`).\n */\nexport const resolveBlurView = (\n requireModule: OptionalRequire = testRequire ?? runtimeRequire,\n): BlurViewComponent | undefined => {\n try {\n if (cached === undefined || requireModule !== runtimeRequire) {\n const resolved = interop(requireModule(\"expo-blur\"));\n const component = resolved ? asComponent(resolved.BlurView) : undefined;\n // Don't poison the module memo from an injected test require.\n if (requireModule === runtimeRequire) cached = component ?? null;\n return component;\n }\n if (cached === null) return undefined;\n return cached;\n } catch {\n return undefined;\n }\n};\n","import React, { useEffect, useMemo, type ReactNode } from \"react\";\nimport { StyleSheet, View } from \"react-native\";\nimport Animated, {\n useAnimatedStyle,\n useReducedMotion,\n useSharedValue,\n withDelay,\n withRepeat,\n withSequence,\n withTiming,\n} from \"react-native-reanimated\";\n\nimport type { GestureKind } from \"./types\";\n\n/**\n * Abstract gesture pictogram shown beside a coachmark tooltip. Pure reanimated —\n * every animation runs on the UI thread (shared values + worklets), never\n * setState, so it costs nothing on the JS thread. Honors Reduce Motion by\n * dropping the motion loop and rendering the glyph static.\n *\n * NO drawn-hand anatomy. Swipes render the standard two-finger swipe glyph: two\n * rounded vertical capsules (an abstract index + middle finger, slightly\n * different heights) with a short, fading motion track trailing behind them along\n * the swipe axis. The whole glyph is rotated per direction (up/down/left/right)\n * and the capsules slide along the axis, fading, in a UI-thread loop. Pinch/zoom\n * reuse the two-capsule abstraction spreading apart. Tap / double-tap render a\n * minimal pulsing tap-target (ring + dot).\n *\n * Every glyph is a self-drawn primitive built from Views/borders (no vector-icon\n * dependency, like AnimatedSparkle). Pass `renderHand` — the glyph slot — to\n * substitute your own node while keeping the tuned motion. (The name is kept for\n * backward compatibility; despite it, the default is a glyph, not a drawn hand.)\n *\n * NOTE: the coachmark path (SpotlightOverlay) and the showcase path\n * (FeatureShowcase) both SKIP this component for `tap` / `double_tap` — those\n * steps show only the highlight ring + tooltip, no glyph. The tap visual here\n * exists for direct / standalone use.\n */\nexport interface GestureHintProps {\n type: GestureKind;\n /** Overall glyph size in px. */\n size?: number;\n /** Glyph color. Defaults to white (reads on the dark blur backdrop). */\n color?: string;\n /**\n * Provide a custom glyph node in place of the default self-drawn primitive; it\n * inherits the tuned motion (slide+fade for swipes, pulse for tap). Kept as\n * `renderHand` for backward compatibility — despite the name it is just the\n * glyph slot, no longer a drawn hand.\n */\n renderHand?: (props: { size: number; color: string }) => ReactNode;\n}\n\n/** Travel distance for the directional swipe loop (local glyph axis). */\nconst TRAVEL = 26;\nconst SWIPE_MS = 700;\nconst TAP_MS = 320;\nconst SPREAD_MS = 620;\n\n/**\n * Per-direction rotation of the whole glyph. Canonical orientation is \"up\":\n * capsules point up, travel up, motion track trailing below. Rotating the\n * container reorients both the capsules and the track together, and rotates the\n * local translate axis so the same upward loop reads correctly per direction.\n */\nconst GLYPH_ROTATION: Record<string, string> = {\n swipe_up: \"0deg\",\n swipe_down: \"180deg\",\n swipe_left: \"-90deg\",\n swipe_right: \"90deg\",\n};\n\n/**\n * The two-finger abstraction: two rounded vertical capsules side by side with\n * slightly different heights (index taller than middle), aligned at the base —\n * the standard swipe pictogram look. Self-drawn from Views only.\n */\nconst FingerPair: React.FC<{ size: number; color: string }> = ({ size, color }) => {\n const { row, index, middle } = useMemo(() => {\n const w = size * 0.2;\n const r = w / 2;\n return {\n row: { flexDirection: \"row\" as const, alignItems: \"flex-end\" as const, gap: size * 0.08 },\n index: { width: w, height: size * 0.54, borderRadius: r, backgroundColor: color },\n middle: { width: w, height: size * 0.44, borderRadius: r, backgroundColor: color },\n };\n }, [size, color]);\n\n return (\n <View style={row} pointerEvents=\"none\">\n <View style={index} />\n <View style={middle} />\n </View>\n );\n};\n\n/**\n * A short, tapering motion track that sits behind the capsules (below, in the\n * canonical \"up\" orientation) — two slim, fading ticks that shrink and dim with\n * distance. Subtle: it reads as the path the fingers just travelled, not a comet\n * tail. Static (the capsules carry the motion via the slide loop).\n */\nconst MotionTrack: React.FC<{ size: number; color: string }> = ({ size, color }) => {\n const { wrap, tick0, tick1 } = useMemo(() => {\n const h = Math.max(2, size * 0.05);\n return {\n wrap: { alignItems: \"center\" as const, marginTop: size * 0.1, gap: size * 0.06 },\n tick0: {\n width: size * 0.3,\n height: h,\n borderRadius: h / 2,\n backgroundColor: color,\n opacity: 0.4,\n },\n tick1: {\n width: size * 0.18,\n height: h,\n borderRadius: h / 2,\n backgroundColor: color,\n opacity: 0.16,\n },\n };\n }, [size, color]);\n\n return (\n <View style={wrap} pointerEvents=\"none\">\n <View style={tick0} />\n <View style={tick1} />\n </View>\n );\n};\n\nconst GestureHintComponent: React.FC<GestureHintProps> = ({\n type,\n size = 34,\n color = \"white\",\n renderHand,\n}) => {\n const translate = useSharedValue(0);\n const opacity = useSharedValue(1);\n const pulse = useSharedValue(1);\n const spread = useSharedValue(0);\n const reduced = useReducedMotion();\n\n const isSwipe =\n type === \"swipe_up\" ||\n type === \"swipe_down\" ||\n type === \"swipe_left\" ||\n type === \"swipe_right\";\n const isSpread = type === \"pinch\" || type === \"zoom\";\n const isTap = type === \"tap\" || type === \"double_tap\";\n\n useEffect(() => {\n if (type === \"none\" || reduced) return undefined;\n\n if (isTap) {\n pulse.value = withRepeat(\n withSequence(\n withTiming(0.82, { duration: TAP_MS }),\n withTiming(1, { duration: TAP_MS }),\n ),\n -1,\n false,\n );\n opacity.value = withRepeat(\n withSequence(\n withTiming(0.55, { duration: TAP_MS }),\n withTiming(1, { duration: TAP_MS }),\n ),\n -1,\n false,\n );\n return undefined;\n }\n\n if (isSpread) {\n // Two capsules easing apart and back — a minimal pinch/zoom abstraction.\n spread.value = withRepeat(\n withSequence(\n withTiming(size * 0.26, { duration: SPREAD_MS }),\n withTiming(0, { duration: SPREAD_MS }),\n ),\n -1,\n false,\n );\n return undefined;\n }\n\n // Directional swipe: slide the capsules along the local \"up\" axis, fading\n // out, then snap back and repeat. The container rotation (below) reorients\n // this loop per direction, so the local motion is always the same.\n translate.value = withRepeat(\n withSequence(\n withTiming(0, { duration: 0 }),\n withTiming(-TRAVEL, { duration: SWIPE_MS }),\n withDelay(140, withTiming(0, { duration: 0 })),\n ),\n -1,\n false,\n );\n opacity.value = withRepeat(\n withSequence(\n withTiming(1, { duration: SWIPE_MS / 2 }),\n withTiming(0, { duration: SWIPE_MS / 2 }),\n withDelay(140, withTiming(1, { duration: 0 })),\n ),\n -1,\n false,\n );\n return undefined;\n }, [type, reduced, isTap, isSpread, translate, opacity, pulse, spread, size]);\n\n const swipeAnimatedStyle = useAnimatedStyle(() => ({\n opacity: opacity.value,\n transform: [{ translateY: translate.value }],\n }));\n const tapAnimatedStyle = useAnimatedStyle(() => ({\n opacity: opacity.value,\n transform: [{ scale: pulse.value }],\n }));\n const spreadLeftStyle = useAnimatedStyle(() => ({\n transform: [{ translateX: -spread.value }],\n }));\n const spreadRightStyle = useAnimatedStyle(() => ({\n transform: [{ translateX: spread.value }],\n }));\n\n if (type === \"none\") return null;\n\n const customGlyph = renderHand ? renderHand({ size, color }) : null;\n\n if (isSwipe) {\n return (\n <View\n style={{ transform: [{ rotate: GLYPH_ROTATION[type] ?? \"0deg\" }] }}\n pointerEvents=\"none\"\n >\n <View style={styles.swipeStack}>\n <Animated.View style={swipeAnimatedStyle} pointerEvents=\"none\">\n {customGlyph ?? <FingerPair size={size} color={color} />}\n </Animated.View>\n <MotionTrack size={size} color={color} />\n </View>\n </View>\n );\n }\n\n if (isSpread) {\n const w = size * 0.2;\n const capsule = {\n width: w,\n height: size * 0.5,\n borderRadius: w / 2,\n backgroundColor: color,\n };\n return (\n <View style={[styles.spreadRow, { gap: size * 0.12 }]} pointerEvents=\"none\">\n <Animated.View style={spreadLeftStyle}>\n <View style={capsule} />\n </Animated.View>\n <Animated.View style={spreadRightStyle}>\n <View style={capsule} />\n </Animated.View>\n </View>\n );\n }\n\n // tap / double_tap — a minimal pulsing tap-target (ring + center dot).\n const ringSize = size * 0.86;\n const ringBorder = Math.max(2, size * 0.08);\n const dotSize = size * 0.32;\n return (\n <View style={[styles.tapWrap, { width: size, height: size }]} pointerEvents=\"none\">\n {customGlyph ? (\n <Animated.View style={tapAnimatedStyle} pointerEvents=\"none\">\n {customGlyph}\n </Animated.View>\n ) : (\n <>\n <Animated.View\n style={[\n styles.tapRing,\n {\n width: ringSize,\n height: ringSize,\n borderRadius: ringSize / 2,\n borderWidth: ringBorder,\n borderColor: color,\n },\n tapAnimatedStyle,\n ]}\n pointerEvents=\"none\"\n />\n <View\n style={{\n position: \"absolute\",\n width: dotSize,\n height: dotSize,\n borderRadius: dotSize / 2,\n backgroundColor: color,\n }}\n />\n </>\n )}\n </View>\n );\n};\n\nconst styles = StyleSheet.create({\n swipeStack: {\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n spreadRow: {\n flexDirection: \"row\",\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n tapWrap: {\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n tapRing: {\n backgroundColor: \"transparent\",\n },\n});\n\nexport const GestureHint = React.memo(GestureHintComponent);\nGestureHint.displayName = \"GestureHint\";\n\nexport default GestureHint;\n","import React, { useEffect, useMemo } from \"react\";\nimport {\n Pressable,\n StyleSheet,\n Text,\n useWindowDimensions,\n View,\n} from \"react-native\";\nimport Animated, {\n FadeIn,\n FadeOut,\n useAnimatedProps,\n useAnimatedStyle,\n useReducedMotion,\n useSharedValue,\n withRepeat,\n withSequence,\n withTiming,\n} from \"react-native-reanimated\";\n\nimport { useOnboardingTheme } from \"../theme/ThemeContext\";\nimport { resolveBlurView } from \"./expoBlur\";\nimport { GestureHint } from \"./GestureHint\";\nimport type { GestureKind, Placement, TargetRect } from \"./types\";\n\nconst BLUR_INTENSITY = 26;\nconst FADE_MS = 280;\n/** Breathing room between the highlighted element and the glowing ring. */\nconst RING_PADDING = 10;\n/** Gap between the ring and the tooltip pill. */\nconst TOOLTIP_GAP = 14;\nconst SIDE_MARGIN = 20;\nconst PILL_MAX_WIDTH = 260;\n\nexport interface SpotlightOverlayProps {\n message: string;\n /** Window-space rect of the element to highlight. Null → centered hint (e.g. a scroll gesture). */\n targetRect?: TargetRect | null;\n gesture?: GestureKind;\n placement?: Placement;\n /** Tapping the highlighted target or the pill — advance / act. */\n onEngage: () => void;\n /** Tapping the dimmed backdrop — advance to the next step (ends the tour only on the last step). */\n onDismiss: () => void;\n /** Ring + tooltip color. Defaults to the onboarding theme's `primary`. */\n accentColor?: string;\n /** Tooltip label color. Defaults to the theme's `onPrimary`. */\n accentTextColor?: string;\n}\n\n/**\n * A single coachmark step: the whole screen is frosted with an animated blur\n * (or a plain dimmed scrim when the optional `expo-blur` peer is absent), and a\n * bright pulsing ring + tooltip point at one measured target. Mounted at the app\n * root (above the tab bar) via CoachmarkOverlayHost.\n *\n * Performance: one BlurView (mounted only while a step is visible), the ring\n * glow is a single reanimated view, and all animation runs on the UI thread.\n * Reduce Motion drops the pulse.\n *\n * `expo-blur` is OPTIONAL. It is resolved through a guarded lazy require (see\n * `expoBlur.ts`) and the animated component is built once on first use, so the\n * subpath never carries a static top-level import of the peer. When it is not\n * installed the frost drops to an equivalent dimmed scrim — a decorative frost\n * missing must never blank a tour, so the ring, copy and gestures are unchanged.\n */\nconst SpotlightOverlayComponent: React.FC<SpotlightOverlayProps> = ({\n message,\n targetRect,\n gesture = \"none\",\n placement = \"bottom\",\n onEngage,\n onDismiss,\n accentColor,\n accentTextColor,\n}) => {\n const { height: screenH } = useWindowDimensions();\n const reduced = useReducedMotion();\n const theme = useOnboardingTheme();\n\n const accent = accentColor ?? theme.colors.primary;\n const accentText = accentTextColor ?? theme.colors.onPrimary;\n\n // Resolve the optional `expo-blur` peer and build its animated component ONCE, on first render,\n // instead of at module scope — so merely importing this file (and thus the coachmarks subpath)\n // never needs the peer. `null` = the peer is absent → the scrim path renders instead.\n const AnimatedBlurView = useMemo(() => {\n const BlurView = resolveBlurView();\n return BlurView ? Animated.createAnimatedComponent(BlurView) : null;\n }, []);\n\n // Tap / double-tap steps show ONLY the ring + tooltip — no gesture glyph. The\n // pulsing highlight ring already reads as \"tap here\", so an extra glyph is\n // noise. Every app inherits this centrally, with no config change.\n const showGesture =\n gesture !== \"none\" && gesture !== \"tap\" && gesture !== \"double_tap\";\n\n const intensity = useSharedValue(0);\n const ringScale = useSharedValue(1);\n\n useEffect(() => {\n intensity.value = withTiming(BLUR_INTENSITY, { duration: FADE_MS });\n }, [intensity]);\n\n useEffect(() => {\n if (reduced) return;\n ringScale.value = withRepeat(\n withSequence(\n withTiming(1.06, { duration: 700 }),\n withTiming(1, { duration: 700 }),\n ),\n -1,\n true,\n );\n }, [reduced, ringScale]);\n\n const blurAnimatedProps = useAnimatedProps(() => ({\n intensity: intensity.value,\n }));\n\n const ringAnimatedStyle = useAnimatedStyle(() => ({\n transform: [{ scale: ringScale.value }],\n }));\n\n // Geometry for the ring + tooltip, derived from the measured target.\n const geometry = useMemo(() => {\n if (!targetRect) return null;\n const ringLeft = targetRect.x - RING_PADDING;\n const ringTop = targetRect.y - RING_PADDING;\n const ringW = targetRect.width + RING_PADDING * 2;\n const ringH = targetRect.height + RING_PADDING * 2;\n return {\n ring: {\n left: ringLeft,\n top: ringTop,\n width: ringW,\n height: ringH,\n borderRadius: Math.min(ringW, ringH) / 2,\n },\n // Tooltip above or below the ring depending on placement.\n tooltip:\n placement === \"top\"\n ? { bottom: screenH - ringTop + TOOLTIP_GAP }\n : { top: ringTop + ringH + TOOLTIP_GAP },\n };\n }, [targetRect, placement, screenH]);\n\n return (\n <Animated.View\n style={[StyleSheet.absoluteFill, styles.root]}\n entering={FadeIn.duration(FADE_MS)}\n exiting={FadeOut.duration(FADE_MS)}\n >\n {AnimatedBlurView ? (\n <AnimatedBlurView\n tint=\"dark\"\n animatedProps={blurAnimatedProps}\n style={StyleSheet.absoluteFill}\n />\n ) : (\n // `expo-blur` absent → a plain dimmed scrim stands in for the frost. Same dark backdrop\n // the tour reads against, so the ring, tooltip and gestures behave identically.\n <Animated.View\n style={[StyleSheet.absoluteFill, styles.scrim]}\n pointerEvents=\"none\"\n />\n )}\n\n {/* Tap-the-backdrop to move on (dismisses the tour on the last step). */}\n <Pressable\n style={StyleSheet.absoluteFill}\n onPress={onDismiss}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Next hint\"\n />\n\n {/* Glowing ring over the highlighted target (tap = engage). */}\n {geometry && (\n <Animated.View\n style={[\n styles.ring,\n geometry.ring,\n { borderColor: accent, shadowColor: accent },\n ringAnimatedStyle,\n ]}\n pointerEvents=\"box-none\"\n >\n <Pressable\n style={StyleSheet.absoluteFill}\n onPress={onEngage}\n accessibilityRole=\"button\"\n accessibilityLabel={message}\n />\n </Animated.View>\n )}\n\n {/* Tooltip pill: anchored to the ring, or centered for a target-less hint. */}\n <View\n style={[\n styles.tooltipWrapper,\n geometry\n ? geometry.tooltip\n : { top: screenH * 0.42, alignItems: \"center\" },\n ]}\n pointerEvents=\"box-none\"\n >\n {showGesture && (\n <View style={styles.gestureSlot} pointerEvents=\"none\">\n <GestureHint type={gesture} color={accent} />\n </View>\n )}\n <Pressable\n onPress={onEngage}\n style={[styles.pill, { backgroundColor: accent }]}\n accessibilityRole=\"button\"\n accessibilityLabel={message}\n >\n <Text numberOfLines={3} style={[styles.pillText, { color: accentText }]}>\n {message}\n </Text>\n </Pressable>\n </View>\n </Animated.View>\n );\n};\n\nconst styles = StyleSheet.create({\n // High elevation/zIndex so the whole overlay (incl. the frosted blur) sits\n // above the bottom tab bar on Android, where sibling z-order follows\n // elevation, not tree order.\n root: {\n zIndex: 9999,\n elevation: 9999,\n },\n // Fallback backdrop when `expo-blur` is absent. A structural dim (not a brand token), tuned to\n // read like the dark blur at BLUR_INTENSITY so the ring + tooltip keep the same contrast.\n scrim: {\n backgroundColor: \"rgba(0, 0, 0, 0.55)\",\n },\n ring: {\n position: \"absolute\",\n borderWidth: 2.5,\n backgroundColor: \"transparent\",\n shadowOffset: { width: 0, height: 0 },\n shadowOpacity: 0.9,\n shadowRadius: 12,\n elevation: 10,\n },\n tooltipWrapper: {\n position: \"absolute\",\n left: SIDE_MARGIN,\n right: SIDE_MARGIN,\n alignItems: \"center\",\n gap: 10,\n },\n gestureSlot: {\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n pill: {\n maxWidth: PILL_MAX_WIDTH,\n paddingVertical: 12,\n paddingHorizontal: 18,\n borderRadius: 18,\n shadowColor: \"#000\",\n shadowOffset: { width: 0, height: 2 },\n shadowOpacity: 0.25,\n shadowRadius: 6,\n elevation: 6,\n },\n pillText: {\n fontSize: 14,\n fontWeight: \"800\",\n textAlign: \"center\",\n },\n});\n\nexport const SpotlightOverlay = React.memo(SpotlightOverlayComponent);\nSpotlightOverlay.displayName = \"SpotlightOverlay\";\n\nexport default SpotlightOverlay;\n","import React from \"react\";\n\nimport { useCoachmarkOverlay } from \"./coachmarkOverlayStore\";\nimport { SpotlightOverlay } from \"./SpotlightOverlay\";\n\nexport interface CoachmarkOverlayHostProps {\n /** Ring/tooltip accent; defaults to the onboarding theme's `primary`. */\n accentColor?: string;\n /** Text/icon color on the accent surface; defaults to the theme's `onPrimary`. */\n accentTextColor?: string;\n}\n\n/**\n * Mounts once at the app root (rendered by CoachmarkProvider as a sibling of the\n * app tree) so the blur + spotlight paint OVER the bottom tab bar — which\n * react-navigation renders above screen components, out of reach of any\n * screen-level overlay. Renders nothing until a step is active.\n */\nconst CoachmarkOverlayHostComponent: React.FC<CoachmarkOverlayHostProps> = ({\n accentColor,\n accentTextColor,\n}) => {\n const active = useCoachmarkOverlay();\n\n if (!active) return null;\n\n return (\n <SpotlightOverlay\n message={active.message}\n targetRect={active.targetRect}\n gesture={active.gesture}\n placement={active.placement}\n onEngage={active.onEngage}\n onDismiss={active.onDismiss}\n accentColor={accentColor}\n accentTextColor={accentTextColor}\n />\n );\n};\n\nexport const CoachmarkOverlayHost = React.memo(CoachmarkOverlayHostComponent);\nCoachmarkOverlayHost.displayName = \"CoachmarkOverlayHost\";\n\nexport default CoachmarkOverlayHost;\n","import React, { useEffect } from \"react\";\n\nimport { useResolvedFeatures } from \"../features/WireFeaturesProvider\";\nimport type { WireFeatures, WireFeaturesConfig } from \"../features/types\";\nimport { CoachmarkOverlayHost } from \"./CoachmarkOverlayHost\";\nimport {\n getCoachmarkStorage,\n setCoachmarkStorage,\n setCoachmarksEnabled,\n setCoachmarkTesting,\n} from \"./runtime\";\nimport type { CoachmarkStorage } from \"./types\";\n\nexport interface CoachmarkProviderProps {\n /**\n * SYNCHRONOUS gate storage (MMKV-friendly). Reads must not be async or a ring\n * would flash before the \"already seen\" gate resolves. See CoachmarkStorage.\n */\n storage: CoachmarkStorage;\n /**\n * QA replay switch. When true, every seen-gate reads as unseen AND seen-writes\n * are suppressed, so every tour + showcase replays on each mount. Flip ONE\n * boolean to re-see the whole coachmark surface.\n */\n isTestingCoachmark?: boolean;\n /** Ring + tooltip color for every tour. Defaults to the onboarding theme's `primary`. */\n accentColor?: string;\n /**\n * Text/icon color on the accent surface (e.g. the tooltip's CTA label).\n * Defaults to the onboarding theme's `onPrimary`.\n */\n accentTextColor?: string;\n /**\n * OPTIONAL feature-flag wiring. When `flags.coachmarks.enabled` is false, every tour + overlay\n * request becomes a silent no-op (once-gates are NOT consumed, so re-enabling replays). Provide\n * pre-resolved `features`, OR a `featuresConfig` (serverUrl + apiKey) to lazily fetch once, OR\n * mount a `WireFeaturesProvider` above (context is read automatically). Omit all three and\n * coachmarks stay on (fail-open) — zero behavior change for hosts that never adopt flags.\n */\n features?: WireFeatures;\n /** Lazy-fetch config for the flags, used when `features` is absent and no provider is above. */\n featuresConfig?: WireFeaturesConfig;\n children: React.ReactNode;\n}\n\n/**\n * Mount ONCE at the app root — wrap it around (or just inside) your\n * NavigationContainer so the overlay host is a root-level sibling of the whole\n * app tree. That placement is what lets a ring + blur paint ABOVE the bottom tab\n * bar, which react-navigation renders over screen components.\n *\n * It feeds the sync storage + testing flag into the engine's module-level\n * singletons so `useCoachmarkTour` / `useCoachmarkAnchor` work from anywhere in\n * the tree without prop-drilling, then renders the overlay host as a sibling\n * after `children` (the SpotlightOverlay self-positions absolute-fill at\n * zIndex/elevation 9999).\n *\n * The singletons are set during render (not in an effect) so a child's mount\n * effect — which runs BEFORE this parent's effects — already sees the storage\n * when it reads its gate.\n */\nexport const CoachmarkProvider: React.FC<CoachmarkProviderProps> = ({\n storage,\n isTestingCoachmark = false,\n accentColor,\n accentTextColor,\n features,\n featuresConfig,\n children,\n}) => {\n // Resolve the coachmarks kill switch: explicit `features` → context → lazy fetch → all-on.\n const flags = useResolvedFeatures({ flags: features, config: featuresConfig });\n const coachmarksOn = flags.coachmarks.enabled;\n\n // Apply during render so gates + the kill switch are readable before any child effect fires.\n setCoachmarkStorage(storage);\n setCoachmarkTesting(isTestingCoachmark);\n setCoachmarksEnabled(coachmarksOn);\n\n useEffect(() => {\n setCoachmarkStorage(storage);\n setCoachmarkTesting(isTestingCoachmark);\n setCoachmarksEnabled(coachmarksOn);\n return () => {\n // Only clear if THIS provider's storage is still the live singleton — a\n // newer provider that mounted before this one unmounts must not be wiped.\n if (getCoachmarkStorage() === storage) {\n setCoachmarkStorage(null);\n }\n // Restore the fail-open default so a torn-down provider never leaves coachmarks dark.\n setCoachmarksEnabled(true);\n };\n }, [storage, isTestingCoachmark, coachmarksOn]);\n\n return (\n <>\n {children}\n <CoachmarkOverlayHost\n accentColor={accentColor}\n accentTextColor={accentTextColor}\n />\n </>\n );\n};\n\nCoachmarkProvider.displayName = \"CoachmarkProvider\";\n\nexport default CoachmarkProvider;\n","import type { TargetRect } from \"./types\";\n\n/**\n * Maps a coachmark anchor id → a function that measures that element's current\n * window rect. Elements register themselves on mount (via useCoachmarkAnchor)\n * and the tour controller resolves an id to a rect at the moment a step fires.\n *\n * This is the \"app declares WHERE\" half of the engine: the kit owns the\n * measuring/registry mechanics, each app decides which ids exist and pins them\n * to its own components.\n */\nexport type AnchorMeasurer = () => Promise<TargetRect | null>;\n\nconst anchors = new Map<string, AnchorMeasurer>();\n\n/**\n * NOTE: this registry is last-writer-wins — one measurer per id. An `anchorId`\n * MUST be unique across screens that can be mounted simultaneously; if two live\n * screens share an id, the second registration hides the first and unmount order\n * decides who survives. Scope ids per screen (e.g. `feed.filter_icon`) when a\n * component can appear in more than one mounted screen at once.\n */\nexport const coachmarkAnchors = {\n register(id: string, measurer: AnchorMeasurer) {\n anchors.set(id, measurer);\n },\n /**\n * Only clears the id when `measurer` is still the current registration, so a\n * screen unmounting after a newer screen registered the same id does not wipe\n * the live measurer. Omit `measurer` to force-delete regardless.\n */\n unregister(id: string, measurer?: AnchorMeasurer) {\n if (measurer !== undefined && anchors.get(id) !== measurer) return;\n anchors.delete(id);\n },\n get(id: string): AnchorMeasurer | undefined {\n return anchors.get(id);\n },\n /**\n * Resolve an anchor to a rect, retrying briefly while the target lays out\n * (e.g. the first feed post, or a screen just navigated to). Cancellable via\n * `shouldCancel` so a superseded step abandons its retry loop immediately.\n */\n async resolve(\n id: string,\n {\n retries = 6,\n intervalMs = 120,\n shouldCancel,\n }: {\n retries?: number;\n intervalMs?: number;\n /** Abort the retry loop early (e.g. the step was superseded). */\n shouldCancel?: () => boolean;\n } = {},\n ): Promise<TargetRect | null> {\n for (let attempt = 0; attempt <= retries; attempt++) {\n if (shouldCancel?.()) return null;\n const measurer = anchors.get(id);\n if (measurer) {\n const rect = await measurer();\n if (rect && rect.width > 0 && rect.height > 0) return rect;\n }\n if (attempt < retries) {\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n }\n return null;\n },\n};\n","import { useEffect, useRef } from \"react\";\nimport type { View } from \"react-native\";\n\nimport { coachmarkAnchors } from \"./coachmarkAnchorRegistry\";\nimport type { TargetRect } from \"./types\";\n\n/**\n * Makes any element ringable by a coachmark tour. Attach the returned ref to a\n * plain RN View wrapping the target (use `collapsable={false}` so the native\n * node survives for measurement):\n *\n * const filterAnchor = useCoachmarkAnchor(\"filter_icon\");\n * <View ref={filterAnchor} collapsable={false}>{button}</View>\n *\n * The app decides which ids exist and where they live; the kit measures them at\n * step time via `measureInWindow` (never continuously). Pass `null` to keep the\n * hook's position stable while registering nothing (e.g. a list item that is\n * only an anchor at one index).\n */\nexport const useCoachmarkAnchor = (id: string | null | undefined) => {\n const ref = useRef<View>(null);\n\n useEffect(() => {\n if (!id) return undefined;\n\n const measure = (): Promise<TargetRect | null> =>\n new Promise((resolve) => {\n const node = ref.current;\n if (!node || typeof node.measureInWindow !== \"function\") {\n return resolve(null);\n }\n node.measureInWindow((x, y, width, height) => {\n if (\n [x, y, width, height].some(\n (value) => value == null || Number.isNaN(value),\n )\n ) {\n return resolve(null);\n }\n resolve({ x, y, width, height });\n });\n });\n\n coachmarkAnchors.register(id, measure);\n return () => coachmarkAnchors.unregister(id, measure);\n }, [id]);\n\n return ref;\n};\n","import { useCallback, useEffect, useRef, useState, useSyncExternalStore } from \"react\";\n\nimport { coachmarkAnchors } from \"./coachmarkAnchorRegistry\";\nimport { coachmarkOverlay } from \"./coachmarkOverlayStore\";\nimport {\n areCoachmarksEnabled,\n coachmarkGateKey,\n hasSeenGate,\n markSeenGate,\n subscribeCoachmarksEnabled,\n} from \"./runtime\";\nimport type { CoachmarkStep } from \"./types\";\n\nexport interface UseCoachmarkTourOptions {\n /**\n * Gate key for the whole tour. The kit reads/writes\n * `wire_coachmark_<tourId>_seen` through the injected CoachmarkStorage so the\n * app never owns the \"seen\" bookkeeping (the global testing flag bypasses it).\n */\n tourId: string;\n /** Run at most once ever (persisted via the gate). Default true. */\n showOnce?: boolean;\n /**\n * Domain gate — the tour only arms while this is true (e.g. hasPosts), and it\n * also drives PAUSE/RESUME: if this flips false mid-tour (e.g. the user tab-\n * switches and the screen loses focus without unmounting) the overlay is\n * hidden but the tour's position is kept, and it resumes on the CURRENT step\n * (re-resolving its anchor) when this returns true. See the hook JSDoc.\n */\n enabled: boolean;\n /** Let passive value land before the first hint. */\n startDelayMs?: number;\n /** Fires once the tour finishes or is skipped (after the gate is written). */\n onComplete?: () => void;\n /**\n * Fires once when a step first becomes visible. It is NOT re-fired when the\n * SAME step resumes after a focus-loss pause (the last-shown step id is\n * tracked in a ref and suppressed), so a tab-switch never inflates\n * impressions. It fires again only when the tour advances to a new step.\n */\n onStepShown?: (id: string) => void;\n onStepEngaged?: (id: string) => void;\n onStepDismissed?: (id: string) => void;\n}\n\nconst DEFAULT_START_DELAY_MS = 3000;\n\n/**\n * Plays an ordered queue of coachmark steps on the current screen through the\n * root SpotlightOverlay (mounted by CoachmarkProvider). Engaging a step (tap the\n * ring/tooltip) advances and fires onStepEngaged. Tapping the backdrop advances\n * to the NEXT step and fires onStepDismissed — a stray tap or a \"not now\" never\n * kills the tour; only a backdrop tap on the LAST step ends it. Both terminal\n * paths (engaging past the end, or dismissing the last step) write the seen gate\n * once and call onComplete, so a finished tour never nags again.\n *\n * Gating lives IN the kit: the tour arms only when `enabled` AND (not `showOnce`\n * OR the `tourId` gate is unseen).\n *\n * PAUSE/RESUME on focus loss: `enabled` is a live gate, not just an arm-once\n * trigger. Once armed, if `enabled` goes false while the tour is in flight\n * (started, not finished) — the classic case being a tab-switch that keeps the\n * screen mounted — the drive effect hides the overlay so a stale rect can't\n * float over the wrong screen, but KEEPS `activeIndex` and does NOT write the\n * seen gate. When `enabled` returns true the effect re-runs (it's in the deps)\n * and re-drives the SAME step, re-resolving its anchor so a moved/relaid-out\n * target is picked up. `onStepShown` is suppressed on that resume (last-shown\n * step id is tracked in a ref) so a pause/resume never double-counts a step.\n *\n * KILL SWITCH vs PAUSE — two different gates, two different endings. `enabled` is the host's\n * domain gate and PAUSES (position kept, gate unwritten, resumes on the same step). The tenant's\n * coachmarks feature flag (`setCoachmarksEnabled`, from GET /v1/features) is TERMINAL: flipped off\n * mid-tour it ends the tour and fires `onComplete`, but does NOT write the once-gate, so the tour\n * replays on the next mount once the flag is back on. It is read through a subscription rather\n * than sampled, because the flip has to reach a tour that is already in flight: the overlay's\n * `show()` is a no-op while the flag is off, so a tour that carried on would paint nothing, could\n * not be tapped to advance, and would never reach a terminal state.\n *\n * IMPORTANT: `steps` MUST be a stable (memoized) array. If a new array identity\n * is passed on every render the drive effect re-runs and re-shows the current\n * step (wasteful anchor re-resolves / overlay churn), and analytics can\n * double-fire. Memoize it, or pass an inline module-level constant.\n *\n * Preserved engine invariants: step callbacks live in a ref (not effect deps),\n * anchor resolution is cancellable, and finish is idempotent (only one overlay\n * is ever active, the gate is written once).\n */\nexport const useCoachmarkTour = (\n /** Ordered coachmark steps. MUST be stable/memoized — see the note above. */\n steps: CoachmarkStep[],\n {\n tourId,\n showOnce = true,\n enabled,\n startDelayMs = DEFAULT_START_DELAY_MS,\n onComplete,\n onStepShown,\n onStepEngaged,\n onStepDismissed,\n }: UseCoachmarkTourOptions,\n) => {\n const [activeIndex, setActiveIndex] = useState<number | null>(null);\n const startedRef = useRef(false);\n const finishedRef = useRef(false);\n // Id of the step onStepShown last fired for. Lets us re-drive the current\n // step on a focus-loss RESUME without re-firing the impression callback.\n const lastShownStepIdRef = useRef<string | null>(null);\n\n // Keep the latest step callbacks in a ref so parent-recreated inline callbacks\n // don't re-trigger the drive effect (which would re-show the step and\n // double-fire analytics). The drive effect keys only on the step, not these.\n const callbacksRef = useRef({ onStepShown, onStepEngaged, onStepDismissed });\n callbacksRef.current = { onStepShown, onStepEngaged, onStepDismissed };\n\n // The tenant's coachmarks kill switch, SUBSCRIBED rather than sampled so a mid-tour flip reaches\n // a tour already in flight. See the KILL SWITCH vs PAUSE note above.\n const coachmarksOn = useSyncExternalStore(\n subscribeCoachmarksEnabled,\n areCoachmarksEnabled,\n areCoachmarksEnabled,\n );\n\n /**\n * The single terminal exit. `writeGate` is what separates the two ways a tour can end:\n * • the user reached the end (or dismissed the last step) → the once-gate IS written, so a\n * finished tour never nags again;\n * • the kill switch went off mid-tour → the gate is NOT written. That gate belongs to a tour\n * the user actually saw, and the module's whole kill-switch contract is that disabling\n * never consumes it, so re-enabling replays the tour.\n * Either way `onComplete` fires: a host that gates its own UI on the tour finishing must not be\n * left waiting on a callback that can no longer arrive.\n */\n const exit = useCallback(\n (writeGate: boolean) => {\n if (finishedRef.current) return;\n finishedRef.current = true;\n if (writeGate && showOnce) markSeenGate(coachmarkGateKey(tourId));\n coachmarkOverlay.hide();\n setActiveIndex(null);\n onComplete?.();\n },\n [onComplete, showOnce, tourId],\n );\n\n const finish = useCallback(() => exit(true), [exit]);\n\n // Arm once, after the delay, when enabled and the gate is unseen.\n useEffect(() => {\n if (!enabled || startedRef.current) return undefined;\n // Feature kill switch: never arm while coachmarks are disabled, so no timer starts, no\n // overlay shows, and the once-gate is NOT consumed — re-enabling replays the tour. Reading\n // the SUBSCRIBED value (and listing it in the deps) is what makes that last clause true\n // without a remount: flipping it off clears a pending arm timer, flipping it back on re-arms.\n if (!coachmarksOn) return undefined;\n if (showOnce && hasSeenGate(coachmarkGateKey(tourId))) return undefined;\n const timer = setTimeout(() => {\n startedRef.current = true;\n setActiveIndex(0);\n }, startDelayMs);\n return () => clearTimeout(timer);\n }, [enabled, coachmarksOn, startDelayMs, showOnce, tourId]);\n\n // Drive the active step. Keyed on `enabled` too, so a mid-tour focus loss\n // pauses (hide, keep position) and a return to focus resumes the same step.\n useEffect(() => {\n if (activeIndex === null) return undefined;\n\n // KILL SWITCH, mid-tour: exit terminally, WITHOUT writing the once-gate, so the tour replays\n // when it is switched back on. Checked BEFORE the pause branch below — a disable is terminal,\n // a focus loss is not.\n if (!coachmarksOn) {\n exit(false);\n return undefined;\n }\n\n // PAUSE: armed but the screen lost focus (enabled flipped false while in\n // flight). Hide the overlay so a stale rect can't float over the wrong\n // screen, but KEEP activeIndex and DON'T write the gate. When enabled\n // returns true this effect re-runs and re-drives the current step below.\n if (!enabled) {\n if (startedRef.current && !finishedRef.current) coachmarkOverlay.hide();\n return undefined;\n }\n\n if (activeIndex >= steps.length) {\n finish();\n return undefined;\n }\n\n const step = steps[activeIndex];\n if (!step) {\n finish();\n return undefined;\n }\n let cancelled = false;\n\n (async () => {\n // Re-resolve the anchor every drive (incl. resume) — rects may have moved\n // while the screen was backgrounded / relaid out.\n const rect = step.anchorId\n ? await coachmarkAnchors.resolve(step.anchorId, {\n shouldCancel: () => cancelled,\n })\n : null;\n if (cancelled) return;\n\n // Fire onStepShown only when the shown step actually changes — a resume\n // of the SAME step (post focus-loss) must not double-count the impression.\n if (lastShownStepIdRef.current !== step.id) {\n lastShownStepIdRef.current = step.id;\n callbacksRef.current.onStepShown?.(step.id);\n }\n coachmarkOverlay.show({\n message: step.message,\n targetRect: rect,\n gesture: step.gesture ?? \"none\",\n placement: step.placement ?? \"bottom\",\n onEngage: () => {\n callbacksRef.current.onStepEngaged?.(step.id);\n step.onEngage?.();\n setActiveIndex((index) => (index ?? 0) + 1);\n },\n onDismiss: () => {\n callbacksRef.current.onStepDismissed?.(step.id);\n // Backdrop tap advances to the next step; only the LAST step's\n // backdrop tap ends the whole tour (the gate is written once, there).\n if (activeIndex >= steps.length - 1) {\n finish();\n } else {\n setActiveIndex((index) => (index ?? 0) + 1);\n }\n },\n });\n })();\n\n return () => {\n cancelled = true;\n };\n }, [activeIndex, steps, finish, exit, enabled, coachmarksOn]);\n\n // Safety: clear the overlay if the screen unmounts mid-tour.\n useEffect(\n () => () => {\n if (!finishedRef.current) coachmarkOverlay.hide();\n },\n [],\n );\n};\n","/**\n * selectTourSteps — the Phase-3 (AI intent-mapping) seam, stubbed today.\n *\n * The app declares a full catalog of coachmarks (its \"feature map\"). Near-term,\n * the whole catalog plays in its declared order. LATER, the Wire server will\n * emit an ordered `coachmarks: string[]` id list chosen by the user's captured\n * intent (see the package spec §1e / §5), and the app passes it straight here as\n * `selection`. This function is the ONE place that turns a selection into the\n * live ordered step list — so turning AI on is a drop-in with zero app changes:\n *\n * // Phase 1-2 (no AI): full catalog, declared order\n * const steps = selectTourSteps(catalog);\n *\n * // Phase 3 (AI on): server-chosen subset, server order\n * const steps = selectTourSteps(catalog, plan.coachmarks);\n *\n * Contract:\n * - `selection` absent → returns the catalog unchanged (identity/declared order).\n * - `selection` present → returns only catalog entries whose `id` appears in\n * `selection`, ordered by `selection` (unknown ids are skipped; duplicates in\n * `selection` are ignored after the first match).\n *\n * NOTE: routing steps through a catalog + this selector is NOT required today.\n * Declaring an inline, static (module-level or memoized) steps array and passing\n * it straight to `useCoachmarkTour` is a perfectly fine consumer pattern. The\n * catalog + selection route exists to make the app AI-selection-ready — flip to\n * server-chosen ordering later with zero app changes — not as the baseline.\n */\nexport const selectTourSteps = <T extends { id: string }>(\n catalog: T[],\n selection?: string[],\n): T[] => {\n if (!selection) return catalog;\n\n const byId = new Map(catalog.map((item) => [item.id, item]));\n const seen = new Set<string>();\n const ordered: T[] = [];\n for (const id of selection) {\n if (seen.has(id)) continue;\n seen.add(id);\n const item = byId.get(id);\n if (item) ordered.push(item);\n }\n return ordered;\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/features/defaults.ts","../../src/features/cache.ts","../../src/features/fetchWireFeatures.ts","../../src/features/useWireFeatures.ts","../../src/features/WireFeaturesProvider.tsx","../../src/coachmarks/runtime.ts","../../src/coachmarks/coachmarkOverlayStore.ts","../../src/theme/defaultTheme.ts","../../src/theme/ThemeContext.tsx","../../src/coachmarks/expoBlur.ts","../../src/motion/useReducedMotion.ts","../../src/coachmarks/reanimated.ts","../../src/coachmarks/GestureHint.tsx","../../src/coachmarks/SpotlightOverlay.tsx","../../src/coachmarks/CoachmarkOverlayHost.tsx","../../src/coachmarks/CoachmarkProvider.tsx","../../src/coachmarks/coachmarkAnchorRegistry.ts","../../src/coachmarks/useCoachmarkAnchor.ts","../../src/coachmarks/useCoachmarkTour.ts","../../src/coachmarks/selectTourSteps.ts"],"names":["cached","useRef","useState","useEffect","createContext","useContext","listeners","useSyncExternalStore","AccessibilityInfo","runtimeRequire","useReducer","current","forwardRef","StaticAnimatedView","createElement","View","_a","api","useReducedMotion","useMemo","jsx","jsxs","Fragment","StyleSheet","React","useWindowDimensions","styles","Pressable","Text","useCallback","_b","_c"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * The fail-open defaults + a tolerant parser for the server's flags payload.\n *\n * THE CONTRACT: fail-open, never fail-dark. An absent server object, a missing module key, a\n * malformed value, or an unreachable endpoint must resolve to the MOST PERMISSIVE state — every\n * module ON, onboarding `ai` — so a control-plane outage can only ever be more permissive than\n * the dashboard intends. It can never dark a tenant's activation. Matches the server's own\n * documented fail-open default (FEATURES.md: \"local defaults — every module on, onboarding ai\").\n */\nimport type { OnboardingMode, WireFeatures } from \"./types\";\n\n/**\n * ALL ON, onboarding `ai`. Frozen + module-level so its reference is stable across every call\n * (consumers that list resolved flags in an effect dep array never loop on a fresh identity).\n */\nexport const defaultWireFeatures: WireFeatures = Object.freeze({\n coachmarks: Object.freeze({ enabled: true }),\n showcase: Object.freeze({ enabled: true }),\n onboarding: Object.freeze({ mode: \"ai\" as OnboardingMode }),\n review: Object.freeze({ enabled: true }),\n questionnaire: Object.freeze({ enabled: true }),\n announcements: Object.freeze({ enabled: true }),\n}) as WireFeatures;\n\nconst VALID_MODES: readonly OnboardingMode[] = [\"ai\", \"static\", \"off\"];\n\n/** Read a `{ enabled: boolean }` module, defaulting to ON when absent/malformed (fail-open). */\nconst readEnabled = (raw: unknown): { enabled: boolean } => {\n if (raw && typeof raw === \"object\" && typeof (raw as { enabled?: unknown }).enabled === \"boolean\") {\n return { enabled: (raw as { enabled: boolean }).enabled };\n }\n return { enabled: true };\n};\n\n/**\n * Narrow the server's (untrusted) JSON to a complete `WireFeatures`. Every field is filled with\n * its fail-open default when the server omits it or sends the wrong type, so a partial or\n * malformed payload degrades PERMISSIVELY rather than throwing. A non-object input (null, array,\n * string) → the full defaults. Never throws.\n */\nexport const parseWireFeatures = (raw: unknown): WireFeatures => {\n if (!raw || typeof raw !== \"object\" || Array.isArray(raw)) return defaultWireFeatures;\n const src = raw as Record<string, unknown>;\n const modeRaw = (src.onboarding as { mode?: unknown } | undefined)?.mode;\n const mode: OnboardingMode =\n typeof modeRaw === \"string\" && VALID_MODES.includes(modeRaw as OnboardingMode)\n ? (modeRaw as OnboardingMode)\n : \"ai\";\n return {\n coachmarks: readEnabled(src.coachmarks),\n showcase: readEnabled(src.showcase),\n onboarding: { mode },\n review: readEnabled(src.review),\n questionnaire: readEnabled(src.questionnaire),\n announcements: readEnabled(src.announcements),\n };\n};\n\n/** Value-equality of two resolved flags — lets the hook hold a stable reference across churn. */\nexport const featuresEqual = (a: WireFeatures, b: WireFeatures): boolean =>\n a === b ||\n (a.coachmarks.enabled === b.coachmarks.enabled &&\n a.showcase.enabled === b.showcase.enabled &&\n a.onboarding.mode === b.onboarding.mode &&\n a.review.enabled === b.review.enabled &&\n a.questionnaire.enabled === b.questionnaire.enabled &&\n a.announcements.enabled === b.announcements.enabled);\n","/**\n * The last-known-flags cache — persisted through the host's optional `storage`.\n *\n * WHY: the fetch is best-effort and fail-open. When the control plane is unreachable we serve the\n * LAST value we saw rather than snapping to defaults, so a tenant that intentionally disabled a\n * module during an incident keeps it disabled across an outage instead of flapping back on. That\n * is \"stale-while-error\": a fresh cache (< TTL) is trusted, and on a fetch error even a STALE\n * cache is served (any age beats a guess). Every operation is best-effort — a broken/hung storage\n * degrades to defaults, never a throw and never a stuck gate (mirrors persistedSession).\n */\nimport { parseWireFeatures } from \"./defaults\";\nimport type { WireFeatures } from \"./types\";\nimport type { WireOnboardingStorage } from \"../session/persistedSession\";\n\n/**\n * TTL for a cached flags entry, aligned to the server's `Cache-Control: private, max-age=300`.\n * A cache younger than this is \"fresh\"; older is \"stale\" (still served on a fetch error).\n */\nexport const DEFAULT_FEATURES_TTL_MS = 300_000;\n\n/** Ceiling on the storage read so a hung adapter degrades to defaults, never a stuck resolve. */\nconst READ_TIMEOUT_MS = 1_500;\n\n/** Storage key for a tenant's cached flags, e.g. `wireai:features:acme`. */\nexport const featuresCacheKey = (appId?: string): string =>\n `wireai:features:${appId && appId.length > 0 ? appId : \"default\"}`;\n\n/** A cached flags entry: the resolved flags + the epoch-ms they were fetched. */\nexport interface CachedFeatures {\n features: WireFeatures;\n /** Age of the entry in ms at read time. */\n ageMs: number;\n}\n\nconst withTimeout = <T>(p: Promise<T>, ms: number): Promise<T | undefined> => {\n let timer: ReturnType<typeof setTimeout>;\n const timeout = new Promise<undefined>((resolve) => {\n timer = setTimeout(() => resolve(undefined), ms);\n });\n return Promise.race([p, timeout]).finally(() => clearTimeout(timer));\n};\n\n/** Whether a cache entry is still within the TTL (server max-age aligned). */\nexport const isFeaturesFresh = (ageMs: number, ttlMs: number = DEFAULT_FEATURES_TTL_MS): boolean =>\n ageMs >= 0 && ageMs < ttlMs;\n\n/**\n * Read the cached flags for `key`, or `undefined` when absent/corrupt/timed-out. Returns the\n * value AND its age so a caller can apply a TTL (fresh) or ignore it (stale-while-error). Never\n * throws; never hangs past the read timeout. The stored value is re-parsed through\n * `parseWireFeatures`, so a partially-corrupt entry still degrades fail-open.\n */\nexport const readCachedFeatures = async (\n storage: WireOnboardingStorage,\n key: string,\n): Promise<CachedFeatures | undefined> => {\n let raw: string | null | undefined;\n try {\n raw = await withTimeout(storage.getItem(key), READ_TIMEOUT_MS);\n } catch {\n return undefined;\n }\n if (!raw) return undefined;\n try {\n const parsed: unknown = JSON.parse(raw);\n if (parsed && typeof parsed === \"object\" && typeof (parsed as { ts?: unknown }).ts === \"number\") {\n const ts = (parsed as { ts: number }).ts;\n return {\n features: parseWireFeatures((parsed as { features?: unknown }).features),\n ageMs: Date.now() - ts,\n };\n }\n } catch {\n // Corrupt entry → treat as absent; the caller falls back to defaults / a fresh fetch.\n }\n return undefined;\n};\n\n/** Persist `{ features, ts }` under `key` — fire-and-forget, all errors swallowed. */\nexport const writeCachedFeatures = (\n storage: WireOnboardingStorage,\n key: string,\n features: WireFeatures,\n): void => {\n try {\n void storage\n .setItem(key, JSON.stringify({ features, ts: Date.now() }))\n .catch(() => {});\n } catch {\n // Best-effort: a failed write just means the next launch has no cache to fall back to.\n }\n};\n","/**\n * fetchWireFeatures — read the per-module kill switches from `GET {serverUrl}/v1/features`.\n *\n * Contract (server: chohra-med/wireai-onboarding-server, routers/onboarding.py):\n * GET {serverUrl}/v1/features\n * Authorization: Bearer {apiKey}\n * 200 → { coachmarks:{enabled}, showcase:{enabled}, onboarding:{mode}, review:{enabled},\n * announcements:{enabled} } (Cache-Control: private, max-age=300)\n *\n * THE CONTRACT — fail-open, never fail-dark. Unreachable, timed-out, unauthorized (401),\n * server-error (5xx), or malformed JSON all resolve to the LAST CACHED value, else the\n * all-on defaults. No throw ever reaches the host: this is timeout-capped and swallows every\n * error, exactly like the session's best-effort reads. A control-plane outage can only ever be\n * MORE permissive than the dashboard intends — it can never dark a tenant's activation.\n */\nimport { readCachedFeatures, featuresCacheKey, writeCachedFeatures } from \"./cache\";\nimport { defaultWireFeatures, parseWireFeatures } from \"./defaults\";\nimport type { WireFeatures, WireFeaturesConfig } from \"./types\";\nimport type { WireOnboardingStorage } from \"../session/persistedSession\";\n\nconst DEFAULT_TIMEOUT_MS = 4_000;\n\n/** The fail-open fallback: last cached value (any age — stale-while-error), else defaults. */\nconst failOpen = async (\n storage: WireOnboardingStorage | undefined,\n key: string,\n): Promise<WireFeatures> => {\n if (!storage) return defaultWireFeatures;\n const cached = await readCachedFeatures(storage, key);\n return cached?.features ?? defaultWireFeatures;\n};\n\n/** GET with a hard timeout via AbortController (falls back to no-abort where unsupported). */\nconst fetchWithTimeout = async (\n url: string,\n apiKey: string,\n timeoutMs: number,\n): Promise<Response> => {\n const controller =\n typeof AbortController !== \"undefined\" ? new AbortController() : undefined;\n const timer = setTimeout(() => controller?.abort(), timeoutMs);\n try {\n return await fetch(url, {\n method: \"GET\",\n headers: { Accept: \"application/json\", Authorization: `Bearer ${apiKey}` },\n signal: controller?.signal,\n });\n } finally {\n clearTimeout(timer);\n }\n};\n\n/**\n * Resolve the tenant's feature flags. Attempts the network once; on ANY failure returns the\n * cached value (any age), else the all-on defaults. On success, persists the fresh value to the\n * cache (fire-and-forget) and returns it. Never throws.\n *\n * const flags = await fetchWireFeatures({ serverUrl, apiKey, appId, storage });\n * if (!flags.coachmarks.enabled) { /* skip the tour * / }\n */\nexport const fetchWireFeatures = async (\n config?: WireFeaturesConfig,\n): Promise<WireFeatures> => {\n const key = featuresCacheKey(config?.appId);\n const storage = config?.storage;\n\n // Nothing to fetch (no creds) → cache, else defaults. Lets a host mount the provider before\n // its config is ready without ever darking.\n if (!config?.serverUrl || !config?.apiKey) return failOpen(storage, key);\n\n const url = `${config.serverUrl.replace(/\\/$/, \"\")}/v1/features`;\n const timeoutMs = config.timeoutMs && config.timeoutMs > 0 ? config.timeoutMs : DEFAULT_TIMEOUT_MS;\n\n try {\n const res = await fetchWithTimeout(url, config.apiKey, timeoutMs);\n // 401 (bad/rotated key), 5xx, any non-2xx → last-known, never dark.\n if (!res || !res.ok) return failOpen(storage, key);\n const json: unknown = await res.json(); // throws on malformed body → caught below\n const features = parseWireFeatures(json);\n if (storage) writeCachedFeatures(storage, key, features);\n return features;\n } catch {\n // Timeout/abort, network error, missing fetch, or malformed JSON — all fail open.\n return failOpen(storage, key);\n }\n};\n","/**\n * useWireFeatures — resolve the tenant's feature flags for a component tree, once per mount.\n *\n * Returns the all-on defaults immediately (fail-open), then swaps to the fetched value when the\n * network resolves. When no `serverUrl`+`apiKey` is supplied it never fetches and just returns\n * defaults, so a host that never adopts flags sees ZERO behavior change and ZERO network calls.\n *\n * frequent_rules #11 (unstable inline props): the config is idiomatically passed inline\n * (`config={{ serverUrl, apiKey }}`), a fresh identity every render. We stabilize the fetch key\n * by VALUE so the effect fires once per real credential change, and we only swap the returned\n * flags object when its VALUES change — so a host that lists the returned flags in an effect dep\n * array settles in a bounded number of commits instead of looping (enforced by the canary suite).\n */\nimport { useEffect, useRef, useState } from \"react\";\n\nimport { defaultWireFeatures, featuresEqual } from \"./defaults\";\nimport { fetchWireFeatures } from \"./fetchWireFeatures\";\nimport type { WireFeatures, WireFeaturesConfig } from \"./types\";\n\n/** Hold a stable reference for a value while its CONTENT is unchanged (see reviews/equality.ts). */\nconst useStableValue = <T,>(value: T, isEqual: (a: T, b: T) => boolean): T => {\n const ref = useRef(value);\n if (!isEqual(ref.current, value)) ref.current = value;\n return ref.current;\n};\n\n/** The credential slice that actually drives a refetch — stabilized by value. */\nconst sameFetchKey = (a: WireFeaturesConfig | undefined, b: WireFeaturesConfig | undefined): boolean =>\n a?.serverUrl === b?.serverUrl && a?.apiKey === b?.apiKey && a?.appId === b?.appId;\n\nexport const useWireFeatures = (config?: WireFeaturesConfig): WireFeatures => {\n const stableConfig = useStableValue(config, sameFetchKey);\n const [flags, setFlags] = useState<WireFeatures>(defaultWireFeatures);\n\n const canFetch = !!stableConfig?.serverUrl && !!stableConfig?.apiKey;\n\n useEffect(() => {\n if (!canFetch) {\n // No creds → stay on the all-on defaults (and reset if creds were removed).\n setFlags((prev) => (featuresEqual(prev, defaultWireFeatures) ? prev : defaultWireFeatures));\n return;\n }\n let alive = true;\n // fetchWireFeatures never throws — the .then always runs with a fail-open value.\n void fetchWireFeatures(stableConfig).then((next) => {\n if (!alive) return;\n // Only adopt a NEW reference on a real value change, so a host effect keyed on the\n // returned flags doesn't loop (frequent_rules #11).\n setFlags((prev) => (featuresEqual(prev, next) ? prev : next));\n });\n return () => {\n alive = false;\n };\n }, [canFetch, stableConfig]);\n\n return flags;\n};\n","/**\n * WireFeaturesProvider + useResolvedFeatures — the OPTIONAL one-fetch-serves-all-modules layer.\n *\n * Mount `WireFeaturesProvider` once near your app root with the tenant `config` and it fetches the\n * flags ONCE; every gated surface below it (coachmarks / showcase / reviews) reads the same\n * resolved value from context instead of each fetching its own. It is entirely optional: with no\n * provider, every surface falls back to its own lazy fetch (when given a config) or to the all-on\n * defaults, so modules work with zero setup and a host that never adopts flags is unchanged.\n *\n * NOTE on the built npm subpaths: React context is shared across the kit's subpath entries in the\n * SOURCE-consumption path (the monorepo apps) and in this test suite — one module instance, one\n * context. If you consume the built `@wireai/activation/*` subpaths as separate bundles, pass the\n * resolved flags (or a `featuresConfig`) to each surface explicitly instead of relying on context.\n */\nimport React, { createContext, useContext, useMemo } from \"react\";\n\nimport { defaultWireFeatures } from \"./defaults\";\nimport { useWireFeatures } from \"./useWireFeatures\";\nimport type { WireFeatures, WireFeaturesConfig } from \"./types\";\n\n/**\n * @globalSlot LATCH — the React context object is minted by the first copy of this module to load\n * and every later copy ADOPTS it (the `if (!…)` guard below). A second write would re-split the\n * identity the guard exists to keep whole: the provider would publish into one context while a\n * subpath bundle's `useContext` read another, and `useResolvedFeatures`' null fallback would serve\n * the all-on defaults with no crash and no warning. Because it is a latch, and only because of\n * that, the module-local `const WireFeaturesContext` below may cache it.\n */\nconst CONTEXT_SYMBOL = Symbol.for(\"wireai.features.context\");\n// `globalThis`, not `global`: the other nine `Symbol.for` slots in this kit all use it, and `global`\n// simply does not exist in a plain browser (RN-web / SSR-in-the-browser), where this line would\n// throw a ReferenceError before the provider could render anything.\nconst globalObj = globalThis as any;\n\nif (!globalObj[CONTEXT_SYMBOL]) {\n globalObj[CONTEXT_SYMBOL] = createContext<WireFeatures | null>(null);\n}\nconst WireFeaturesContext = globalObj[CONTEXT_SYMBOL];\n\nexport interface WireFeaturesProviderProps {\n /** Tenant creds (+ optional storage) to fetch the flags once for the whole tree. */\n config?: WireFeaturesConfig;\n /**\n * Pre-resolved flags to provide directly instead of fetching (e.g. you already have them, or\n * you drive them from your own remote-config). Takes precedence over `config`.\n */\n flags?: WireFeatures;\n children: React.ReactNode;\n}\n\n/**\n * Fetch (or accept) the flags once and broadcast them to descendants. The provider VALUE is\n * memoized (performance rule #6) so a fresh object each render doesn't re-render every consumer.\n */\nexport const WireFeaturesProvider: React.FC<WireFeaturesProviderProps> = ({\n config,\n flags,\n children,\n}) => {\n // Always call the hook (rules of hooks); when `flags` is supplied we pass no config so it\n // never fetches and the explicit flags win below.\n const fetched = useWireFeatures(flags ? undefined : config);\n const value = flags ?? fetched;\n const stable = useMemo(() => value, [value]);\n return <WireFeaturesContext.Provider value={stable}>{children}</WireFeaturesContext.Provider>;\n};\n\nWireFeaturesProvider.displayName = \"WireFeaturesProvider\";\n\n/** Raw context read — `null` when no `WireFeaturesProvider` is mounted above. */\nexport const useWireFeaturesContext = (): WireFeatures | null =>\n useContext(WireFeaturesContext);\n\n/** Options for `useResolvedFeatures`: an explicit override and/or a lazy-fetch config. */\nexport interface ResolveFeaturesOptions {\n /** Explicit flags — win over everything (a surface's own `features` prop). */\n flags?: WireFeatures;\n /** Lazy-fetch config, used ONLY when there is no explicit `flags` and no provider above. */\n config?: WireFeaturesConfig;\n}\n\n/**\n * The resolution every gated surface uses. Precedence:\n * 1. explicit `options.flags` (a surface's own prop) →\n * 2. the nearest `WireFeaturesProvider` (context) →\n * 3. a lazy fetch from `options.config` (serverUrl + apiKey) →\n * 4. the all-on defaults.\n * Always fail-open, always a stable reference for a given value (so it's safe in effect deps).\n */\nexport const useResolvedFeatures = (options?: ResolveFeaturesOptions): WireFeatures => {\n const ctx = useWireFeaturesContext();\n // Only lazily fetch when nothing else provides the flags — otherwise pass no config so the\n // hook stays inert (defaults, no network). The hook is always called (rules of hooks).\n const shouldFetch = !options?.flags && ctx == null;\n const fetched = useWireFeatures(shouldFetch ? options?.config : undefined);\n return options?.flags ?? ctx ?? fetched ?? defaultWireFeatures;\n};\n","/**\n * Module-level runtime for the coachmark engine: the injected sync storage, the\n * global `isTestingCoachmark` flag, and the seen-gate helpers built on top.\n *\n * WHY module singletons (not just context): the tour hooks and the anchor\n * registry are driven imperatively from anywhere in the tree (a screen deep\n * under the navigator), while the storage + testing flag are configured once at\n * the root by `CoachmarkProvider`. Singletons let a hook read the gate without\n * every call site threading the storage through props. The provider is still the\n * single writer — it calls `setCoachmarkStorage` / `setCoachmarkTesting` on mount.\n *\n * ── WHY A globalThis SLOT, NOT PLAIN MODULE VARIABLES ─────────────────────────────────────────\n * These three values used to be plain module `let`s, and this module is inlined by tsup into FOUR\n * dist bundles (`./coachmarks`, `./reviews`, `./questionnaire`, `./showcase`). Under `dist`\n * resolution — node `import`/`require`, SSR, jest, RN-web, anything that is not Metro — a host that\n * mounts `CoachmarkProvider` from `@wireai/activation/coachmarks` wrote the COACHMARKS copy, while\n * `useReviewGate` from `@wireai/activation/reviews` read the REVIEWS copy, which was still `null`.\n * Everything downstream then failed silently: `readInt(null, …)` returns 0, so `bumpSessionCount`\n * returns 1 forever and the fail-closed `minSessions: 2` default is unsatisfiable (the gate NEVER\n * fires); the `seen` once-gate never persists; and a tenant's coachmarks kill switch never reaches\n * the reviews bundle. Metro masked it by collapsing every subpath back to one `src/` file through\n * the `react-native` export condition, which is a bundler accident, not a guarantee.\n *\n * Same remedy this repo already applies to `currentSession`, the auto device-key registry and the\n * activation revalidation counter: ONE record in a `globalThis` slot keyed by `Symbol.for(...)`, so\n * every inlined copy of this module addresses the SAME state.\n */\nimport type { CoachmarkStorage } from \"./types\";\n\n/**\n * Well-known key into the runtime-global symbol registry — one coachmark runtime across bundles.\n *\n * @globalSlot LATCH — the RUNTIME RECORD is created once and its identity is then stable. A second\n * write replaces the record `subscribeCoachmarksEnabled` registered its listeners on, so a\n * kill-switch flip notifies an orphaned set while a tour that believes it is running paints nothing\n * — the exact limbo `coachmarkKillSwitch` canaries. Its FIELDS (`storage`, `testing`,\n * `coachmarksEnabled`, `listeners`) are live, which is why every accessor calls `coachmarkRuntime()`\n * instead of holding the record, and why `coachmarksEnabled` is subscribable rather than sampled.\n */\nconst COACHMARK_RUNTIME_SLOT: unique symbol = Symbol.for(\"@wireai/activation:coachmarkRuntime\");\n\n/** The shared runtime: the provider-injected storage, the QA replay flag, and the kill switch. */\ntype CoachmarkRuntime = {\n storage: CoachmarkStorage | null;\n testing: boolean;\n // The coachmarks feature kill switch (from GET /v1/features). Default true = fail-open: with no\n // flags fetched, coachmarks behave exactly as before. CoachmarkProvider writes it from the\n // resolved flags. Disabled → the tour never ARMS and the overlay `show()` is a no-op, so nothing\n // paints and — critically — no once-gate is written, so re-enabling replays the tour correctly.\n coachmarksEnabled: boolean;\n // Subscribers to the kill switch. OPTIONAL on the type (never on the behaviour) so a record left\n // in the registry by an inlined copy from an OLDER kit version — which had no listener set — is\n // upgraded in place rather than read as corrupt.\n listeners?: Set<() => void>;\n};\n\ntype GlobalWithCoachmarkRuntime = typeof globalThis & {\n [COACHMARK_RUNTIME_SLOT]?: CoachmarkRuntime;\n};\n\nconst runtimeGlobal = globalThis as GlobalWithCoachmarkRuntime;\n\nconst coachmarkRuntime = (): CoachmarkRuntime => {\n const existing = runtimeGlobal[COACHMARK_RUNTIME_SLOT];\n if (existing) return existing;\n const created: CoachmarkRuntime = { storage: null, testing: false, coachmarksEnabled: true };\n runtimeGlobal[COACHMARK_RUNTIME_SLOT] = created;\n return created;\n};\n\nconst enabledListeners = (): Set<() => void> => {\n const runtime = coachmarkRuntime();\n if (!runtime.listeners) runtime.listeners = new Set();\n return runtime.listeners;\n};\n\n/**\n * Wake the subscribers on a MICROTASK, never synchronously.\n *\n * `CoachmarkProvider` writes this flag during its RENDER phase on purpose (so a child's mount\n * effect already sees the resolved value). Notifying from there synchronously would schedule a\n * React update while a *different* component is rendering. Every subscriber reads the value\n * through `areCoachmarksEnabled()` at render time anyway, so the notification only has to wake\n * the components that are not already re-rendering — one microtask later is soon enough, and it\n * keeps the write side legal from anywhere.\n */\nconst notifyCoachmarksEnabled = (): void => {\n if (enabledListeners().size === 0) return;\n void Promise.resolve().then(() => {\n for (const listener of [...enabledListeners()]) {\n try {\n listener();\n } catch {\n // A broken subscriber must never break the kill switch for the others.\n }\n }\n });\n};\n\n/**\n * Set the coachmarks master switch (from the resolved feature flags). Default true (fail-open).\n * Written by CoachmarkProvider; read imperatively by the tour arm + the overlay store, and\n * SUBSCRIBED to by `useCoachmarkTour` (see `subscribeCoachmarksEnabled`).\n *\n * No-ops when the value is unchanged, which matters because the provider writes it on every\n * render — without that guard every render would fan out a notification.\n */\nexport const setCoachmarksEnabled = (value: boolean): void => {\n const runtime = coachmarkRuntime();\n if (runtime.coachmarksEnabled === value) return;\n runtime.coachmarksEnabled = value;\n notifyCoachmarksEnabled();\n};\n\n/** Whether the coachmarks module is enabled. False → tours/overlays are silently skipped. */\nexport const areCoachmarksEnabled = (): boolean => coachmarkRuntime().coachmarksEnabled;\n\n/**\n * Subscribe to kill-switch flips. Returns the unsubscribe function — the `useSyncExternalStore`\n * contract, and deliberately the SAME shape as `coachmarkOverlay.subscribe` next door rather than\n * a second pattern to keep correct.\n *\n * WHY IT EXISTS: the flag is a mutable `globalThis` value, so on its own it can only be SAMPLED.\n * A tour that samples it cannot notice a tenant flipping it off mid-flight — the overlay's\n * `show()` quietly becomes a no-op while the tour still believes it is running, so nothing paints,\n * nothing can be tapped to advance, and no terminal path is reachable. `useCoachmarkTour`\n * subscribes instead. The listener set lives in the SAME `globalThis` record as the flag, so every\n * inlined copy of this module shares one subscriber list.\n */\nexport const subscribeCoachmarksEnabled = (listener: () => void): (() => void) => {\n const listeners = enabledListeners();\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n};\n\n/** Set (or clear) the injected sync gate storage. Called by CoachmarkProvider. */\nexport const setCoachmarkStorage = (storage: CoachmarkStorage | null): void => {\n coachmarkRuntime().storage = storage;\n};\n\n/** The currently-injected gate storage, or null if no provider is mounted. */\nexport const getCoachmarkStorage = (): CoachmarkStorage | null => coachmarkRuntime().storage;\n\n/**\n * Toggle the global QA replay flag. When true, EVERY seen-gate reads as unseen\n * and every seen-write is suppressed, so every tour + showcase replays on each\n * mount. The app flips ONE boolean to QA the whole coachmark surface.\n */\nexport const setCoachmarkTesting = (value: boolean): void => {\n coachmarkRuntime().testing = value;\n};\n\n/** Whether replay-everything QA mode is on. */\nexport const isCoachmarkTesting = (): boolean => coachmarkRuntime().testing;\n\n/** Gate key for a tour: `wire_coachmark_<tourId>_seen`. */\nexport const coachmarkGateKey = (tourId: string): string =>\n `wire_coachmark_${tourId}_seen`;\n\n/** Gate key for a feature showcase: `wire_showcase_<id>_seen`. */\nexport const showcaseGateKey = (showcaseId: string): string =>\n `wire_showcase_${showcaseId}_seen`;\n\n/** Marker value written for a seen gate. */\nconst SEEN_VALUE = \"1\";\n\n/**\n * Read a seen gate. Testing mode ALWAYS reports unseen (so everything replays).\n * A missing storage (no provider) also reports unseen — the safe default is to\n * show the hint rather than silently swallow it. `storageOverride` /\n * `testingOverride` let a self-contained component (e.g. FeatureShowcase) pass\n * its own storage without relying on the provider singleton.\n */\nexport const hasSeenGate = (\n key: string,\n storageOverride?: CoachmarkStorage | null,\n testingOverride?: boolean,\n): boolean => {\n if (testingOverride ?? isCoachmarkTesting()) return false;\n const storage = storageOverride ?? getCoachmarkStorage();\n if (!storage) return false;\n try {\n return storage.getItem(key) === SEEN_VALUE;\n } catch {\n return false;\n }\n};\n\n/**\n * Mark a gate seen. Suppressed in testing mode (so replay never persists) and a\n * no-op without storage. Best-effort — a throwing adapter never breaks the tour.\n */\nexport const markSeenGate = (\n key: string,\n storageOverride?: CoachmarkStorage | null,\n testingOverride?: boolean,\n): void => {\n if (testingOverride ?? isCoachmarkTesting()) return;\n const storage = storageOverride ?? getCoachmarkStorage();\n if (!storage) return;\n try {\n storage.setItem(key, SEEN_VALUE);\n } catch {\n // Best-effort: a failed write just means the hint may show once more.\n }\n};\n","import { useSyncExternalStore } from \"react\";\n\nimport { areCoachmarksEnabled } from \"./runtime\";\nimport type { GestureKind, Placement, TargetRect } from \"./types\";\n\n/**\n * A tiny module-level store for the single active coachmark overlay. The host\n * (CoachmarkOverlayHost, mounted once by CoachmarkProvider at the app root)\n * subscribes and renders whatever is active; the tour controller drives it\n * imperatively via show()/hide(). No React context is needed for the overlay\n * itself — the host reaches the root so the ring can paint above the tab bar.\n *\n * Only ONE overlay is ever active (steps never stack), per the engine's\n * one-overlay-at-a-time rule.\n */\nexport interface CoachmarkOverlayState {\n message: string;\n targetRect: TargetRect | null;\n gesture: GestureKind;\n placement: Placement;\n onEngage: () => void;\n onDismiss: () => void;\n}\n\nlet current: CoachmarkOverlayState | null = null;\nconst listeners = new Set<() => void>();\n\nconst emit = () => {\n for (const listener of listeners) listener();\n};\n\nexport const coachmarkOverlay = {\n show(state: CoachmarkOverlayState) {\n // Feature kill switch: when coachmarks are disabled, a show() request is a silent no-op —\n // no ring paints, and because nothing shows the user can't advance/dismiss a tour, so no\n // once-gate is ever written and re-enabling replays it. hide() still works (see below).\n if (!areCoachmarksEnabled()) return;\n current = state;\n emit();\n },\n hide() {\n if (current === null) return;\n current = null;\n emit();\n },\n subscribe(listener: () => void) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n getSnapshot(): CoachmarkOverlayState | null {\n return current;\n },\n};\n\n/** Subscribe a component to the active overlay (or null). */\nexport const useCoachmarkOverlay = (): CoachmarkOverlayState | null =>\n useSyncExternalStore(\n coachmarkOverlay.subscribe,\n coachmarkOverlay.getSnapshot,\n coachmarkOverlay.getSnapshot,\n );\n","/**\n * defaultOnboardingTheme — a neutral, light, brand-agnostic baseline. Consumers\n * pass a `Partial<OnboardingTheme>` that is deep-merged over this (see\n * `mergeTheme`), so they only override what differs from neutral.\n */\nimport type { OnboardingTheme } from \"./types\";\n\nexport const defaultOnboardingTheme: OnboardingTheme = {\n colors: {\n background: \"#FFFFFF\",\n surface: \"#F7F7F8\",\n text: \"#101114\",\n textMuted: \"#6B7280\",\n primary: \"#111111\",\n onPrimary: \"#FFFFFF\",\n primarySoft: \"rgba(17,17,17,0.06)\",\n border: \"#E4E4E7\",\n borderStrong: \"#C7C7CC\",\n disabled: \"#EBEBEB\",\n success: \"#16A34A\",\n warning: \"#D97706\",\n error: \"#DC2626\",\n info: \"#2563EB\",\n },\n fonts: {\n regular: undefined,\n medium: undefined,\n bold: undefined,\n baseSize: 16,\n scale: 1,\n },\n radius: {\n sm: 8,\n md: 12,\n lg: 16,\n full: 9999,\n },\n spacing: {\n xs: 4,\n sm: 8,\n md: 16,\n lg: 24,\n xl: 32,\n },\n // Circled (pill) CTA by default; an app can pass `button: { radius: 12 }` for\n // a rounded rectangle, or override height/paddingX to match its design system.\n button: {\n radius: 9999,\n height: 52,\n paddingX: 24,\n },\n};\n\n/**\n * Deep-merge a partial theme over the default. Two levels deep is enough — the\n * theme is intentionally shallow (colors/fonts/radius/spacing), so we merge each\n * known sub-object and leave scalars to overwrite.\n */\nexport const mergeTheme = (\n override?: Partial<OnboardingTheme>,\n): OnboardingTheme => {\n if (!override) return defaultOnboardingTheme;\n return {\n colors: { ...defaultOnboardingTheme.colors, ...override.colors },\n fonts: { ...defaultOnboardingTheme.fonts, ...override.fonts },\n radius: { ...defaultOnboardingTheme.radius, ...override.radius },\n spacing: { ...defaultOnboardingTheme.spacing, ...override.spacing },\n button: { ...defaultOnboardingTheme.button, ...override.button },\n };\n};\n","/**\n * ThemeContext — provides the resolved OnboardingTheme to every shell element and\n * themed card via `useOnboardingTheme()`. WHY a context rather than prop-drilling:\n * the cards are mounted by the SDK's ComponentRenderer (not by us), so we can't\n * pass them props directly — they must read the theme from context.\n *\n * ── WHY THE CONTEXT LIVES ON A `Symbol.for` SLOT ───────────────────────────────────────────────\n *\n * It was a plain `createContext(...)`, and tsup inlines this module into FIVE dist bundles\n * (`.`, `./reviews`, `./questionnaire`, `./coachmarks`, `./showcase`) — so each one carried its own\n * context instance. `OnboardingThemeProvider` is exported ONLY from the root barrel, so on any\n * `dist` resolution path (plain RN CLI, `unstable_enablePackageExports: false`, node, jest, SSR) a\n * host that wrapped its tree in `<OnboardingThemeProvider>` and rendered `<ReviewGate>` from\n * `@wireai/activation/reviews` was writing one context and reading another. Nothing crashed and\n * nothing warned: `useOnboardingTheme`'s `ctx ?? mergeTheme()` fallback quietly served the NEUTRAL\n * default theme, so the tenant's brand simply did not apply to the gate. On-device this was masked\n * only because Metro's `react-native` export condition collapses every subpath back to this one\n * `src/` file — the same \"bundler accident, not a guarantee\" the `currentSession` header names, and\n * the same root cause as the optional-peers bug 0.13.3 fixed.\n *\n * The bundler-agnostic fix, exactly as `coachmarks/runtime`, `analytics/currentSession`,\n * `context/deviceId` and `features/WireFeaturesProvider` already do it: park the ONE context on a\n * well-known `globalThis` slot keyed by `Symbol.for(...)`. `Symbol.for` uses the runtime-global\n * symbol registry, so every inlined copy of this module resolves the SAME symbol, finds the slot\n * already filled, and reuses that instance — one context identity however many copies exist.\n * `globalThis` is present and identical in Hermes/React Native, Node and SSR (we never touch\n * `window`), so this is safe on every host. `test/canary/themeContextIdentity.test.tsx` measures it\n * in the BUILT artifact, because the defect is invisible in source.\n */\nimport React, { createContext, useContext, useMemo } from \"react\";\nimport { mergeTheme } from \"./defaultTheme\";\nimport type { OnboardingTheme } from \"./types\";\n\n/**\n * Well-known key into the runtime-global symbol registry. `Symbol.for` (NOT a plain `Symbol()`) is\n * what makes this cross-bundle: it returns the SAME symbol for the same string across every copy of\n * this module, so duplicated inlined copies all address one slot.\n *\n * @globalSlot LATCH — the React context object is minted by the first copy of this module to load\n * and every later copy ADOPTS it (the `if (!…)` guard below says so in one line). A second write\n * re-splits the identity: `<OnboardingThemeProvider>` (root barrel only) publishes into one context\n * while `<ReviewGate>` from a subpath reads another, and `useOnboardingTheme`'s `ctx ?? mergeTheme()`\n * fallback quietly serves the NEUTRAL theme. Because it is a latch, and only because of that, the\n * module-local `const OnboardingThemeContext` below may cache it.\n */\nconst THEME_CONTEXT_SLOT: unique symbol = Symbol.for(\"@wireai/activation:themeContext\");\n\ntype GlobalWithThemeContext = typeof globalThis & {\n [THEME_CONTEXT_SLOT]?: React.Context<OnboardingTheme | null>;\n};\n\nconst themeGlobal = globalThis as GlobalWithThemeContext;\n\n// First copy to load creates the context; every later copy adopts it. Never overwrite an existing\n// slot — a second `createContext` here would re-split the identity this guard exists to keep whole.\nif (!themeGlobal[THEME_CONTEXT_SLOT]) {\n themeGlobal[THEME_CONTEXT_SLOT] = createContext<OnboardingTheme | null>(null);\n}\nconst OnboardingThemeContext = themeGlobal[THEME_CONTEXT_SLOT] as React.Context<OnboardingTheme | null>;\n\nexport type OnboardingThemeProviderProps = {\n /** Partial overrides merged over the neutral default theme. */\n theme?: Partial<OnboardingTheme>;\n children: React.ReactNode;\n};\n\nexport const OnboardingThemeProvider: React.FC<OnboardingThemeProviderProps> = ({\n theme,\n children,\n}) => {\n const resolved = useMemo(() => mergeTheme(theme), [theme]);\n return (\n <OnboardingThemeContext.Provider value={resolved}>\n {children}\n </OnboardingThemeContext.Provider>\n );\n};\n\n/**\n * Read the active theme. Falls back to the default theme when used outside a\n * provider so a stray card never crashes — it just renders neutral.\n */\nexport const useOnboardingTheme = (): OnboardingTheme => {\n const ctx = useContext(OnboardingThemeContext);\n return ctx ?? mergeTheme();\n};\n","/**\n * expoBlur — resolve `expo-blur`'s `BlurView`, lazily and optionally.\n *\n * ── WHY THIS DOES NOT BREAK THE NO-NATIVE-DEPENDENCY POLICY ──────────────────────────────\n *\n * `expo-blur` is an OPTIONAL peer of the coachmarks subpath. The spotlight overlay frosts the\n * screen with it WHEN it is installed, and degrades to a plain dimmed scrim when it is not — the\n * ring, tooltip and gestures behave identically either way (see SpotlightOverlay). So a host that\n * never installs `expo-blur` can still run the guided tour, and the free tier that must load under\n * Expo Go is not forced into a native module it cannot take.\n *\n * Before this file, `SpotlightOverlay` did `import { BlurView } from \"expo-blur\"` at module scope,\n * and `coachmarks/index.ts` re-exports the overlay with no wildcard escape — so importing ANYTHING\n * from `@wireai/activation/coachmarks`, even `setCoachmarkStorage`, dragged the peer in and a host\n * without it hit a Metro resolution failure. This resolver removes that static edge.\n *\n * ── THE SPECIFIER MUST BE A STRING LITERAL, INSIDE A TRY/CATCH ───────────────────────────\n *\n * This follows `icons/expoIcons.ts` exactly, and its header carries the full autopsy. In short:\n *\n * • Metro collects dependencies STATICALLY, matching a call whose callee is literally the\n * identifier `require` and whose argument is a STRING LITERAL. A variable specifier\n * (`const req = require; req(name)`) is collected NOWHERE, so the module never enters the\n * bundle — and the aliased `require` is Metro's own numeric-id-keyed `metroRequire`, which can\n * never resolve a package-name string. That shape shipped broken once; do not restore it.\n * • The call sitting inside a TRY/CATCH is literally how Metro marks the dependency `isOptional`:\n * when the peer is absent Metro puts `null` in the dependencyMap and the require throws \"Cannot\n * find module\" straight into the catch below. Do NOT \"simplify\" the try/catch away — it is what\n * keeps the peer optional, not just tidy. (`withWireOnboarding` in metro/index.js adds a\n * stub-to-empty-module safety net for hosts that disable Metro's `allowOptionalDependencies`.)\n */\nimport type { ComponentType } from \"react\";\n\n// Metro injects a module-scoped `require`; it is ABSENT in a pure-ESM runtime (the kit's own\n// tests run under `node --test` as ESM). Declared locally so this type-checks without ambient\n// Node types; the `typeof` guard keeps the reference ESM-safe.\ndeclare const require: ((id: string) => unknown) | undefined;\n\n/** A `require`-like resolver. Injectable in tests; production uses the guarded literal require. */\nexport type OptionalRequire = (moduleName: string) => unknown;\n\n/** The minimal prop shape the overlay uses from `expo-blur`'s `BlurView`. */\nexport type BlurViewComponent = ComponentType<{\n intensity?: number;\n tint?: \"light\" | \"dark\" | \"default\";\n style?: unknown;\n children?: unknown;\n}>;\n\n/**\n * The production resolver. The specifier is a LITERAL so Metro collects it (see the header); the\n * `moduleName` parameter exists only to keep the `OptionalRequire` seam shape, so anything other\n * than the one module this file owns resolves to undefined.\n */\nconst runtimeRequire: OptionalRequire = (moduleName) => {\n if (moduleName !== \"expo-blur\") return undefined;\n if (typeof require !== \"function\") return undefined;\n try {\n return require(\"expo-blur\");\n } catch {\n return undefined;\n }\n};\n\n/**\n * TEST-ONLY seam. `SpotlightOverlay`'s public props are frozen, so it cannot take a `requireModule`\n * the way `WireIcon` does — this lets a component render exercise the PRESENT path without the\n * native peer installed. Production never sets it; `runtimeRequire` is the only resolver.\n */\nlet testRequire: OptionalRequire | undefined;\nexport const __setBlurRequireForTests = (fn: OptionalRequire | undefined): void => {\n testRequire = fn;\n cached = undefined;\n};\n\n/** Read a module's `default` (Expo modules are consumed as default exports) or the namespace. */\nconst interop = (mod: unknown): Record<string, unknown> | undefined => {\n if (!mod || typeof mod !== \"object\") return undefined;\n const ns = mod as Record<string, unknown>;\n // `expo-blur` exposes `BlurView` as a NAMED export; prefer the namespace when it already carries\n // it, and only fall back to `default` for a CJS-interop wrapper.\n if (ns.BlurView) return ns;\n const def = (mod as { default?: unknown }).default;\n if (def && typeof def === \"object\") return def as Record<string, unknown>;\n return ns;\n};\n\n/**\n * Narrow an unknown export to something mountable. `BlurView` is a real React component (function\n * or class across versions), and React.memo / forwardRef wrappers are objects carrying `$$typeof`.\n * Reject anything else rather than handing the reconciler a non-component.\n */\nconst asComponent = (value: unknown): BlurViewComponent | undefined => {\n if (typeof value === \"function\") return value as BlurViewComponent;\n if (value && typeof value === \"object\" && \"$$typeof\" in (value as object)) {\n return value as BlurViewComponent;\n }\n return undefined;\n};\n\n/**\n * Module-level memo. `null` = \"we looked and it is not there\" (distinct from \"not looked yet\"),\n * so an absent peer costs exactly one failed require per process, not one per overlay mount.\n */\nlet cached: BlurViewComponent | null | undefined;\n\n/** Reset the memo. TEST-ONLY seam — production never calls it. */\nexport const resetBlurModuleCache = (): void => {\n cached = undefined;\n};\n\n/**\n * Resolve the `BlurView` component, or undefined when the peer is absent/unresolvable.\n * Never throws: an absent blur must degrade to a plain scrim, never break the tour.\n *\n * `requireModule` is injectable so tests can exercise BOTH the found and absent paths without\n * installing the native peer (same convention as `resolveIconFamily` / `detectAppVersion`).\n */\nexport const resolveBlurView = (\n requireModule: OptionalRequire = testRequire ?? runtimeRequire,\n): BlurViewComponent | undefined => {\n try {\n if (cached === undefined || requireModule !== runtimeRequire) {\n const resolved = interop(requireModule(\"expo-blur\"));\n const component = resolved ? asComponent(resolved.BlurView) : undefined;\n // Don't poison the module memo from an injected test require.\n if (requireModule === runtimeRequire) cached = component ?? null;\n return component;\n }\n if (cached === null) return undefined;\n return cached;\n } catch {\n return undefined;\n }\n};\n","/**\n * useReducedMotion — the kit's ONE reduce-motion gate. Reads the OS setting via\n * AccessibilityInfo and stays subscribed to `reduceMotionChanged`, so every\n * animated component lands on its final frame (or a ~120ms fade) the moment the\n * user flips the setting — no restart needed.\n *\n * This closes the gap documented in ai_rules/rules/performance.md §3: every\n * animation in the kit must consume this hook (usually through the pure helpers\n * in motionSpec.ts: `entranceSpec` / `stateChangeDuration` / `loopEnabled`).\n */\nimport { useEffect, useState } from \"react\";\nimport { AccessibilityInfo } from \"react-native\";\n\n// Last-known value, module-level: cards remount every turn (keyed on message id),\n// and a `useState(false)` default would flash one animated frame per turn for a\n// reduce-motion user before the async read resolves.\nlet lastKnown = false;\n\nexport const useReducedMotion = (): boolean => {\n const [reduced, setReduced] = useState(lastKnown);\n\n useEffect(() => {\n let mounted = true;\n AccessibilityInfo.isReduceMotionEnabled()\n .then((value) => {\n lastKnown = value;\n if (mounted) setReduced(value);\n })\n .catch(() => {\n // Unavailable (e.g. some test envs): keep the last-known value.\n });\n const sub = AccessibilityInfo.addEventListener(\"reduceMotionChanged\", (value) => {\n lastKnown = value;\n setReduced(value);\n });\n return () => {\n mounted = false;\n sub?.remove();\n };\n }, []);\n\n return reduced;\n};\n","/**\n * reanimated — resolve `react-native-reanimated`, lazily and optionally.\n *\n * ── WHY THIS DOES NOT BREAK THE NO-NATIVE-DEPENDENCY POLICY ──────────────────────────────\n *\n * `react-native-reanimated` is an OPTIONAL peer of the coachmarks subpath. `SpotlightOverlay` and\n * `GestureHint` animate with it WHEN it is installed, and fall back to a STATIC render of the same\n * visual when it is not — same ring, same tooltip, same glyph, same copy, same gestures, just\n * without motion. So a host that never installs it can still run the guided tour and the feature\n * showcase, and an Expo Go / Lite build is not forced into a native module it cannot take.\n *\n * Before this file, both components did `import Animated, { … } from \"react-native-reanimated\"` at\n * module scope, and `coachmarks/index.ts` re-exports them with no wildcard escape — so importing\n * ANYTHING from `@wireai/activation/coachmarks` (even `setCoachmarkStorage`) dragged the peer in,\n * and a host without it hit a Metro resolution failure. `@wireai/activation/showcase` inherited the\n * same edge through `GestureHint`. This resolver removes it. Same class as the 0.14.2 `expo-blur`\n * fix (`expoBlur.ts`), same shape, one size up.\n *\n * ── THE SPECIFIER MUST BE A STRING LITERAL, INSIDE A TRY/CATCH ───────────────────────────\n *\n * This follows `icons/expoIcons.ts` and `coachmarks/expoBlur.ts` exactly, and expoIcons' header\n * carries the full autopsy. In short: Metro collects dependencies STATICALLY, matching a call whose\n * callee is literally the identifier `require` and whose argument is literally a string — an\n * aliased callee (`const req = require; req(name)`) or a variable specifier is collected NOWHERE,\n * so the module never enters the bundle (that shape shipped broken in 0.8.0). And the call sitting\n * inside a TRY/CATCH is literally how Metro marks the dependency `isOptional`, which is what lets\n * an absent peer degrade instead of failing the build. Do NOT \"simplify\" either half away.\n *\n * ── WHY THE EXPORTS ARE BARE FUNCTIONS WITH THE PEER'S OWN NAMES ─────────────────────────\n *\n * The call sites import `useAnimatedStyle` / `useAnimatedProps` / `withTiming` … from HERE instead\n * of from the peer, and call them unqualified, exactly as before. That is load-bearing, not style:\n * reanimated's Babel plugin decides what to workletize by the CALLEE NAME (`react-native-worklets`\n * `plugin/index.js` → `reanimatedFunctionHooks` / `reanimatedFunctionArgsToWorkletize`; it reads\n * `callee.name`, or `callee.property.name` for a member call, and never checks which module the\n * name came from). Keeping the names identical keeps every worklet in `SpotlightOverlay` and\n * `GestureHint` workletized byte-for-byte on a host that HAS the peer. Rename them and the\n * animations silently stop running on the UI thread.\n *\n * ── THE DEGRADE: THE FINAL FRAME, NOT A DEAD ONE ─────────────────────────────────────────\n *\n * The shim resolves every animation to its RESTING value — `withTiming(to)` is `to`,\n * `withSequence(a, b)` is `b`, `withRepeat(x)` is `x` — so a component lands on the pose it would\n * have settled into anyway (ring at scale 1, glyph at full opacity, blur at BLUR_INTENSITY) rather\n * than on frame zero, which for the blur would have meant a fully transparent overlay. Shared\n * values are state-backed so a write from an effect actually reaches the next render; reanimated's\n * own values do not need this because they drive the UI thread directly. The kit's own\n * AccessibilityInfo-backed `useReducedMotion` stands in for the peer's, so the reduce-motion\n * contract in ai_rules/rules/performance.md §3 holds with or without the peer.\n *\n * This is also what `ai_rules/rules/frequent_rules.md` #1 prescribes: when the kit needs motion\n * without the optional peer, it uses core React Native, never Reanimated.\n */\nimport {\n createElement,\n forwardRef,\n useReducer,\n useRef,\n type ComponentType,\n type ReactNode,\n} from \"react\";\nimport { View, type ViewProps, type ViewStyle } from \"react-native\";\n\nimport { useReducedMotion as useOsReducedMotion } from \"../motion/useReducedMotion\";\n\n// Metro injects a module-scoped `require`; it is ABSENT in a pure-ESM runtime (the kit's own tests\n// run under `node --test` as ESM). Declared locally so this type-checks without ambient Node types;\n// the `typeof` guard keeps the reference ESM-safe.\ndeclare const require: ((id: string) => unknown) | undefined;\n\n/** A `require`-like resolver. Injectable in tests; production uses the guarded literal require. */\nexport type OptionalRequire = (moduleName: string) => unknown;\n\n/** A reanimated shared value, narrowed to the one member the kit uses. */\nexport interface SharedValue<T> {\n value: T;\n}\n\n/** Props `Animated.View` accepts on top of a plain View (layout-animation descriptors). */\nexport interface AnimatedViewProps extends ViewProps {\n entering?: unknown;\n exiting?: unknown;\n children?: ReactNode;\n}\n\n/** A component built by `createAnimatedComponent`: its own props plus reanimated's driven props. */\nexport type AnimatedComponent<P> = ComponentType<P & { animatedProps?: object }>;\n\n/** The slice of reanimated the coachmark surfaces actually use. */\nexport interface ReanimatedApi {\n /** True when the real peer resolved; false when this is the static fallback. */\n present: boolean;\n View: ComponentType<AnimatedViewProps>;\n createAnimatedComponent: <P extends object>(component: ComponentType<P>) => AnimatedComponent<P>;\n useSharedValue: <T>(initial: T) => SharedValue<T>;\n useAnimatedStyle: (factory: () => ViewStyle) => ViewStyle;\n useAnimatedProps: <P extends object>(factory: () => P) => P;\n useReducedMotion: () => boolean;\n withTiming: (toValue: number, config?: object) => number;\n withRepeat: (animation: number, count?: number, reverse?: boolean) => number;\n withSequence: (...animations: number[]) => number;\n withDelay: (ms: number, animation: number) => number;\n /** The `entering` / `exiting` descriptors, or undefined when the peer is absent. */\n fadeIn: (durationMs: number) => unknown;\n fadeOut: (durationMs: number) => unknown;\n}\n\n/**\n * The production resolver. The specifier is a LITERAL so Metro collects it (see the header); the\n * `moduleName` parameter exists only to keep the `OptionalRequire` seam shape, so anything other\n * than the one module this file owns resolves to undefined.\n */\nconst runtimeRequire: OptionalRequire = (moduleName) => {\n if (moduleName !== \"react-native-reanimated\") return undefined;\n if (typeof require !== \"function\") return undefined;\n try {\n return require(\"react-native-reanimated\");\n } catch {\n return undefined;\n }\n};\n\n/**\n * TEST-ONLY seam. `SpotlightOverlay` / `GestureHint` have frozen public props, so neither can take\n * a `requireModule` the way `WireIcon` does — this lets a component render exercise the PRESENT\n * path. Production never sets it; `runtimeRequire` is the only resolver.\n */\nlet testRequire: OptionalRequire | undefined;\nexport const __setReanimatedRequireForTests = (fn: OptionalRequire | undefined): void => {\n testRequire = fn;\n cached = undefined;\n};\n\n// ── the static fallback ───────────────────────────────────────────────────────\n\n/**\n * A shared value that re-renders its owner on write. Reanimated's own value drives the UI thread\n * and deliberately does NOT re-render; here the render IS the only output, so a value written from\n * an effect (`intensity.value = withTiming(26)`) has to reach it or the overlay would sit on frame\n * zero forever — a fully transparent blur. The box identity is stable for the component's lifetime,\n * exactly like the real one, so it stays safe in a dependency list.\n */\nconst useStaticSharedValue = <T,>(initial: T): SharedValue<T> => {\n const [, bump] = useReducer((n: number): number => n + 1, 0);\n const box = useRef<SharedValue<T> | null>(null);\n if (box.current === null) {\n let current = initial;\n box.current = {\n get value(): T {\n return current;\n },\n set value(next: T) {\n if (Object.is(next, current)) return;\n current = next;\n bump();\n },\n };\n }\n return box.current;\n};\n\n/** Run a worklet body on the JS side. It must never throw into the render — degrade, don't crash. */\nconst runWorklet = <R extends object>(factory: () => R, fallback: R): R => {\n try {\n return factory() ?? fallback;\n } catch {\n return fallback;\n }\n};\n\n/** `Animated.View` without the peer: a plain View, with the layout-animation props dropped. */\nconst StaticAnimatedView = forwardRef<View, AnimatedViewProps>(function StaticAnimatedView(\n { entering: _entering, exiting: _exiting, children, ...rest },\n ref,\n) {\n return createElement(View, { ...rest, ref }, children);\n});\n\n/**\n * `createAnimatedComponent` without the peer. The wrapper MERGES `animatedProps` into the real\n * props, because that object is the only carrier for values the worklet would have driven (the\n * spotlight's blur `intensity`). Built once per wrapped component at the call site's `useMemo`, so\n * the returned type identity is stable and React never remounts the subtree.\n */\nconst staticCreateAnimatedComponent = <P extends object>(\n component: ComponentType<P>,\n): AnimatedComponent<P> =>\n function StaticAnimatedComponent({ animatedProps, ...rest }) {\n return createElement(component, { ...(rest as P), ...(animatedProps as object) });\n };\n\n/**\n * The peer-absent API. Every animation resolves to its RESTING value, so components render the\n * frame they would have settled on. Nothing here schedules work, allocates a native module, or\n * throws.\n */\nconst staticApi: ReanimatedApi = {\n present: false,\n View: StaticAnimatedView,\n createAnimatedComponent: staticCreateAnimatedComponent,\n useSharedValue: useStaticSharedValue,\n useAnimatedStyle: (factory) => runWorklet(factory, {}),\n useAnimatedProps: (factory) => runWorklet(factory, {} as never),\n useReducedMotion: useOsReducedMotion,\n withTiming: (toValue) => toValue,\n withRepeat: (animation) => animation,\n withSequence: (...animations) => animations[animations.length - 1] ?? 0,\n withDelay: (_ms, animation) => animation,\n fadeIn: () => undefined,\n fadeOut: () => undefined,\n};\n\n// ── the real peer ─────────────────────────────────────────────────────────────\n\nconst isFunction = (value: unknown): boolean => typeof value === \"function\";\n\n/** A React component is a function, or an object carrying `$$typeof` (memo / forwardRef). */\nconst isComponent = (value: unknown): boolean =>\n typeof value === \"function\" || (!!value && typeof value === \"object\" && \"$$typeof\" in value);\n\n/**\n * Build the API from a resolved module namespace, or undefined when it is not the module we expect.\n *\n * The hooks are NAMED exports; `View` and `createAnimatedComponent` live on the DEFAULT export (the\n * `Animated` object). A CJS interop wrapper puts everything one level down under `default`, so both\n * are looked up on the namespace first and the default second. EVERY member is verified before the\n * namespace is accepted: a partial module must degrade to the static fallback, never crash halfway\n * through a render.\n */\nconst fromModule = (mod: unknown): ReanimatedApi | undefined => {\n if (!mod || typeof mod !== \"object\") return undefined;\n const ns = mod as Record<string, unknown>;\n const def =\n ns.default && typeof ns.default === \"object\"\n ? (ns.default as Record<string, unknown>)\n : undefined;\n const pick = (name: string): unknown => ns[name] ?? def?.[name];\n\n const view = def?.View ?? ns.View;\n const createAnimated = def?.createAnimatedComponent ?? ns.createAnimatedComponent;\n const hooks = {\n useSharedValue: pick(\"useSharedValue\"),\n useAnimatedStyle: pick(\"useAnimatedStyle\"),\n useAnimatedProps: pick(\"useAnimatedProps\"),\n useReducedMotion: pick(\"useReducedMotion\"),\n withTiming: pick(\"withTiming\"),\n withRepeat: pick(\"withRepeat\"),\n withSequence: pick(\"withSequence\"),\n withDelay: pick(\"withDelay\"),\n };\n const fadeIn = pick(\"FadeIn\");\n const fadeOut = pick(\"FadeOut\");\n\n if (!isComponent(view) || !isFunction(createAnimated)) return undefined;\n if (Object.values(hooks).some((member) => !isFunction(member))) return undefined;\n if (!fadeIn || !fadeOut) return undefined;\n\n // The single narrowing seam. Everything above proved the members exist and are callable; the peer\n // is untyped here (it is resolved through `unknown`), so the cast happens once, at the boundary,\n // and the exported signatures above are the contract from here on.\n const api = {\n present: true,\n View: view,\n createAnimatedComponent: createAnimated,\n ...hooks,\n fadeIn: (durationMs: number) => (fadeIn as { duration: (ms: number) => unknown }).duration(durationMs),\n fadeOut: (durationMs: number) => (fadeOut as { duration: (ms: number) => unknown }).duration(durationMs),\n } as unknown as ReanimatedApi;\n return api;\n};\n\n/**\n * Module-level memo. Holds the RESOLVED api (real or static), so an absent peer costs exactly one\n * failed require per process, not one per mount — and, more importantly, so the implementation can\n * never change between two renders of the same component, which would break the rules of hooks.\n */\nlet cached: ReanimatedApi | undefined;\n\n/** Reset the memo. TEST-ONLY seam — production never calls it. */\nexport const resetReanimatedModuleCache = (): void => {\n cached = undefined;\n};\n\n/**\n * Resolve the reanimated API, or the static fallback when the peer is absent/unresolvable.\n * Never throws and never returns undefined: an absent animation library must degrade to a still\n * frame, never break the tour.\n */\nexport const resolveReanimated = (\n requireModule: OptionalRequire = testRequire ?? runtimeRequire,\n): ReanimatedApi => {\n try {\n if (cached === undefined || requireModule !== runtimeRequire) {\n const resolved = fromModule(requireModule(\"react-native-reanimated\")) ?? staticApi;\n // Don't poison the module memo from an injected test require.\n if (requireModule === runtimeRequire) cached = resolved;\n return resolved;\n }\n return cached;\n } catch {\n return staticApi;\n }\n};\n\n// ── the call-site surface: the peer's own names, resolved lazily ──────────────\n//\n// Each one delegates on every call, so nothing is resolved at import time. `api()` is memoized, so\n// the delegation is a property read.\n\nconst api = (): ReanimatedApi => resolveReanimated();\n\n/**\n * The `Animated` namespace, with `View` behind a getter so merely importing this module never\n * touches the peer. The component identity it returns is stable (the peer's own `Animated.View`, or\n * the module-level `StaticAnimatedView`), so React never remounts the tree under it.\n */\nexport const Animated: {\n readonly View: ComponentType<AnimatedViewProps>;\n createAnimatedComponent: <P extends object>(component: ComponentType<P>) => AnimatedComponent<P>;\n} = {\n get View() {\n return api().View;\n },\n createAnimatedComponent: (component) => api().createAnimatedComponent(component),\n};\n\n/** Layout-animation descriptors. `.duration()` is the only builder the kit uses. */\nexport const FadeIn = { duration: (durationMs: number): unknown => api().fadeIn(durationMs) };\nexport const FadeOut = { duration: (durationMs: number): unknown => api().fadeOut(durationMs) };\n\nexport const useSharedValue = <T,>(initial: T): SharedValue<T> => api().useSharedValue(initial);\nexport const useAnimatedStyle = (factory: () => ViewStyle): ViewStyle =>\n api().useAnimatedStyle(factory);\nexport const useAnimatedProps = <P extends object>(factory: () => P): P =>\n api().useAnimatedProps(factory);\nexport const useReducedMotion = (): boolean => api().useReducedMotion();\nexport const withTiming = (toValue: number, config?: object): number =>\n api().withTiming(toValue, config);\nexport const withRepeat = (animation: number, count?: number, reverse?: boolean): number =>\n api().withRepeat(animation, count, reverse);\nexport const withSequence = (...animations: number[]): number => api().withSequence(...animations);\nexport const withDelay = (ms: number, animation: number): number => api().withDelay(ms, animation);\n","import React, { useEffect, useMemo, type ReactNode } from \"react\";\nimport { StyleSheet, View } from \"react-native\";\n\nimport {\n Animated,\n useAnimatedStyle,\n useReducedMotion,\n useSharedValue,\n withDelay,\n withRepeat,\n withSequence,\n withTiming,\n} from \"./reanimated\";\nimport type { GestureKind } from \"./types\";\n\n/**\n * Abstract gesture pictogram shown beside a coachmark tooltip. With the OPTIONAL\n * `react-native-reanimated` peer installed every animation runs on the UI thread\n * (shared values + worklets), never setState, so it costs nothing on the JS\n * thread. Honors Reduce Motion by dropping the motion loop and rendering the\n * glyph static.\n *\n * The peer is reached through the guarded lazy require in `reanimated.ts`, never\n * a static import, so `@wireai/activation/coachmarks` (and `/showcase`, which\n * reaches this component through FeatureShowcase) builds on a host that never\n * installed it. Absent, the glyph renders STATICALLY at its resting frame — the\n * same capsules, ring, dot and motion track, at full opacity and no travel, with\n * one render instead of a UI-thread loop. The pictogram never disappears.\n *\n * NO drawn-hand anatomy. Swipes render the standard two-finger swipe glyph: two\n * rounded vertical capsules (an abstract index + middle finger, slightly\n * different heights) with a short, fading motion track trailing behind them along\n * the swipe axis. The whole glyph is rotated per direction (up/down/left/right)\n * and the capsules slide along the axis, fading, in a UI-thread loop. Pinch/zoom\n * reuse the two-capsule abstraction spreading apart. Tap / double-tap render a\n * minimal pulsing tap-target (ring + dot).\n *\n * Every glyph is a self-drawn primitive built from Views/borders (no vector-icon\n * dependency, like AnimatedSparkle). Pass `renderHand` — the glyph slot — to\n * substitute your own node while keeping the tuned motion. (The name is kept for\n * backward compatibility; despite it, the default is a glyph, not a drawn hand.)\n *\n * NOTE: the coachmark path (SpotlightOverlay) and the showcase path\n * (FeatureShowcase) both SKIP this component for `tap` / `double_tap` — those\n * steps show only the highlight ring + tooltip, no glyph. The tap visual here\n * exists for direct / standalone use.\n */\nexport interface GestureHintProps {\n type: GestureKind;\n /** Overall glyph size in px. */\n size?: number;\n /** Glyph color. Defaults to white (reads on the dark blur backdrop). */\n color?: string;\n /**\n * Provide a custom glyph node in place of the default self-drawn primitive; it\n * inherits the tuned motion (slide+fade for swipes, pulse for tap). Kept as\n * `renderHand` for backward compatibility — despite the name it is just the\n * glyph slot, no longer a drawn hand.\n */\n renderHand?: (props: { size: number; color: string }) => ReactNode;\n}\n\n/** Travel distance for the directional swipe loop (local glyph axis). */\nconst TRAVEL = 26;\nconst SWIPE_MS = 700;\nconst TAP_MS = 320;\nconst SPREAD_MS = 620;\n\n/**\n * Per-direction rotation of the whole glyph. Canonical orientation is \"up\":\n * capsules point up, travel up, motion track trailing below. Rotating the\n * container reorients both the capsules and the track together, and rotates the\n * local translate axis so the same upward loop reads correctly per direction.\n */\nconst GLYPH_ROTATION: Record<string, string> = {\n swipe_up: \"0deg\",\n swipe_down: \"180deg\",\n swipe_left: \"-90deg\",\n swipe_right: \"90deg\",\n};\n\n/**\n * The two-finger abstraction: two rounded vertical capsules side by side with\n * slightly different heights (index taller than middle), aligned at the base —\n * the standard swipe pictogram look. Self-drawn from Views only.\n */\nconst FingerPair: React.FC<{ size: number; color: string }> = ({ size, color }) => {\n const { row, index, middle } = useMemo(() => {\n const w = size * 0.2;\n const r = w / 2;\n return {\n row: { flexDirection: \"row\" as const, alignItems: \"flex-end\" as const, gap: size * 0.08 },\n index: { width: w, height: size * 0.54, borderRadius: r, backgroundColor: color },\n middle: { width: w, height: size * 0.44, borderRadius: r, backgroundColor: color },\n };\n }, [size, color]);\n\n return (\n <View style={row} pointerEvents=\"none\">\n <View style={index} />\n <View style={middle} />\n </View>\n );\n};\n\n/**\n * A short, tapering motion track that sits behind the capsules (below, in the\n * canonical \"up\" orientation) — two slim, fading ticks that shrink and dim with\n * distance. Subtle: it reads as the path the fingers just travelled, not a comet\n * tail. Static (the capsules carry the motion via the slide loop).\n */\nconst MotionTrack: React.FC<{ size: number; color: string }> = ({ size, color }) => {\n const { wrap, tick0, tick1 } = useMemo(() => {\n const h = Math.max(2, size * 0.05);\n return {\n wrap: { alignItems: \"center\" as const, marginTop: size * 0.1, gap: size * 0.06 },\n tick0: {\n width: size * 0.3,\n height: h,\n borderRadius: h / 2,\n backgroundColor: color,\n opacity: 0.4,\n },\n tick1: {\n width: size * 0.18,\n height: h,\n borderRadius: h / 2,\n backgroundColor: color,\n opacity: 0.16,\n },\n };\n }, [size, color]);\n\n return (\n <View style={wrap} pointerEvents=\"none\">\n <View style={tick0} />\n <View style={tick1} />\n </View>\n );\n};\n\nconst GestureHintComponent: React.FC<GestureHintProps> = ({\n type,\n size = 34,\n color = \"white\",\n renderHand,\n}) => {\n const translate = useSharedValue(0);\n const opacity = useSharedValue(1);\n const pulse = useSharedValue(1);\n const spread = useSharedValue(0);\n const reduced = useReducedMotion();\n\n const isSwipe =\n type === \"swipe_up\" ||\n type === \"swipe_down\" ||\n type === \"swipe_left\" ||\n type === \"swipe_right\";\n const isSpread = type === \"pinch\" || type === \"zoom\";\n const isTap = type === \"tap\" || type === \"double_tap\";\n\n useEffect(() => {\n if (type === \"none\" || reduced) return undefined;\n\n if (isTap) {\n pulse.value = withRepeat(\n withSequence(\n withTiming(0.82, { duration: TAP_MS }),\n withTiming(1, { duration: TAP_MS }),\n ),\n -1,\n false,\n );\n opacity.value = withRepeat(\n withSequence(\n withTiming(0.55, { duration: TAP_MS }),\n withTiming(1, { duration: TAP_MS }),\n ),\n -1,\n false,\n );\n return undefined;\n }\n\n if (isSpread) {\n // Two capsules easing apart and back — a minimal pinch/zoom abstraction.\n spread.value = withRepeat(\n withSequence(\n withTiming(size * 0.26, { duration: SPREAD_MS }),\n withTiming(0, { duration: SPREAD_MS }),\n ),\n -1,\n false,\n );\n return undefined;\n }\n\n // Directional swipe: slide the capsules along the local \"up\" axis, fading\n // out, then snap back and repeat. The container rotation (below) reorients\n // this loop per direction, so the local motion is always the same.\n translate.value = withRepeat(\n withSequence(\n withTiming(0, { duration: 0 }),\n withTiming(-TRAVEL, { duration: SWIPE_MS }),\n withDelay(140, withTiming(0, { duration: 0 })),\n ),\n -1,\n false,\n );\n opacity.value = withRepeat(\n withSequence(\n withTiming(1, { duration: SWIPE_MS / 2 }),\n withTiming(0, { duration: SWIPE_MS / 2 }),\n withDelay(140, withTiming(1, { duration: 0 })),\n ),\n -1,\n false,\n );\n return undefined;\n }, [type, reduced, isTap, isSpread, translate, opacity, pulse, spread, size]);\n\n const swipeAnimatedStyle = useAnimatedStyle(() => ({\n opacity: opacity.value,\n transform: [{ translateY: translate.value }],\n }));\n const tapAnimatedStyle = useAnimatedStyle(() => ({\n opacity: opacity.value,\n transform: [{ scale: pulse.value }],\n }));\n const spreadLeftStyle = useAnimatedStyle(() => ({\n transform: [{ translateX: -spread.value }],\n }));\n const spreadRightStyle = useAnimatedStyle(() => ({\n transform: [{ translateX: spread.value }],\n }));\n\n if (type === \"none\") return null;\n\n const customGlyph = renderHand ? renderHand({ size, color }) : null;\n\n if (isSwipe) {\n return (\n <View\n style={{ transform: [{ rotate: GLYPH_ROTATION[type] ?? \"0deg\" }] }}\n pointerEvents=\"none\"\n >\n <View style={styles.swipeStack}>\n <Animated.View style={swipeAnimatedStyle} pointerEvents=\"none\">\n {customGlyph ?? <FingerPair size={size} color={color} />}\n </Animated.View>\n <MotionTrack size={size} color={color} />\n </View>\n </View>\n );\n }\n\n if (isSpread) {\n const w = size * 0.2;\n const capsule = {\n width: w,\n height: size * 0.5,\n borderRadius: w / 2,\n backgroundColor: color,\n };\n return (\n <View style={[styles.spreadRow, { gap: size * 0.12 }]} pointerEvents=\"none\">\n <Animated.View style={spreadLeftStyle}>\n <View style={capsule} />\n </Animated.View>\n <Animated.View style={spreadRightStyle}>\n <View style={capsule} />\n </Animated.View>\n </View>\n );\n }\n\n // tap / double_tap — a minimal pulsing tap-target (ring + center dot).\n const ringSize = size * 0.86;\n const ringBorder = Math.max(2, size * 0.08);\n const dotSize = size * 0.32;\n return (\n <View style={[styles.tapWrap, { width: size, height: size }]} pointerEvents=\"none\">\n {customGlyph ? (\n <Animated.View style={tapAnimatedStyle} pointerEvents=\"none\">\n {customGlyph}\n </Animated.View>\n ) : (\n <>\n <Animated.View\n style={[\n styles.tapRing,\n {\n width: ringSize,\n height: ringSize,\n borderRadius: ringSize / 2,\n borderWidth: ringBorder,\n borderColor: color,\n },\n tapAnimatedStyle,\n ]}\n pointerEvents=\"none\"\n />\n <View\n style={{\n position: \"absolute\",\n width: dotSize,\n height: dotSize,\n borderRadius: dotSize / 2,\n backgroundColor: color,\n }}\n />\n </>\n )}\n </View>\n );\n};\n\nconst styles = StyleSheet.create({\n swipeStack: {\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n spreadRow: {\n flexDirection: \"row\",\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n tapWrap: {\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n tapRing: {\n backgroundColor: \"transparent\",\n },\n});\n\nexport const GestureHint = React.memo(GestureHintComponent);\nGestureHint.displayName = \"GestureHint\";\n\nexport default GestureHint;\n","import React, { useEffect, useMemo } from \"react\";\nimport {\n Pressable,\n StyleSheet,\n Text,\n useWindowDimensions,\n View,\n} from \"react-native\";\n\nimport { useOnboardingTheme } from \"../theme/ThemeContext\";\nimport { resolveBlurView } from \"./expoBlur\";\nimport { GestureHint } from \"./GestureHint\";\nimport {\n Animated,\n FadeIn,\n FadeOut,\n useAnimatedProps,\n useAnimatedStyle,\n useReducedMotion,\n useSharedValue,\n withRepeat,\n withSequence,\n withTiming,\n} from \"./reanimated\";\nimport type { GestureKind, Placement, TargetRect } from \"./types\";\n\nconst BLUR_INTENSITY = 26;\nconst FADE_MS = 280;\n/** Breathing room between the highlighted element and the glowing ring. */\nconst RING_PADDING = 10;\n/** Gap between the ring and the tooltip pill. */\nconst TOOLTIP_GAP = 14;\nconst SIDE_MARGIN = 20;\nconst PILL_MAX_WIDTH = 260;\n\nexport interface SpotlightOverlayProps {\n message: string;\n /** Window-space rect of the element to highlight. Null → centered hint (e.g. a scroll gesture). */\n targetRect?: TargetRect | null;\n gesture?: GestureKind;\n placement?: Placement;\n /** Tapping the highlighted target or the pill — advance / act. */\n onEngage: () => void;\n /** Tapping the dimmed backdrop — advance to the next step (ends the tour only on the last step). */\n onDismiss: () => void;\n /** Ring + tooltip color. Defaults to the onboarding theme's `primary`. */\n accentColor?: string;\n /** Tooltip label color. Defaults to the theme's `onPrimary`. */\n accentTextColor?: string;\n}\n\n/**\n * A single coachmark step: the whole screen is frosted with an animated blur\n * (or a plain dimmed scrim when the optional `expo-blur` peer is absent), and a\n * bright pulsing ring + tooltip point at one measured target. Mounted at the app\n * root (above the tab bar) via CoachmarkOverlayHost.\n *\n * Performance: one BlurView (mounted only while a step is visible), the ring\n * glow is a single animated view, and with `react-native-reanimated` installed\n * every animation runs on the UI thread. Reduce Motion drops the pulse.\n *\n * BOTH native peers are OPTIONAL, and each is resolved through a guarded lazy\n * require, so the subpath never carries a static top-level import of either:\n * • `expo-blur` (`expoBlur.ts`) — absent, the frost drops to an equivalent\n * dimmed scrim. The animated component is built once, on first use.\n * • `react-native-reanimated` (`reanimated.ts`) — absent, the overlay renders\n * STATICALLY at its resting frame: the ring sits at scale 1 (no pulse), the\n * blur at full BLUR_INTENSITY (no fade-in), and the whole overlay appears\n * and leaves without the fade. Nothing moves; everything renders.\n * A missing decoration must never blank a tour, so the ring, tooltip, copy and\n * gestures are identical in all four combinations.\n */\nconst SpotlightOverlayComponent: React.FC<SpotlightOverlayProps> = ({\n message,\n targetRect,\n gesture = \"none\",\n placement = \"bottom\",\n onEngage,\n onDismiss,\n accentColor,\n accentTextColor,\n}) => {\n const { height: screenH } = useWindowDimensions();\n const reduced = useReducedMotion();\n const theme = useOnboardingTheme();\n\n const accent = accentColor ?? theme.colors.primary;\n const accentText = accentTextColor ?? theme.colors.onPrimary;\n\n // Resolve the optional `expo-blur` peer and build its animated component ONCE, on first render,\n // instead of at module scope — so merely importing this file (and thus the coachmarks subpath)\n // never needs the peer. `null` = the peer is absent → the scrim path renders instead.\n const AnimatedBlurView = useMemo(() => {\n const BlurView = resolveBlurView();\n return BlurView ? Animated.createAnimatedComponent(BlurView) : null;\n }, []);\n\n // Tap / double-tap steps show ONLY the ring + tooltip — no gesture glyph. The\n // pulsing highlight ring already reads as \"tap here\", so an extra glyph is\n // noise. Every app inherits this centrally, with no config change.\n const showGesture =\n gesture !== \"none\" && gesture !== \"tap\" && gesture !== \"double_tap\";\n\n const intensity = useSharedValue(0);\n const ringScale = useSharedValue(1);\n\n useEffect(() => {\n intensity.value = withTiming(BLUR_INTENSITY, { duration: FADE_MS });\n }, [intensity]);\n\n useEffect(() => {\n if (reduced) return;\n ringScale.value = withRepeat(\n withSequence(\n withTiming(1.06, { duration: 700 }),\n withTiming(1, { duration: 700 }),\n ),\n -1,\n true,\n );\n }, [reduced, ringScale]);\n\n const blurAnimatedProps = useAnimatedProps(() => ({\n intensity: intensity.value,\n }));\n\n const ringAnimatedStyle = useAnimatedStyle(() => ({\n transform: [{ scale: ringScale.value }],\n }));\n\n // Geometry for the ring + tooltip, derived from the measured target.\n const geometry = useMemo(() => {\n if (!targetRect) return null;\n const ringLeft = targetRect.x - RING_PADDING;\n const ringTop = targetRect.y - RING_PADDING;\n const ringW = targetRect.width + RING_PADDING * 2;\n const ringH = targetRect.height + RING_PADDING * 2;\n return {\n ring: {\n left: ringLeft,\n top: ringTop,\n width: ringW,\n height: ringH,\n borderRadius: Math.min(ringW, ringH) / 2,\n },\n // Tooltip above or below the ring depending on placement.\n tooltip:\n placement === \"top\"\n ? { bottom: screenH - ringTop + TOOLTIP_GAP }\n : { top: ringTop + ringH + TOOLTIP_GAP },\n };\n }, [targetRect, placement, screenH]);\n\n return (\n <Animated.View\n style={[StyleSheet.absoluteFill, styles.root]}\n entering={FadeIn.duration(FADE_MS)}\n exiting={FadeOut.duration(FADE_MS)}\n >\n {AnimatedBlurView ? (\n <AnimatedBlurView\n tint=\"dark\"\n animatedProps={blurAnimatedProps}\n style={StyleSheet.absoluteFill}\n />\n ) : (\n // `expo-blur` absent → a plain dimmed scrim stands in for the frost. Same dark backdrop\n // the tour reads against, so the ring, tooltip and gestures behave identically.\n <Animated.View\n style={[StyleSheet.absoluteFill, styles.scrim]}\n pointerEvents=\"none\"\n />\n )}\n\n {/* Tap-the-backdrop to move on (dismisses the tour on the last step). */}\n <Pressable\n style={StyleSheet.absoluteFill}\n onPress={onDismiss}\n accessibilityRole=\"button\"\n accessibilityLabel=\"Next hint\"\n />\n\n {/* Glowing ring over the highlighted target (tap = engage). */}\n {geometry && (\n <Animated.View\n style={[\n styles.ring,\n geometry.ring,\n { borderColor: accent, shadowColor: accent },\n ringAnimatedStyle,\n ]}\n pointerEvents=\"box-none\"\n >\n <Pressable\n style={StyleSheet.absoluteFill}\n onPress={onEngage}\n accessibilityRole=\"button\"\n accessibilityLabel={message}\n />\n </Animated.View>\n )}\n\n {/* Tooltip pill: anchored to the ring, or centered for a target-less hint. */}\n <View\n style={[\n styles.tooltipWrapper,\n geometry\n ? geometry.tooltip\n : { top: screenH * 0.42, alignItems: \"center\" },\n ]}\n pointerEvents=\"box-none\"\n >\n {showGesture && (\n <View style={styles.gestureSlot} pointerEvents=\"none\">\n <GestureHint type={gesture} color={accent} />\n </View>\n )}\n <Pressable\n onPress={onEngage}\n style={[styles.pill, { backgroundColor: accent }]}\n accessibilityRole=\"button\"\n accessibilityLabel={message}\n >\n <Text numberOfLines={3} style={[styles.pillText, { color: accentText }]}>\n {message}\n </Text>\n </Pressable>\n </View>\n </Animated.View>\n );\n};\n\nconst styles = StyleSheet.create({\n // High elevation/zIndex so the whole overlay (incl. the frosted blur) sits\n // above the bottom tab bar on Android, where sibling z-order follows\n // elevation, not tree order.\n root: {\n zIndex: 9999,\n elevation: 9999,\n },\n // Fallback backdrop when `expo-blur` is absent. A structural dim (not a brand token), tuned to\n // read like the dark blur at BLUR_INTENSITY so the ring + tooltip keep the same contrast.\n scrim: {\n backgroundColor: \"rgba(0, 0, 0, 0.55)\",\n },\n ring: {\n position: \"absolute\",\n borderWidth: 2.5,\n backgroundColor: \"transparent\",\n shadowOffset: { width: 0, height: 0 },\n shadowOpacity: 0.9,\n shadowRadius: 12,\n elevation: 10,\n },\n tooltipWrapper: {\n position: \"absolute\",\n left: SIDE_MARGIN,\n right: SIDE_MARGIN,\n alignItems: \"center\",\n gap: 10,\n },\n gestureSlot: {\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n pill: {\n maxWidth: PILL_MAX_WIDTH,\n paddingVertical: 12,\n paddingHorizontal: 18,\n borderRadius: 18,\n shadowColor: \"#000\",\n shadowOffset: { width: 0, height: 2 },\n shadowOpacity: 0.25,\n shadowRadius: 6,\n elevation: 6,\n },\n pillText: {\n fontSize: 14,\n fontWeight: \"800\",\n textAlign: \"center\",\n },\n});\n\nexport const SpotlightOverlay = React.memo(SpotlightOverlayComponent);\nSpotlightOverlay.displayName = \"SpotlightOverlay\";\n\nexport default SpotlightOverlay;\n","import React from \"react\";\n\nimport { useCoachmarkOverlay } from \"./coachmarkOverlayStore\";\nimport { SpotlightOverlay } from \"./SpotlightOverlay\";\n\nexport interface CoachmarkOverlayHostProps {\n /** Ring/tooltip accent; defaults to the onboarding theme's `primary`. */\n accentColor?: string;\n /** Text/icon color on the accent surface; defaults to the theme's `onPrimary`. */\n accentTextColor?: string;\n}\n\n/**\n * Mounts once at the app root (rendered by CoachmarkProvider as a sibling of the\n * app tree) so the blur + spotlight paint OVER the bottom tab bar — which\n * react-navigation renders above screen components, out of reach of any\n * screen-level overlay. Renders nothing until a step is active.\n */\nconst CoachmarkOverlayHostComponent: React.FC<CoachmarkOverlayHostProps> = ({\n accentColor,\n accentTextColor,\n}) => {\n const active = useCoachmarkOverlay();\n\n if (!active) return null;\n\n return (\n <SpotlightOverlay\n message={active.message}\n targetRect={active.targetRect}\n gesture={active.gesture}\n placement={active.placement}\n onEngage={active.onEngage}\n onDismiss={active.onDismiss}\n accentColor={accentColor}\n accentTextColor={accentTextColor}\n />\n );\n};\n\nexport const CoachmarkOverlayHost = React.memo(CoachmarkOverlayHostComponent);\nCoachmarkOverlayHost.displayName = \"CoachmarkOverlayHost\";\n\nexport default CoachmarkOverlayHost;\n","import React, { useEffect } from \"react\";\n\nimport { useResolvedFeatures } from \"../features/WireFeaturesProvider\";\nimport type { WireFeatures, WireFeaturesConfig } from \"../features/types\";\nimport { CoachmarkOverlayHost } from \"./CoachmarkOverlayHost\";\nimport {\n getCoachmarkStorage,\n setCoachmarkStorage,\n setCoachmarksEnabled,\n setCoachmarkTesting,\n} from \"./runtime\";\nimport type { CoachmarkStorage } from \"./types\";\n\nexport interface CoachmarkProviderProps {\n /**\n * SYNCHRONOUS gate storage (MMKV-friendly). Reads must not be async or a ring\n * would flash before the \"already seen\" gate resolves. See CoachmarkStorage.\n */\n storage: CoachmarkStorage;\n /**\n * QA replay switch. When true, every seen-gate reads as unseen AND seen-writes\n * are suppressed, so every tour + showcase replays on each mount. Flip ONE\n * boolean to re-see the whole coachmark surface.\n */\n isTestingCoachmark?: boolean;\n /** Ring + tooltip color for every tour. Defaults to the onboarding theme's `primary`. */\n accentColor?: string;\n /**\n * Text/icon color on the accent surface (e.g. the tooltip's CTA label).\n * Defaults to the onboarding theme's `onPrimary`.\n */\n accentTextColor?: string;\n /**\n * OPTIONAL feature-flag wiring. When `flags.coachmarks.enabled` is false, every tour + overlay\n * request becomes a silent no-op (once-gates are NOT consumed, so re-enabling replays). Provide\n * pre-resolved `features`, OR a `featuresConfig` (serverUrl + apiKey) to lazily fetch once, OR\n * mount a `WireFeaturesProvider` above (context is read automatically). Omit all three and\n * coachmarks stay on (fail-open) — zero behavior change for hosts that never adopt flags.\n */\n features?: WireFeatures;\n /** Lazy-fetch config for the flags, used when `features` is absent and no provider is above. */\n featuresConfig?: WireFeaturesConfig;\n children: React.ReactNode;\n}\n\n/**\n * Mount ONCE at the app root — wrap it around (or just inside) your\n * NavigationContainer so the overlay host is a root-level sibling of the whole\n * app tree. That placement is what lets a ring + blur paint ABOVE the bottom tab\n * bar, which react-navigation renders over screen components.\n *\n * It feeds the sync storage + testing flag into the engine's module-level\n * singletons so `useCoachmarkTour` / `useCoachmarkAnchor` work from anywhere in\n * the tree without prop-drilling, then renders the overlay host as a sibling\n * after `children` (the SpotlightOverlay self-positions absolute-fill at\n * zIndex/elevation 9999).\n *\n * The singletons are set during render (not in an effect) so a child's mount\n * effect — which runs BEFORE this parent's effects — already sees the storage\n * when it reads its gate.\n */\nexport const CoachmarkProvider: React.FC<CoachmarkProviderProps> = ({\n storage,\n isTestingCoachmark = false,\n accentColor,\n accentTextColor,\n features,\n featuresConfig,\n children,\n}) => {\n // Resolve the coachmarks kill switch: explicit `features` → context → lazy fetch → all-on.\n const flags = useResolvedFeatures({ flags: features, config: featuresConfig });\n const coachmarksOn = flags.coachmarks.enabled;\n\n // Apply during render so gates + the kill switch are readable before any child effect fires.\n setCoachmarkStorage(storage);\n setCoachmarkTesting(isTestingCoachmark);\n setCoachmarksEnabled(coachmarksOn);\n\n useEffect(() => {\n setCoachmarkStorage(storage);\n setCoachmarkTesting(isTestingCoachmark);\n setCoachmarksEnabled(coachmarksOn);\n return () => {\n // Only clear if THIS provider's storage is still the live singleton — a\n // newer provider that mounted before this one unmounts must not be wiped.\n if (getCoachmarkStorage() === storage) {\n setCoachmarkStorage(null);\n }\n // Restore the fail-open default so a torn-down provider never leaves coachmarks dark.\n setCoachmarksEnabled(true);\n };\n }, [storage, isTestingCoachmark, coachmarksOn]);\n\n return (\n <>\n {children}\n <CoachmarkOverlayHost\n accentColor={accentColor}\n accentTextColor={accentTextColor}\n />\n </>\n );\n};\n\nCoachmarkProvider.displayName = \"CoachmarkProvider\";\n\nexport default CoachmarkProvider;\n","import type { TargetRect } from \"./types\";\n\n/**\n * Maps a coachmark anchor id → a function that measures that element's current\n * window rect. Elements register themselves on mount (via useCoachmarkAnchor)\n * and the tour controller resolves an id to a rect at the moment a step fires.\n *\n * This is the \"app declares WHERE\" half of the engine: the kit owns the\n * measuring/registry mechanics, each app decides which ids exist and pins them\n * to its own components.\n */\nexport type AnchorMeasurer = () => Promise<TargetRect | null>;\n\nconst anchors = new Map<string, AnchorMeasurer>();\n\n/**\n * NOTE: this registry is last-writer-wins — one measurer per id. An `anchorId`\n * MUST be unique across screens that can be mounted simultaneously; if two live\n * screens share an id, the second registration hides the first and unmount order\n * decides who survives. Scope ids per screen (e.g. `feed.filter_icon`) when a\n * component can appear in more than one mounted screen at once.\n */\nexport const coachmarkAnchors = {\n register(id: string, measurer: AnchorMeasurer) {\n anchors.set(id, measurer);\n },\n /**\n * Only clears the id when `measurer` is still the current registration, so a\n * screen unmounting after a newer screen registered the same id does not wipe\n * the live measurer. Omit `measurer` to force-delete regardless.\n */\n unregister(id: string, measurer?: AnchorMeasurer) {\n if (measurer !== undefined && anchors.get(id) !== measurer) return;\n anchors.delete(id);\n },\n get(id: string): AnchorMeasurer | undefined {\n return anchors.get(id);\n },\n /**\n * Resolve an anchor to a rect, retrying briefly while the target lays out\n * (e.g. the first feed post, or a screen just navigated to). Cancellable via\n * `shouldCancel` so a superseded step abandons its retry loop immediately.\n */\n async resolve(\n id: string,\n {\n retries = 6,\n intervalMs = 120,\n shouldCancel,\n }: {\n retries?: number;\n intervalMs?: number;\n /** Abort the retry loop early (e.g. the step was superseded). */\n shouldCancel?: () => boolean;\n } = {},\n ): Promise<TargetRect | null> {\n for (let attempt = 0; attempt <= retries; attempt++) {\n if (shouldCancel?.()) return null;\n const measurer = anchors.get(id);\n if (measurer) {\n const rect = await measurer();\n if (rect && rect.width > 0 && rect.height > 0) return rect;\n }\n if (attempt < retries) {\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n }\n return null;\n },\n};\n","import { useEffect, useRef } from \"react\";\nimport type { View } from \"react-native\";\n\nimport { coachmarkAnchors } from \"./coachmarkAnchorRegistry\";\nimport type { TargetRect } from \"./types\";\n\n/**\n * Makes any element ringable by a coachmark tour. Attach the returned ref to a\n * plain RN View wrapping the target (use `collapsable={false}` so the native\n * node survives for measurement):\n *\n * const filterAnchor = useCoachmarkAnchor(\"filter_icon\");\n * <View ref={filterAnchor} collapsable={false}>{button}</View>\n *\n * The app decides which ids exist and where they live; the kit measures them at\n * step time via `measureInWindow` (never continuously). Pass `null` to keep the\n * hook's position stable while registering nothing (e.g. a list item that is\n * only an anchor at one index).\n */\nexport const useCoachmarkAnchor = (id: string | null | undefined) => {\n const ref = useRef<View>(null);\n\n useEffect(() => {\n if (!id) return undefined;\n\n const measure = (): Promise<TargetRect | null> =>\n new Promise((resolve) => {\n const node = ref.current;\n if (!node || typeof node.measureInWindow !== \"function\") {\n return resolve(null);\n }\n node.measureInWindow((x, y, width, height) => {\n if (\n [x, y, width, height].some(\n (value) => value == null || Number.isNaN(value),\n )\n ) {\n return resolve(null);\n }\n resolve({ x, y, width, height });\n });\n });\n\n coachmarkAnchors.register(id, measure);\n return () => coachmarkAnchors.unregister(id, measure);\n }, [id]);\n\n return ref;\n};\n","import { useCallback, useEffect, useRef, useState, useSyncExternalStore } from \"react\";\n\nimport { coachmarkAnchors } from \"./coachmarkAnchorRegistry\";\nimport { coachmarkOverlay } from \"./coachmarkOverlayStore\";\nimport {\n areCoachmarksEnabled,\n coachmarkGateKey,\n hasSeenGate,\n markSeenGate,\n subscribeCoachmarksEnabled,\n} from \"./runtime\";\nimport type { CoachmarkStep } from \"./types\";\n\nexport interface UseCoachmarkTourOptions {\n /**\n * Gate key for the whole tour. The kit reads/writes\n * `wire_coachmark_<tourId>_seen` through the injected CoachmarkStorage so the\n * app never owns the \"seen\" bookkeeping (the global testing flag bypasses it).\n */\n tourId: string;\n /** Run at most once ever (persisted via the gate). Default true. */\n showOnce?: boolean;\n /**\n * Domain gate — the tour only arms while this is true (e.g. hasPosts), and it\n * also drives PAUSE/RESUME: if this flips false mid-tour (e.g. the user tab-\n * switches and the screen loses focus without unmounting) the overlay is\n * hidden but the tour's position is kept, and it resumes on the CURRENT step\n * (re-resolving its anchor) when this returns true. See the hook JSDoc.\n */\n enabled: boolean;\n /** Let passive value land before the first hint. */\n startDelayMs?: number;\n /** Fires once the tour finishes or is skipped (after the gate is written). */\n onComplete?: () => void;\n /**\n * Fires once when a step first becomes visible. It is NOT re-fired when the\n * SAME step resumes after a focus-loss pause (the last-shown step id is\n * tracked in a ref and suppressed), so a tab-switch never inflates\n * impressions. It fires again only when the tour advances to a new step.\n */\n onStepShown?: (id: string) => void;\n onStepEngaged?: (id: string) => void;\n onStepDismissed?: (id: string) => void;\n}\n\nconst DEFAULT_START_DELAY_MS = 3000;\n\n/**\n * Plays an ordered queue of coachmark steps on the current screen through the\n * root SpotlightOverlay (mounted by CoachmarkProvider). Engaging a step (tap the\n * ring/tooltip) advances and fires onStepEngaged. Tapping the backdrop advances\n * to the NEXT step and fires onStepDismissed — a stray tap or a \"not now\" never\n * kills the tour; only a backdrop tap on the LAST step ends it. Both terminal\n * paths (engaging past the end, or dismissing the last step) write the seen gate\n * once and call onComplete, so a finished tour never nags again.\n *\n * Gating lives IN the kit: the tour arms only when `enabled` AND (not `showOnce`\n * OR the `tourId` gate is unseen).\n *\n * PAUSE/RESUME on focus loss: `enabled` is a live gate, not just an arm-once\n * trigger. Once armed, if `enabled` goes false while the tour is in flight\n * (started, not finished) — the classic case being a tab-switch that keeps the\n * screen mounted — the drive effect hides the overlay so a stale rect can't\n * float over the wrong screen, but KEEPS `activeIndex` and does NOT write the\n * seen gate. When `enabled` returns true the effect re-runs (it's in the deps)\n * and re-drives the SAME step, re-resolving its anchor so a moved/relaid-out\n * target is picked up. `onStepShown` is suppressed on that resume (last-shown\n * step id is tracked in a ref) so a pause/resume never double-counts a step.\n *\n * KILL SWITCH vs PAUSE — two different gates, two different endings. `enabled` is the host's\n * domain gate and PAUSES (position kept, gate unwritten, resumes on the same step). The tenant's\n * coachmarks feature flag (`setCoachmarksEnabled`, from GET /v1/features) is TERMINAL: flipped off\n * mid-tour it ends the tour and fires `onComplete`, but does NOT write the once-gate, so the tour\n * replays on the next mount once the flag is back on. It is read through a subscription rather\n * than sampled, because the flip has to reach a tour that is already in flight: the overlay's\n * `show()` is a no-op while the flag is off, so a tour that carried on would paint nothing, could\n * not be tapped to advance, and would never reach a terminal state.\n *\n * IMPORTANT: `steps` MUST be a stable (memoized) array. If a new array identity\n * is passed on every render the drive effect re-runs and re-shows the current\n * step (wasteful anchor re-resolves / overlay churn), and analytics can\n * double-fire. Memoize it, or pass an inline module-level constant.\n *\n * Preserved engine invariants: step callbacks live in a ref (not effect deps),\n * anchor resolution is cancellable, and finish is idempotent (only one overlay\n * is ever active, the gate is written once).\n */\nexport const useCoachmarkTour = (\n /** Ordered coachmark steps. MUST be stable/memoized — see the note above. */\n steps: CoachmarkStep[],\n {\n tourId,\n showOnce = true,\n enabled,\n startDelayMs = DEFAULT_START_DELAY_MS,\n onComplete,\n onStepShown,\n onStepEngaged,\n onStepDismissed,\n }: UseCoachmarkTourOptions,\n) => {\n const [activeIndex, setActiveIndex] = useState<number | null>(null);\n const startedRef = useRef(false);\n const finishedRef = useRef(false);\n // Id of the step onStepShown last fired for. Lets us re-drive the current\n // step on a focus-loss RESUME without re-firing the impression callback.\n const lastShownStepIdRef = useRef<string | null>(null);\n\n // Keep the latest step callbacks in a ref so parent-recreated inline callbacks\n // don't re-trigger the drive effect (which would re-show the step and\n // double-fire analytics). The drive effect keys only on the step, not these.\n const callbacksRef = useRef({ onStepShown, onStepEngaged, onStepDismissed });\n callbacksRef.current = { onStepShown, onStepEngaged, onStepDismissed };\n\n // The tenant's coachmarks kill switch, SUBSCRIBED rather than sampled so a mid-tour flip reaches\n // a tour already in flight. See the KILL SWITCH vs PAUSE note above.\n const coachmarksOn = useSyncExternalStore(\n subscribeCoachmarksEnabled,\n areCoachmarksEnabled,\n areCoachmarksEnabled,\n );\n\n /**\n * The single terminal exit. `writeGate` is what separates the two ways a tour can end:\n * • the user reached the end (or dismissed the last step) → the once-gate IS written, so a\n * finished tour never nags again;\n * • the kill switch went off mid-tour → the gate is NOT written. That gate belongs to a tour\n * the user actually saw, and the module's whole kill-switch contract is that disabling\n * never consumes it, so re-enabling replays the tour.\n * Either way `onComplete` fires: a host that gates its own UI on the tour finishing must not be\n * left waiting on a callback that can no longer arrive.\n */\n const exit = useCallback(\n (writeGate: boolean) => {\n if (finishedRef.current) return;\n finishedRef.current = true;\n if (writeGate && showOnce) markSeenGate(coachmarkGateKey(tourId));\n coachmarkOverlay.hide();\n setActiveIndex(null);\n onComplete?.();\n },\n [onComplete, showOnce, tourId],\n );\n\n const finish = useCallback(() => exit(true), [exit]);\n\n // Arm once, after the delay, when enabled and the gate is unseen.\n useEffect(() => {\n if (!enabled || startedRef.current) return undefined;\n // Feature kill switch: never arm while coachmarks are disabled, so no timer starts, no\n // overlay shows, and the once-gate is NOT consumed — re-enabling replays the tour. Reading\n // the SUBSCRIBED value (and listing it in the deps) is what makes that last clause true\n // without a remount: flipping it off clears a pending arm timer, flipping it back on re-arms.\n if (!coachmarksOn) return undefined;\n if (showOnce && hasSeenGate(coachmarkGateKey(tourId))) return undefined;\n const timer = setTimeout(() => {\n startedRef.current = true;\n setActiveIndex(0);\n }, startDelayMs);\n return () => clearTimeout(timer);\n }, [enabled, coachmarksOn, startDelayMs, showOnce, tourId]);\n\n // Drive the active step. Keyed on `enabled` too, so a mid-tour focus loss\n // pauses (hide, keep position) and a return to focus resumes the same step.\n useEffect(() => {\n if (activeIndex === null) return undefined;\n\n // KILL SWITCH, mid-tour: exit terminally, WITHOUT writing the once-gate, so the tour replays\n // when it is switched back on. Checked BEFORE the pause branch below — a disable is terminal,\n // a focus loss is not.\n if (!coachmarksOn) {\n exit(false);\n return undefined;\n }\n\n // PAUSE: armed but the screen lost focus (enabled flipped false while in\n // flight). Hide the overlay so a stale rect can't float over the wrong\n // screen, but KEEP activeIndex and DON'T write the gate. When enabled\n // returns true this effect re-runs and re-drives the current step below.\n if (!enabled) {\n if (startedRef.current && !finishedRef.current) coachmarkOverlay.hide();\n return undefined;\n }\n\n if (activeIndex >= steps.length) {\n finish();\n return undefined;\n }\n\n const step = steps[activeIndex];\n if (!step) {\n finish();\n return undefined;\n }\n let cancelled = false;\n\n (async () => {\n // Re-resolve the anchor every drive (incl. resume) — rects may have moved\n // while the screen was backgrounded / relaid out.\n const rect = step.anchorId\n ? await coachmarkAnchors.resolve(step.anchorId, {\n shouldCancel: () => cancelled,\n })\n : null;\n if (cancelled) return;\n\n // Fire onStepShown only when the shown step actually changes — a resume\n // of the SAME step (post focus-loss) must not double-count the impression.\n if (lastShownStepIdRef.current !== step.id) {\n lastShownStepIdRef.current = step.id;\n callbacksRef.current.onStepShown?.(step.id);\n }\n coachmarkOverlay.show({\n message: step.message,\n targetRect: rect,\n gesture: step.gesture ?? \"none\",\n placement: step.placement ?? \"bottom\",\n onEngage: () => {\n callbacksRef.current.onStepEngaged?.(step.id);\n step.onEngage?.();\n setActiveIndex((index) => (index ?? 0) + 1);\n },\n onDismiss: () => {\n callbacksRef.current.onStepDismissed?.(step.id);\n // Backdrop tap advances to the next step; only the LAST step's\n // backdrop tap ends the whole tour (the gate is written once, there).\n if (activeIndex >= steps.length - 1) {\n finish();\n } else {\n setActiveIndex((index) => (index ?? 0) + 1);\n }\n },\n });\n })();\n\n return () => {\n cancelled = true;\n };\n }, [activeIndex, steps, finish, exit, enabled, coachmarksOn]);\n\n // Safety: clear the overlay if the screen unmounts mid-tour.\n useEffect(\n () => () => {\n if (!finishedRef.current) coachmarkOverlay.hide();\n },\n [],\n );\n};\n","/**\n * selectTourSteps — the Phase-3 (AI intent-mapping) seam, stubbed today.\n *\n * The app declares a full catalog of coachmarks (its \"feature map\"). Near-term,\n * the whole catalog plays in its declared order. LATER, the Wire server will\n * emit an ordered `coachmarks: string[]` id list chosen by the user's captured\n * intent (see the package spec §1e / §5), and the app passes it straight here as\n * `selection`. This function is the ONE place that turns a selection into the\n * live ordered step list — so turning AI on is a drop-in with zero app changes:\n *\n * // Phase 1-2 (no AI): full catalog, declared order\n * const steps = selectTourSteps(catalog);\n *\n * // Phase 3 (AI on): server-chosen subset, server order\n * const steps = selectTourSteps(catalog, plan.coachmarks);\n *\n * Contract:\n * - `selection` absent → returns the catalog unchanged (identity/declared order).\n * - `selection` present → returns only catalog entries whose `id` appears in\n * `selection`, ordered by `selection` (unknown ids are skipped; duplicates in\n * `selection` are ignored after the first match).\n *\n * NOTE: routing steps through a catalog + this selector is NOT required today.\n * Declaring an inline, static (module-level or memoized) steps array and passing\n * it straight to `useCoachmarkTour` is a perfectly fine consumer pattern. The\n * catalog + selection route exists to make the app AI-selection-ready — flip to\n * server-chosen ordering later with zero app changes — not as the baseline.\n */\nexport const selectTourSteps = <T extends { id: string }>(\n catalog: T[],\n selection?: string[],\n): T[] => {\n if (!selection) return catalog;\n\n const byId = new Map(catalog.map((item) => [item.id, item]));\n const seen = new Set<string>();\n const ordered: T[] = [];\n for (const id of selection) {\n if (seen.has(id)) continue;\n seen.add(id);\n const item = byId.get(id);\n if (item) ordered.push(item);\n }\n return ordered;\n};\n"]}
|