npx claudepluginhub openclix/openclix --plugin openclixThis skill uses the workspace's default tool permissions.
This skill adds OpenClix functionality by copying client code into the user project, not by installing an SDK package.
__tests__/campaign-processor.test.ts__tests__/campaign-state.test.ts__tests__/config-validator.test.ts__tests__/cross-platform-parity.test.ts__tests__/event-condition.test.ts__tests__/helpers/fixtures.ts__tests__/helpers/mocks.ts__tests__/schedule-calculator.test.ts__tests__/template-rendering.test.ts__tests__/trigger-service.test.tspackage.jsonreferences/openclix.schema.jsontemplates/android/core/OpenClix.kttemplates/android/core/OpenClixCampaignManager.kttemplates/android/engine/CampaignProcessor.kttemplates/android/engine/EventConditionProcessor.kttemplates/android/engine/ScheduleCalculator.kttemplates/android/engine/TriggerService.kttemplates/android/models/OpenClixTypes.kttemplates/android/notification/LocalNotificationScheduler.ktDesigns OpenClix campaign configurations from product goals and app events, producing schema-valid openclix-config.json, app profiles, and runtime integration setup for notifications and retention flows.
Advises on mobile lifecycle management, permissions, deep linking, push notifications, and app store compliance for iOS, Android, React Native, Flutter, and Expo with platform-specific best practices.
Guides cross-platform mobile app development for iOS/Android using React Native (Expo/CLI) and Flutter. Covers framework selection by tier/use case, Expo project setup, folder structure, and navigation patterns.
Share bugs, ideas, or general feedback.
This skill adds OpenClix functionality by copying client code into the user project, not by installing an SDK package.
Use a local-source integration model (shadcn-style): copy, adapt, wire, verify.
.openclix/**, ensure .openclix/ is listed in .gitignore (add it if missing).openclix-config.json as the default filename; do not invent case variants such as OpenClix-config.json.Use file evidence in this order:
| Priority | Platform | Required Evidence |
|---|---|---|
| 1 | Expo | app.json or app.config.* with expo |
| 2 | React Native | package.json with react-native and typical ios/ + android/ structure |
| 3 | Flutter | pubspec.yaml with Flutter SDK |
| 4 | iOS native | *.xcodeproj or *.xcworkspace or Package.swift |
| 5 | Android native | build.gradle or build.gradle.kts |
If signals conflict, trust concrete file evidence and report the mismatch.
templates/react-native/templates/flutter/templates/ios/templates/android/ (package namespace ai.openclix.*)templates/react-native/ is the canonical reference when platform ports need alignment.
Before copying templates or wiring OpenClix touchpoints, inspect the host app for pre-existing local notification code outside the OpenClix namespace.
Detection must cover these paths when they exist:
For each detected path, classify it as either:
migration-capable: can be redirected into OpenClix with localized edits, no new dependencies, and no broad refactorkeep-as-is: should remain untouched during OpenClix integrationIf no existing local notification code is found, continue with the normal integration flow.
If existing local notification code is found, report:
migration-capable or keep-as-isUse these rules conservatively:
migration-capable only when the app already uses @notifee/react-native or expo-notificationskeep-as-ismigration-capable only when the existing plugin can provide the current OpenClix callback contract for schedule, cancel, listPending, permission request/status, and optional foreground setupkeep-as-ismigration-capable when the app already uses UNUserNotificationCenter local notifications and the existing permission/delegate path can be reused with localized editsmigration-capable when the current local notification flow is platform-local scheduling/display that can be redirected into the OpenClix scheduler path without adding dependencies or broad refactorskeep-as-isAlways mark these scenarios as keep-as-is unless the user asks for a separate redesign:
If one or more detected paths are migration-capable, ask the user before rewriting existing notification behavior.
Use this decision wording:
I found existing local notifications outside OpenClix. Some paths are migration-capable. Do you want me to migrate the supported local-notification flows into OpenClix, or keep the existing implementation unchanged? If you do not choose, I will keep the existing implementation.
Decision rules:
keep-as-is if the user does not explicitly choosekeep, treat migration-capable paths as keep-as-is, integrate OpenClix alongside the current notification system, and do not rewrite existing notification flowsmigrate, migrate only supported engagement-style local notification flows that fit the current OpenClix modelmigratemigration-capable or keep-as-is.references/openclix.schema.json when config/schema changes are involved.Select adapters using existing dependencies only:
React Native / Expo storage selection:
AsyncStorageCampaignStateRepository.MmkvCampaignStateRepository.campaignStateRepository explicitly when calling OpenClix.initialize(...).React Native / Expo scheduler selection:
new NotifeeScheduler(notifee).new ExpoNotificationScheduler(ExpoNotifications).messageScheduler explicitly when calling OpenClix.initialize(...).Platform expectations:
OpenClix core for storage and scheduler adapters; select these at integration time.lifecycleStateReader) may be chosen by the template core based on the runtime environment when no project-specific implementation is required.Notification permission must be requested before campaign triggers fire. Each platform template includes a permission utility; the integration agent must wire it at the appropriate location in the host app.
requestNotifeePermission from infrastructure/NotifeeNotificationSetup. Call it at app startup (e.g. in App.tsx or a startup hook) passing the Notifee adapter. No foreground handler is needed — Notifee handles foreground display natively via presentationOptions.requestExpoPermission and setupExpoForegroundHandler from infrastructure/ExpoNotificationSetup. Call setupExpoForegroundHandler once during initialization, then call requestExpoPermission at app startup.await NotificationPermission.request() at app startup (e.g. in application(_:didFinishLaunchingWithOptions:) or a SwiftUI .task modifier). This calls UNUserNotificationCenter.requestAuthorization.ForegroundNotificationHandler.handleWillPresent(notification:completionHandler:) as a static method.
UNUserNotificationCenterDelegate per app. Do NOT assign ForegroundNotificationHandler as the delegate. Instead, set the app's existing delegate (usually AppDelegate) as UNUserNotificationCenter.current().delegate = self, and call the static method from the delegate's willPresent implementation.<uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> to AndroidManifest.xml.NotificationPermission.shouldRequestPermission(context) at startup. If it returns true, use the Activity's requestPermissions() or ActivityResultLauncher to request NotificationPermission.getPermissionString().NotificationManager.notify() always displays regardless of app state.The NotificationPermission class in notification/notification_permission.dart accepts callbacks. Wire the host app's notification plugin:
requestPermission callback that calls the plugin's permission request API.checkPermissionStatus callback that checks current status.setupForegroundHandler callback to configure foreground display (required for iOS, not needed for Android).permission.request() at app startup before campaign triggers fire.permission.setupForeground() during initialization if the handler is provided.OpenClix files must stay grouped in a dedicated location:
src/openclix/lib/openclix/OpenClix/ or Sources/OpenClix/app/src/main/kotlin/ai/openclix/ with ai.openclix.* packagesWhen integration includes bundled config delivery (non-HTTP endpoint), enforce this contract:
openclix-config.json to that exact path.assets/openclix/openclix-config.jsonassets/openclix/openclix-config.json and add it to pubspec.yaml<app-target>/OpenClix/openclix-config.json and include in "Copy Bundle Resources"app/src/main/assets/openclix/openclix-config.jsonOpenClixConfig.endpoint, asset key, bundle filename) matches the copied file path exactly.Before changing dependencies:
Never run package-manager install/update commands without approval.
After wiring, run platform-appropriate build/analysis commands based on detected project structure. Prefer project-native commands first (existing scripts, Gradle tasks, Xcode scheme, Flutter workflow).
If unclear, use common fallback commands:
npx tsc --noEmit./gradlew assembleDebugxcodebuild -scheme <scheme> build or swift buildflutter analyzeIf build fails, apply minimal targeted fixes and retry. Stop only on hard blockers.
After integration, append an OpenClix section to the project's agent instruction file so future sessions have context.
Detect which file to update:
CLAUDE.md exists: update CLAUDE.md (Claude Code)AGENTS.md exists: update AGENTS.md (Codex or other agents)Append this section (do not overwrite existing content):
## OpenClix
OpenClix is integrated in this project. It provides local-first, config-driven mobile engagement logic.
Available skills:
- `openclix-design-campaigns`: Create and iterate campaign configurations from product goals.
- `openclix-analytics`: Wire events to a PA provider and produce retention impact reports.
- `openclix-update-campaigns`: Propose campaign operations from measured analytics performance.
- `openclix-update`: Sync integration source code with the latest template baseline.