关于 openclix-init
openclix-init 是一项用于将 OpenClix 集成到现有移动应用的技能,通过复制并适配模板代码,而非安装 SDK。它根据项目文件识别平台,并要求先确认是否迁移兼容的本地通知流程。
主要功能
- 01依据项目文件识别平台
- 02复制平台模板到专用目录
- 03检测并分类现有本地通知
- 04适配存储与通知调度器
- 05集成后运行构建验证
适用场景
- 01在现有移动项目中接入 OpenClix
- 02评估能否将本地通知迁入 OpenClix
- 03按项目已有依赖选择适配器
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ openclix/ openclix --skill openclix-init安装后在 Claude Code 中输入/openclix-init确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
package.json__tests__/campaign-processor.test.tscampaign-state.test.tsconfig-validator.test.tscross-platform-parity.test.tsevent-condition.test.tsschedule-calculator.test.tstemplate-rendering.test.tstrigger-service.test.ts__tests__/helpers/fixtures.tsmocks.tsreferences/openclix.schema.jsontemplates/android/core/OpenClix.ktOpenClixCampaignManager.kttemplates/android/engine/CampaignProcessor.ktEventConditionProcessor.ktScheduleCalculator.ktTriggerService.kttemplates/android/models/OpenClixTypes.kttemplates/android/notification/LocalNotificationScheduler.ktNotificationPermission.kttemplates/android/services/ConfigLoader.ktConfigValidator.ktUtils.kttemplates/android/store/FileCampaignStateRepository.kttemplates/flutter/core/openclix_campaign_manager.dartopenclix.darttemplates/flutter/engine/campaign_processor.dartcampaign_state_service.dartevent_condition_processor.dart详细介绍
OpenClix 初始化
用途
此技能通过将客户端代码复制到用户项目中来添加 OpenClix 功能,而不是通过安装 SDK 包。
采用本地源码集成模式(shadcn 风格):复制、调整、接入、验证。
核心规则
- 首先根据项目文件检测真实平台。
- 尽量少修改现有用户代码。
- 将所有 OpenClix 文件保存在专用命名空间/目录中。
- 在
.openclix/**下创建本地规划/报告文件时,确保.gitignore中列出了.openclix/(如果缺少则添加)。 - 尽可能复用现有依赖。
- 未经用户明确批准,不要添加或更新依赖。
- 集成后运行构建,并且只修复由集成导致的问题。
- 不要在生产集成路径中使用内存回退。
- 对于捆绑的 JSON 配置交付,运行时加载器路径和复制的文件路径必须完全一致(相同目录和区分大小写的文件名)。
- 默认文件名使用
openclix-config.json;不要自行创建大小写变体,例如OpenClix-config.json。
平台检测
按以下顺序使用文件证据:
| 优先级 | 平台 | 必需证据 |
|---|---|---|
| 1 | Expo | 包含 expo 的 app.json 或 app.config.* |
| 2 | React Native | 包含 react-native 的 package.json,以及典型的 ios/ + android/ 结构 |
| 3 | Flutter | 使用 Flutter SDK 的 pubspec.yaml |
| 4 | iOS 原生 | *.xcodeproj、*.xcworkspace 或 Package.swift |
| 5 | Android 原生 | build.gradle 或 build.gradle.kts |
如果信号冲突,以具体文件证据为准,并报告不一致之处。
模板选择
- Expo / React Native:
templates/react-native/ - Flutter:
templates/flutter/ - iOS:
templates/ios/ - Android:
templates/android/(包命名空间ai.openclix.*)
当平台移植版本需要保持一致时,以 templates/react-native/ 为规范参考。
现有本地通知检测
复制模板或接入 OpenClix 触点之前,检查宿主应用中 OpenClix 命名空间以外是否已有本地通知代码。
如果以下路径存在,检测必须涵盖这些路径:
- 通知调度
- 通知权限请求/状态
- 前台显示处理
- 通知点击/打开处理
对于检测到的每条路径,将其分类为:
migration-capable:可以通过局部修改将其重定向到 OpenClix,无需新增依赖,也无需大范围重构keep-as-is:在集成 OpenClix 时应保持不变
如果没有发现现有本地通知代码,则继续执行常规集成流程。
如果发现了现有本地通知代码,则报告:
- 检测到的文件或入口点
- 每条路径属于
migration-capable还是keep-as-is - 任何路径不具备迁移条件的原因
迁移能力规则
谨慎使用以下规则:
- React Native / Expo:
- 仅当应用已使用
@notifee/react-native或expo-notifications时,才标记为migration-capable - 针对这些库检测并分类现有的调度、权限、前台和打开处理代码
- 其他通知技术栈保持为
keep-as-is
- 仅当应用已使用
- Flutter:
- 仅当现有插件能够提供当前 OpenClix 回调契约(包括
schedule、cancel、listPending、权限请求/状态,以及可选的前台设置)时,才标记为migration-capable - 如果插件无法在不添加依赖或进行大范围重写的情况下满足该契约,则标记为
keep-as-is
- 仅当现有插件能够提供当前 OpenClix 回调契约(包括
- iOS 原生:
- 当应用已使用
UNUserNotificationCenter本地通知,且现有权限/代理路径能够通过局部修改复用时,标记为migration-capable - 保留 OpenClix 内容模型不支持的通知行为
- 当应用已使用
- Android 原生:
- 当当前本地通知流程属于平台本地调度/显示,且能够在不添加依赖或进行大范围重构的情况下,重定向至 OpenClix 调度路径时,标记为
migration-capable - 由供应商管理或经过大量自定义的流程保持为
keep-as-is
- 当当前本地通知流程属于平台本地调度/显示,且能够在不添加依赖或进行大范围重构的情况下,重定向至 OpenClix 调度路径时,标记为
除非用户要求单独重新设计,否则以下场景一律标记为 keep-as-is:
- 远程推送投递基础设施
- 当前 OpenClix 适配器不支持的供应商专属通知产品
- 当前 OpenClix 内容模型未涵盖的丰富操作或高级功能
- 与不相关业务逻辑紧密耦合的通知流程
迁移决策
如果检测到一个或多个 migration-capable 路径,请在重写现有通知行为前询问用户。
使用以下决策措辞:
我发现了 OpenClix 之外的现有本地通知。其中一些路径具备迁移能力。您希望我将受支持的本地通知流程迁移到 OpenClix,还是保持现有实现不变?如果您没有选择,我会保持现有实现不变。
决策规则:
- 如果用户没有明确选择,则默认将具备迁移能力的路径设为
keep-as-is - 如果用户选择
keep,则将具备迁移能力的路径视为keep-as-is,在现有通知系统旁集成 OpenClix,且不要重写现有通知流程 - 如果用户选择
migrate,则仅迁移符合当前 OpenClix 模型的受支持互动式本地通知流程 - 即使用户选择
migrate,也不要改动不受支持或不相关的通知流程 - 如果没有检测到具备迁移能力的路径,请说明这一点,并仅进行共存集成
- 绝不要在不告知用户的情况下替换现有通知实现
- 在集成交接/报告中注明用户的最终选择
集成工作流
- 确定平台以及当前的启动/事件/生命周期入口点。
- 检测已有的本地通知路径,并将其分类为
migration-capable或keep-as-is。 - 如果存在具备迁移能力的路径,请询问用户是迁移受支持的流程,还是保持现有实现不变。默认保持现有实现不变。
- 将所选模板复制到用户项目中专门用于 OpenClix 的区域。
- 仅接入必需的触点:
- 应用启动时初始化
- 事件跟踪调用路径
- 前台/应用生命周期触发器
- 保持现有架构和代码风格不变;避免大范围重构。
- 如果涉及配置/架构变更,请依据
references/openclix.schema.json进行验证。
适配器选择规则
仅使用现有依赖来选择适配器:
- 在集成时选择具体的适配器;避免在运行时自动检测依赖。
- 如果项目已包含受支持的持久化存储依赖,请接入对应实现。
- 如果已有通知库,请接入匹配的调度器适配器。
- 如果不存在兼容的依赖,则快速失败并提供清晰的集成错误信息。
- 不要将降级的内存路径作为生产模板的默认配置。
React Native / Expo 存储选择:
- 使用 AsyncStorage 的项目:使用
AsyncStorageCampaignStateRepository。 - 使用 MMKV 的项目:使用
MmkvCampaignStateRepository。 - 如果两者都存在,优先使用项目标准,并且只将一个存储适配器复制到应用中。
- 调用
OpenClix.initialize(...)时,显式注入campaignStateRepository。
React Native / Expo 调度器选择:
- Notifee 项目:创建
new NotifeeScheduler(notifee)。 - Expo notifications 项目:创建
new ExpoNotificationScheduler(ExpoNotifications)。 - 调用
OpenClix.initialize(...)时,显式注入messageScheduler。
平台要求:
- React Native / Expo:
- 不要在
OpenClix核心中对存储和调度器适配器进行运行时自动检测;应在集成时选择这些适配器。 - 在集成期间选择存储和调度器实现,并显式注入其依赖;如果无需项目专用实现,模板核心可以根据运行时环境选择生命周期辅助工具(例如
lifecycleStateReader)。 - 如果没有兼容的实现,初始化必须失败并提供清晰的说明。
- 不要在
- Flutter:
- 对现有通知插件使用基于回调的调度器适配器
- 初始化时必须显式提供调度器和状态仓库依赖
- iOS / Android 原生:
- 默认使用平台原生实现
- 不要将内存或无操作回退方案设为默认运行时行为
通知权限与前台设置
必须先请求通知权限,才能触发营销活动。每个平台模板都包含权限工具;集成 Agent 必须在宿主应用的适当位置接入该工具。
React Native / Expo — 权限
- **Notifee 项目:**从
infrastructure/NotifeeNotificationSetup导入requestNotifeePermission。在应用启动时调用(例如,在App.tsx或启动钩子中),并传入 Notifee 适配器。无需前台处理程序 — Notifee 通过presentationOptions原生处理前台显示。 - **Expo 项目:**从
infrastructure/ExpoNotificationSetup导入requestExpoPermission和setupExpoForegroundHandler。在初始化期间调用一次setupExpoForegroundHandler,然后在应用启动时调用requestExpoPermission。
iOS — 权限与前台显示
- **权限:**在应用启动时调用
await NotificationPermission.request()(例如,在application(_:didFinishLaunchingWithOptions:)中,或使用 SwiftUI 的.task修饰符)。此操作会调用UNUserNotificationCenter.requestAuthorization。 - **前台显示:**应用处于活动状态时,iOS 会隐藏通知横幅。模板提供了静态方法
ForegroundNotificationHandler.handleWillPresent(notification:completionHandler:)。- **重要:**每个应用只能有一个
UNUserNotificationCenterDelegate。不要将ForegroundNotificationHandler设为代理。相反,应将应用现有的代理(通常是AppDelegate)设为UNUserNotificationCenter.current().delegate = self,并在代理的willPresent实现中调用该静态方法。
- **重要:**每个应用只能有一个
Android — 权限
- Manifest: 在
AndroidManifest.xml中添加<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />。 - 运行时请求: 在 API 33+(Android 13)上,于启动时调用
NotificationPermission.shouldRequestPermission(context)。如果返回true,请使用 Activity 的requestPermissions()或ActivityResultLauncher请求NotificationPermission.getPermissionString()。 - Android 无需设置前台显示——无论应用处于什么状态,
NotificationManager.notify()都会显示通知。
Flutter — 权限和前台显示
notification/notification_permission.dart 中的 NotificationPermission 类接受回调。接入宿主应用的通知插件:
- 提供
requestPermission回调,用于调用插件的权限请求 API。 - 提供
checkPermissionStatus回调,用于检查当前状态。 - 可选地提供
setupForegroundHandler回调,用于配置前台显示(iOS 必需,Android 无需配置)。 - 在应用启动时调用
permission.request(),确保在触发营销活动前完成请求。 - 如果提供了处理程序,请在初始化期间调用
permission.setupForeground()。
目录和命名空间策略
OpenClix 文件必须集中放在专用目录中:
- React Native / Expo:
src/openclix/ - Flutter:
lib/openclix/ - iOS:
OpenClix/或Sources/OpenClix/ - Android:
app/src/main/kotlin/ai/openclix/,使用ai.openclix.*包
随附配置路径约定
如果集成包含随附配置交付(非 HTTP 端点),请遵循以下约定:
- 首先从当前启动代码中确认确切的运行时加载路径。
- 将
openclix-config.json复制到该确切路径。 - 如果尚不存在运行时加载路径,请使用以下默认路径:
- React Native / Expo:
assets/openclix/openclix-config.json - Flutter:
assets/openclix/openclix-config.json,并将其添加到pubspec.yaml - iOS:
<app-target>/OpenClix/openclix-config.json,并将其加入“Copy Bundle Resources” - Android:
app/src/main/assets/openclix/openclix-config.json
- React Native / Expo:
- 确保任何随附路径标识符(
OpenClixConfig.endpoint、资源键、包内文件名)都与复制后的文件路径完全一致。 - 交付前进行最终路径一致性检查,并报告:
- 源配置文件路径
- 随附的运行时文件路径
- 运行时加载器引用位置
依赖策略
更改依赖项前:
- 检查所选模板的要求。
- 检查用户项目中已有的依赖项。
- 优先使用项目已有的库或平台 API。
- 如果可以替换,应调整模板代码,而不是添加依赖项。
- 如果没有安全的替代方案,请先征求批准,再添加或更新依赖项。
未经批准,切勿运行包管理器的安装或更新命令。
构建验证
接入后,根据检测到的项目结构运行适用于平台的构建或分析命令。 优先使用项目原生命令(现有脚本、Gradle 任务、Xcode 方案、Flutter 工作流)。
如果不确定,请使用常见的备用命令:
- React Native / Expo:
npx tsc --noEmit - Android:
./gradlew assembleDebug - iOS:
xcodebuild -scheme <scheme> build或swift build - Flutter:
flutter analyze
如果构建失败,请进行最小化的针对性修复并重试。只有遇到无法解决的阻碍时才停止。
更新 Agent 指令文件
集成完成后,在项目的 Agent 指令文件中追加一个 OpenClix 部分,为后续会话提供上下文。
确定要更新的文件:
- 如果存在
CLAUDE.md:更新CLAUDE.md(Claude Code) - 如果存在
AGENTS.md:更新AGENTS.md(Codex 或其他 Agent) - 如果两者都存在:更新与当前 Agent 对应的文件
- 如果两者都不存在:按照当前 Agent 的约定创建文件
追加以下部分(不要覆盖现有内容):
## 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.
完成检查清单
- OpenClix 代码已添加到专用命名空间/目录下。
- 对现有应用代码的更改尽可能少,且范围明确。
- 集成前已检测并分类现有的本地通知路径。
- 发现受支持的路径时,已记录迁移决定;用户未选择迁移时,默认保留现有行为。
- 交接/报告说明了检测到的内容、支持迁移的内容、未改动的内容以及所做的更改。
- 未添加或升级未经批准的依赖项。
- 适配器接线优先使用现有依赖项,并在依赖项不可用时快速失败。
- 使用本地资源交付时,已验证打包配置的路径/文件名一致性。
- 已执行构建验证。
- 已明确报告任何遗留阻碍。