@clix-so/clix-agent-skills 0.1.1

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.
@@ -0,0 +1,426 @@
1
+ ---
2
+ name: clix-integration
3
+ description:
4
+ Integrates Clix Mobile SDK into iOS, Android, Flutter, and React Native
5
+ projects. Provides step-by-step guidance for installation, initialization, and
6
+ verification. Use when the user asks to install, setup, or configure Clix
7
+ analytics.
8
+ version: 0.1.0
9
+ ---
10
+
11
+ # Clix SDK Integration Skill
12
+
13
+ This skill provides comprehensive guidance for integrating Clix analytics SDK
14
+ into mobile applications. Follow the workflow below to ensure proper
15
+ installation and configuration.
16
+
17
+ ## Integration Strategy (MCP First)
18
+
19
+ This skill follows an **"MCP First"** strategy to ensure agents always use the
20
+ latest verified SDK source code.
21
+
22
+ **Step 1: Check for MCP Capability**
23
+
24
+ - Check if the Clix MCP Server tools (`clix-mcp-server:search_sdk`,
25
+ `clix-mcp-server:search_docs`) are available in your toolset.
26
+
27
+ **Step 2: Primary Path (MCP Available)**
28
+
29
+ - **MUST** use `clix-mcp-server:search_sdk` to fetch exact initialization code
30
+ for the target platform (e.g.,
31
+ `clix-mcp-server:search_sdk(query="initialize", platform="android")`).
32
+ - Use these fetched results as the **Single Source of Truth** for
33
+ implementation.
34
+ - Do **NOT** rely on static examples if MCP returns valid results.
35
+
36
+ **Step 3: Fallback Path (MCP Unavailable)**
37
+
38
+ - If checks for `clix-mcp-server` fail:
39
+ 1. **Ask the user**: "The Clix MCP Server is not detected. It provides the
40
+ latest official SDK code. Would you like me to install it now?"
41
+ 2. **If User says YES**:
42
+ - Run: `bash scripts/install-mcp.sh`
43
+ - The script will:
44
+ - Verify the package is available
45
+ - Auto-detect the MCP client (Codex, Cursor, Claude Desktop, VS Code, etc.)
46
+ - Automatically configure the MCP server in the appropriate config file
47
+ - Provide clear instructions for restart
48
+ - Instruct user to restart their agent/IDE to load the new server.
49
+ - Stop here (let user restart).
50
+ 3. **If User says NO**:
51
+ - Fall back to using the static patterns in
52
+ `references/framework-patterns.md` and `examples/`.
53
+ - Inform the user: "Proceeding with static fallback examples (may be
54
+ outdated)."
55
+
56
+ ## Interaction Guidelines for Agents
57
+
58
+ When using this skill (for example inside Claude Code, Codex, Cursor, or other
59
+ AI IDEs), follow these behaviors:
60
+
61
+ - **Start with reconnaissance**
62
+ - Inspect the project structure first (list key files like `package.json`,
63
+ `Podfile`, `build.gradle`, `pubspec.yaml`, `AppDelegate.swift`,
64
+ `MainActivity.kt`, etc.)
65
+ - Clearly state what you detected (e.g., “This looks like a React Native
66
+ project with iOS and Android”)
67
+ - **Ask clarifying questions when needed**
68
+ - If multiple platforms are present, ask the user which one(s) to integrate
69
+ first
70
+ - If the structure is unusual, ask before making assumptions
71
+ - **Explain each step briefly**
72
+ - Before making changes, say what you are about to do and why (install
73
+ dependency, update entrypoint, add config, etc.)
74
+ - Keep explanations short but concrete, so the user understands the impact
75
+ - **Handle errors gracefully**
76
+ - If a command or change fails, show the error, explain likely causes, and
77
+ suggest concrete next steps
78
+ - Avoid getting stuck in loops—propose a fallback if automation fails
79
+ - **End with a verification summary**
80
+ - Summarize what was installed/modified (files touched, dependencies added)
81
+ - Point out any remaining manual steps (e.g., Xcode capabilities, Firebase
82
+ config, running the app to test)
83
+
84
+ ## Integration Workflow
85
+
86
+ ### Phase 1: Prerequisite — Credentials (User Setup)
87
+
88
+ Before continuing, the user must ensure the following environment variables are
89
+ available to the app at runtime:
90
+
91
+ - `CLIX_PROJECT_ID`
92
+ - `CLIX_PUBLIC_API_KEY`
93
+
94
+ **How to get credentials:**
95
+
96
+ - Ask the user to visit `https://console.clix.so/` and copy the values for their
97
+ Clix project.
98
+
99
+ **How to set credentials:**
100
+
101
+ - Add them to a local `.env` file (recommended), or to your framework’s env
102
+ configuration (see `references/framework-patterns.md`).
103
+ - Ensure `.env` is in `.gitignore`.
104
+
105
+ **Security warning:**
106
+
107
+ - Do **not** paste credentials into chat. Enter them directly into the user’s
108
+ terminal/editor.
109
+
110
+ ### Phase 2: Project Type Detection
111
+
112
+ **Step 2.1: Identify Platform**
113
+
114
+ Examine the codebase structure to determine platform:
115
+
116
+ - **iOS**: Look for `.xcodeproj`, `Podfile`, `Info.plist`, Swift/Objective-C
117
+ files
118
+ - **Android**: Look for `build.gradle`, `AndroidManifest.xml`, Kotlin/Java files
119
+ - **Flutter**: Look for `pubspec.yaml`, `lib/main.dart`, plus `ios/` and
120
+ `android/` folders
121
+ - **React Native**: Look for `package.json` with React Native dependencies,
122
+ `android/` and `ios/` folders
123
+ - **Other**: If it’s not one of the above, stop and ask the user—this skill is
124
+ mobile-only.
125
+
126
+ **Step 2.2: Verify Detection**
127
+
128
+ Confirm platform detection with user if ambiguous:
129
+
130
+ - Multiple platforms detected (e.g., React Native has both iOS and Android)
131
+ - Unusual project structure
132
+ - Hybrid applications
133
+
134
+ ### Phase 3: SDK Installation
135
+
136
+ **Step 3.1: Install SDK Package**
137
+
138
+ Install the appropriate SDK based on detected platform:
139
+
140
+ **iOS (Swift Package Manager):**
141
+
142
+ ```swift
143
+ // Add to Package.swift or Xcode: https://github.com/clix-so/clix-ios-sdk
144
+ ```
145
+
146
+ **iOS (CocoaPods):**
147
+
148
+ ```ruby
149
+ # Add to Podfile
150
+ pod 'Clix', :git => 'https://github.com/clix-so/clix-ios-sdk.git'
151
+ ```
152
+
153
+ **Android (Gradle):**
154
+
155
+ ```kotlin
156
+ // Add to build.gradle.kts
157
+ implementation("so.clix:clix-android-sdk:latest")
158
+ ```
159
+
160
+ **React Native:**
161
+
162
+ ```bash
163
+ npm install @clix-so/react-native-sdk
164
+ # or
165
+ yarn add @clix-so/react-native-sdk
166
+ ```
167
+
168
+ **Flutter:**
169
+
170
+ - Add the Clix Flutter SDK dependency in `pubspec.yaml`:
171
+ ```yaml
172
+ dependencies:
173
+ clix_flutter: ^0.0.1
174
+ firebase_core: ^3.6.0
175
+ firebase_messaging: ^15.1.3
176
+ ```
177
+ - If MCP tools (`search_docs`, `search_sdk`) are available, use them to confirm
178
+ the latest package version and setup steps.
179
+
180
+ **Step 3.2: Verify Installation**
181
+
182
+ - Check that package appears in dependency files (`package.json`,
183
+ `Podfile.lock`, `build.gradle`)
184
+ - Verify import/require statements work
185
+ - Check for installation errors
186
+
187
+ ### Phase 4: SDK Initialization
188
+
189
+ **Step 4.1: Locate Entry Point**
190
+
191
+ Find the appropriate initialization location:
192
+
193
+ - **iOS**: `AppDelegate.swift` or `@main` app file
194
+ - **Android**: `Application.kt` or `Application.java` class
195
+ - **Flutter**: `lib/main.dart`
196
+ - **React Native**: Root component or `index.js`
197
+
198
+ **Step 4.2: Initialize SDK**
199
+
200
+ Add initialization code following platform-specific patterns (see examples/
201
+ directory):
202
+
203
+ **Key Requirements:**
204
+
205
+ - Initialize early in application lifecycle
206
+ - Use environment variables for credentials (never hardcode)
207
+ - Handle initialization errors gracefully
208
+ - Follow framework-specific best practices
209
+
210
+ **Step 4.3: Configure SDK**
211
+
212
+ Set up SDK configuration:
213
+
214
+ - Use `CLIX_PROJECT_ID` from environment variables
215
+ - Use `CLIX_PUBLIC_API_KEY` from environment variables
216
+ - Set appropriate environment (production/staging/development)
217
+ - Configure logging level if needed
218
+ - Enable/disable features as required
219
+
220
+ ### Phase 5: Integration Verification
221
+
222
+ **Step 5.1: Code Review**
223
+
224
+ Verify integration completeness:
225
+
226
+ - SDK is imported/required correctly
227
+ - Initialization code is in correct location
228
+ - Credentials are loaded from environment variables
229
+ - Error handling is implemented
230
+ - No hardcoded credentials
231
+
232
+ **Step 5.2: Verify Integration**
233
+
234
+ Run validation checks:
235
+
236
+ - Execute `scripts/validate-sdk.sh` if available
237
+ - Check that SDK initializes without errors
238
+ - Verify environment variables are accessible
239
+ - Verify SDK is properly imported and initialized
240
+
241
+ **Step 5.3: Documentation**
242
+
243
+ Create or update documentation:
244
+
245
+ - Add integration notes to README.md
246
+ - Document environment variables needed
247
+ - Note any framework-specific considerations
248
+ - Update `.env.example` if it exists
249
+
250
+ ## Framework-Specific Patterns
251
+
252
+ ### iOS (Swift)
253
+
254
+ **Initialization Pattern:**
255
+
256
+ ```swift
257
+ import Clix
258
+
259
+ @main
260
+ struct MyApp: App {
261
+ init() {
262
+ // Load credentials from your app configuration (do NOT hardcode).
263
+ // Example: store values in Info.plist keys.
264
+ let projectId = Bundle.main.object(forInfoDictionaryKey: "CLIX_PROJECT_ID") as? String ?? ""
265
+ let apiKey = Bundle.main.object(forInfoDictionaryKey: "CLIX_PUBLIC_API_KEY") as? String
266
+
267
+ let config = ClixConfig(projectId: projectId, apiKey: apiKey)
268
+ Clix.initialize(config: config)
269
+ }
270
+ }
271
+ ```
272
+
273
+ **Key Points:**
274
+
275
+ - Initialize in `@main` app struct or `AppDelegate`
276
+ - Use environment variables, never hardcode
277
+ - Handle optional API key for analytics-only mode
278
+
279
+ ### Android (Kotlin)
280
+
281
+ **Initialization Pattern:**
282
+
283
+ ```kotlin
284
+ import so.clix.core.Clix
285
+ import so.clix.core.ClixConfig
286
+
287
+ class MyApplication : Application() {
288
+ override fun onCreate() {
289
+ super.onCreate()
290
+
291
+ // Load credentials from BuildConfig (do NOT hardcode).
292
+ val config = ClixConfig.Builder()
293
+ .projectId(BuildConfig.CLIX_PROJECT_ID)
294
+ .apiKey(BuildConfig.CLIX_PUBLIC_API_KEY)
295
+ .build()
296
+
297
+ Clix.initialize(this, config)
298
+ }
299
+ }
300
+ ```
301
+
302
+ **Key Points:**
303
+
304
+ - Initialize in `Application.onCreate()`
305
+ - Use `Application` context, not Activity context
306
+ - Register Application class in `AndroidManifest.xml`
307
+
308
+ ### React Native
309
+
310
+ **Initialization Pattern:**
311
+
312
+ ```typescript
313
+ import { Clix } from "@clix-so/react-native-sdk";
314
+ import Config from "react-native-config";
315
+
316
+ // In App.tsx or index.js
317
+ Clix.initialize({
318
+ projectId: Config.CLIX_PROJECT_ID || "",
319
+ apiKey: Config.CLIX_PUBLIC_API_KEY,
320
+ });
321
+ ```
322
+
323
+ **Key Points:**
324
+
325
+ - Initialize in root component
326
+ - Use `react-native-config` (or similar) for environment variables
327
+ - Link native dependencies if needed
328
+
329
+ ### Flutter
330
+
331
+ **Initialization Pattern:**
332
+
333
+ ```dart
334
+ import 'package:clix_flutter/clix_flutter.dart';
335
+
336
+ Future<void> main() async {
337
+ // Load credentials from build-time configuration (do NOT hardcode).
338
+ // Example:
339
+ // flutter run --dart-define=CLIX_PROJECT_ID=... --dart-define=CLIX_PUBLIC_API_KEY=...
340
+ const projectId = String.fromEnvironment('CLIX_PROJECT_ID');
341
+ const apiKey = String.fromEnvironment('CLIX_PUBLIC_API_KEY');
342
+
343
+ await Clix.initialize(
344
+ ClixConfig(
345
+ projectId: projectId,
346
+ apiKey: apiKey,
347
+ ),
348
+ );
349
+
350
+ runApp(const MyApp());
351
+ }
352
+ ```
353
+
354
+ **Key Points:**
355
+
356
+ - Initialize before `runApp`
357
+ - Use `--dart-define` (or your chosen secret mechanism), never hardcode
358
+
359
+ ## Error Handling
360
+
361
+ **Common Issues:**
362
+
363
+ 1. **Missing Credentials**
364
+ - Error: SDK fails to initialize
365
+ - Solution: Verify `.env` file exists and contains required variables
366
+ - Check: Environment variable names match exactly
367
+
368
+ 2. **Wrong Initialization Location**
369
+ - Error: SDK not tracking events
370
+ - Solution: Ensure initialization happens before any SDK usage
371
+ - Check: Initialization is in app entry point, not a component
372
+
373
+ 3. **Environment Variables Not Loading**
374
+ - Error: `undefined` or empty values
375
+ - Solution: Verify env loading mechanism (dotenv, framework config, etc.)
376
+ - Check: Variable names match framework requirements (prefixes)
377
+
378
+ ## Best Practices
379
+
380
+ 1. **Never hardcode credentials** - Always use environment variables
381
+ 2. **Initialize early** - SDK should initialize before app starts or as early as
382
+ possible
383
+ 3. **Handle errors gracefully** - Wrap initialization in try-catch blocks
384
+ 4. **Use appropriate environment** - Set production/staging/development based on
385
+ build
386
+ 5. **Verify integration** - Use validation scripts to verify SDK is properly
387
+ integrated
388
+ 6. **Document changes** - Update README and configuration files
389
+ 7. **Version control** - Add `.env` to `.gitignore`, commit `.env.example`
390
+
391
+ ## Progressive Disclosure
392
+
393
+ - **Level 1**: This SKILL.md file (always loaded)
394
+ - **Level 2**: `references/` directory (loaded when needed for specific topics)
395
+ - **Level 3**: `examples/` directory (loaded when framework-specific examples
396
+ needed)
397
+ - **Level 4**: `scripts/` directory (executed directly, not loaded into context)
398
+
399
+ ## References
400
+
401
+ For detailed information, see:
402
+
403
+ - `references/sdk-reference.md` - Complete SDK API documentation
404
+ - `references/framework-patterns.md` - Framework-specific integration patterns
405
+ - `references/error-handling.md` - Common errors and troubleshooting
406
+ - `references/mcp-integration.md` - Optional: MCP server usage guide (for
407
+ tool-augmented mode)
408
+
409
+ ## Examples
410
+
411
+ Working code examples available in `examples/` directory:
412
+
413
+ - `ios-integration.swift` - iOS integration (UIKit/SwiftUI)
414
+ - `android-integration.kt` - Android integration (Application)
415
+ - `flutter-integration.dart` - Flutter integration (main.dart)
416
+ - `react-native-integration.tsx` - React Native integration (App.tsx)
417
+
418
+ ## Scripts
419
+
420
+ Utility scripts available in `scripts/` directory:
421
+
422
+ - `validate-sdk.sh` - Validate SDK installation and initialization (bash,
423
+ deterministic)
424
+
425
+ Run scripts with `--help` first to see usage. Do not read source code unless
426
+ customization is absolutely necessary.
@@ -0,0 +1,38 @@
1
+ // Android Clix SDK Integration Example
2
+ //
3
+ // Constructed from Clix MCP sources:
4
+ // - `search_sdk` (Android): Clix.initialize(context, config) and ClixConfig model
5
+ // - `search_sdk` (Android sample): samples/basic-app/AndroidManifest.xml shows Application entrypoint name
6
+ //
7
+ // Note: the official sample app also uses an assets-based config (`ClixConfig.json`).
8
+ // The code for that loader isn't returned in current `search_sdk` results, so this example keeps
9
+ // the official SDK API shape (Clix.initialize + ClixConfig) without inventing a loader.
10
+
11
+ package com.example.app
12
+
13
+ import android.app.Application
14
+ import so.clix.core.Clix
15
+ import so.clix.core.ClixConfig
16
+
17
+ class MyApplication : Application() {
18
+ override fun onCreate() {
19
+ super.onCreate()
20
+
21
+ val projectId = BuildConfig.CLIX_PROJECT_ID ?: "YOUR_PROJECT_ID"
22
+ val apiKey = BuildConfig.CLIX_PUBLIC_API_KEY ?: "YOUR_API_KEY"
23
+
24
+ // Use verified ClixConfig pattern
25
+ val config = ClixConfig(
26
+ projectId = projectId,
27
+ apiKey = apiKey,
28
+ // logLevel = ClixLogLevel.INFO (optional)
29
+ )
30
+
31
+ // Must be application context
32
+ Clix.initialize(this, config)
33
+ }
34
+ }
35
+
36
+ // AndroidManifest.xml:
37
+ // <application android:name=".MyApplication" ... />
38
+
@@ -0,0 +1,81 @@
1
+ // Flutter Clix SDK Integration Example
2
+ //
3
+ // This file is constructed directly from Clix SDK `search_sdk` sample sources:
4
+ // - samples/basic_app/lib/main.dart
5
+ // - samples/basic_app/lib/clix_configuration.dart
6
+ //
7
+ // Pattern:
8
+ // - WidgetsFlutterBinding.ensureInitialized()
9
+ // - Firebase.initializeApp()
10
+ // - Load `assets/clix_config.json` -> ClixConfig
11
+ // - await Clix.initialize(config)
12
+ // - await Clix.Notification.configure(autoRequestPermission: true)
13
+
14
+ import 'dart:convert';
15
+
16
+ import 'package:clix_flutter/clix_flutter.dart';
17
+ import 'package:firebase_core/firebase_core.dart';
18
+ import 'package:flutter/material.dart';
19
+ import 'package:flutter/services.dart';
20
+
21
+ class ClixConfiguration {
22
+ static const ClixLogLevel logLevel = ClixLogLevel.debug;
23
+
24
+ static ClixConfig? _config;
25
+
26
+ static ClixConfig get config {
27
+ if (_config == null) {
28
+ throw StateError(
29
+ 'ClixConfiguration not initialized. Call initialize() first.',
30
+ );
31
+ }
32
+ return _config!;
33
+ }
34
+
35
+ static Future<void> initialize({
36
+ String path = 'assets/clix_config.json',
37
+ }) async {
38
+ if (_config != null) return; // Already initialized
39
+
40
+ final jsonString = await rootBundle.loadString(path);
41
+ final jsonMap = json.decode(jsonString) as Map<String, dynamic>;
42
+
43
+ _config = ClixConfig(
44
+ projectId: jsonMap['projectId'] as String,
45
+ apiKey: jsonMap['apiKey'] as String,
46
+ endpoint: jsonMap['endpoint'] as String,
47
+ logLevel: logLevel,
48
+ extraHeaders: Map<String, String>.from(
49
+ jsonMap['extraHeaders'] as Map? ?? {},
50
+ ),
51
+ );
52
+ }
53
+ }
54
+
55
+ Future<void> main() async {
56
+ WidgetsFlutterBinding.ensureInitialized();
57
+
58
+ await Firebase.initializeApp();
59
+
60
+ await ClixConfiguration.initialize();
61
+ final config = ClixConfiguration.config;
62
+
63
+ await Clix.initialize(config);
64
+ await Clix.Notification.configure(autoRequestPermission: true);
65
+
66
+ runApp(const MyApp());
67
+ }
68
+
69
+ class MyApp extends StatelessWidget {
70
+ const MyApp({super.key});
71
+
72
+ @override
73
+ Widget build(BuildContext context) {
74
+ return const MaterialApp(
75
+ home: Scaffold(
76
+ body: Center(child: Text('Clix Flutter Integration Example')),
77
+ ),
78
+ );
79
+ }
80
+ }
81
+
@@ -0,0 +1,36 @@
1
+ // iOS Clix SDK Integration Example
2
+ //
3
+ // This file is constructed directly from Clix SDK `search_sdk` sample sources:
4
+ // - Samples/BasicApp/Sources/AppDelegate.swift
5
+ // - Samples/BasicApp/Sources/ClixConfiguration.swift
6
+ // - Samples/BasicApp/Sources/AppState.swift
7
+ //
8
+ // It demonstrates:
9
+ // - Using a standard `AppDelegate` that conforms to `UIApplicationDelegate`
10
+ // - Creating `ClixConfig` from environment variables (e.g., CLIX_PROJECT_ID, CLIX_PUBLIC_API_KEY)
11
+ // - Initializing `Clix` early in `application(_:didFinishLaunchingWithOptions:)`
12
+
13
+ import Clix
14
+ import FirebaseCore
15
+ import UIKit
16
+
17
+ @main
18
+ class AppDelegate: UIResponder, UIApplicationDelegate {
19
+ func application(
20
+ _ application: UIApplication,
21
+ didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
22
+ ) -> Bool {
23
+ // Initialize ClixConfig with params (verified pattern)
24
+ let config = ClixConfig(
25
+ projectId: ProcessInfo.processInfo.environment["CLIX_PROJECT_ID"] ?? "YOUR_PROJECT_ID",
26
+ apiKey: ProcessInfo.processInfo.environment["CLIX_PUBLIC_API_KEY"] ?? "YOUR_PUBLIC_API_KEY",
27
+ logLevel: .info
28
+ )
29
+
30
+ // Pass config to initialize
31
+ try? Clix.initialize(config: config)
32
+
33
+ return true
34
+ }
35
+ }
36
+
@@ -0,0 +1,18 @@
1
+ // React Native Clix SDK Integration Example
2
+ //
3
+ // This file is constructed directly from Clix SDK `search_sdk` sample source:
4
+ // - samples/BasicApp/index.js
5
+ //
6
+ // Note: In a real RN app, this code typically lives in your `index.js` / `index.ts` bootstrap file.
7
+
8
+ import Clix from "@clix-so/react-native-sdk";
9
+ import { AppRegistry } from "react-native";
10
+
11
+ // These imports mirror the sample app structure:
12
+ import { name as appName } from "./app.json";
13
+ import App from "./src/App";
14
+ import config from "./src/assets/clix_config.json";
15
+
16
+ Clix.initialize(config);
17
+
18
+ AppRegistry.registerComponent(appName, () => App);