@cometchat/skills 3.0.0 → 4.0.0

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.
Files changed (101) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +44 -17
  3. package/bin/install.js +389 -43
  4. package/package.json +19 -9
  5. package/skills/cometchat/SKILL.md +1066 -265
  6. package/skills/cometchat-android-v5/SKILL.md +120 -0
  7. package/skills/cometchat-android-v5-components/SKILL.md +430 -0
  8. package/skills/cometchat-android-v5-core/SKILL.md +468 -0
  9. package/skills/cometchat-android-v5-customization/SKILL.md +305 -0
  10. package/skills/cometchat-android-v5-extensions/SKILL.md +124 -0
  11. package/skills/cometchat-android-v5-features/SKILL.md +130 -0
  12. package/skills/cometchat-android-v5-placement/SKILL.md +276 -0
  13. package/skills/cometchat-android-v5-production/SKILL.md +94 -0
  14. package/skills/cometchat-android-v5-push/SKILL.md +620 -0
  15. package/skills/cometchat-android-v5-testing/SKILL.md +187 -0
  16. package/skills/cometchat-android-v5-theming/SKILL.md +166 -0
  17. package/skills/cometchat-android-v5-troubleshooting/SKILL.md +73 -0
  18. package/skills/cometchat-android-v6/SKILL.md +107 -0
  19. package/skills/cometchat-android-v6-builder-settings/SKILL.md +145 -0
  20. package/skills/cometchat-android-v6-compose-components/SKILL.md +202 -0
  21. package/skills/cometchat-android-v6-compose-customization/SKILL.md +280 -0
  22. package/skills/cometchat-android-v6-compose-placement/SKILL.md +213 -0
  23. package/skills/cometchat-android-v6-compose-theming/SKILL.md +224 -0
  24. package/skills/cometchat-android-v6-core/SKILL.md +354 -0
  25. package/skills/cometchat-android-v6-events/SKILL.md +212 -0
  26. package/skills/cometchat-android-v6-extensions/SKILL.md +191 -0
  27. package/skills/cometchat-android-v6-features/SKILL.md +130 -0
  28. package/skills/cometchat-android-v6-kotlin-components/SKILL.md +197 -0
  29. package/skills/cometchat-android-v6-kotlin-customization/SKILL.md +268 -0
  30. package/skills/cometchat-android-v6-kotlin-placement/SKILL.md +248 -0
  31. package/skills/cometchat-android-v6-kotlin-theming/SKILL.md +202 -0
  32. package/skills/cometchat-android-v6-production/SKILL.md +187 -0
  33. package/skills/cometchat-android-v6-push/SKILL.md +274 -0
  34. package/skills/cometchat-android-v6-testing/SKILL.md +279 -0
  35. package/skills/cometchat-android-v6-troubleshooting/SKILL.md +249 -0
  36. package/skills/cometchat-angular-components/SKILL.md +706 -0
  37. package/skills/cometchat-angular-core/SKILL.md +444 -0
  38. package/skills/cometchat-angular-customization/SKILL.md +424 -0
  39. package/skills/cometchat-angular-features/SKILL.md +447 -0
  40. package/skills/cometchat-angular-patterns/SKILL.md +447 -0
  41. package/skills/cometchat-angular-placement/SKILL.md +685 -0
  42. package/skills/cometchat-angular-production/SKILL.md +415 -0
  43. package/skills/cometchat-angular-theming/SKILL.md +365 -0
  44. package/skills/cometchat-angular-troubleshooting/SKILL.md +329 -0
  45. package/skills/cometchat-astro-patterns/SKILL.md +3 -3
  46. package/skills/cometchat-components/SKILL.md +11 -0
  47. package/skills/cometchat-core/SKILL.md +11 -6
  48. package/skills/cometchat-customization/references/component-catalog.md +1 -1
  49. package/skills/cometchat-features/SKILL.md +176 -108
  50. package/skills/cometchat-flutter-v5/SKILL.md +167 -0
  51. package/skills/cometchat-flutter-v5-calls/SKILL.md +192 -0
  52. package/skills/cometchat-flutter-v5-conversations/SKILL.md +117 -0
  53. package/skills/cometchat-flutter-v5-core/SKILL.md +221 -0
  54. package/skills/cometchat-flutter-v5-customization/SKILL.md +227 -0
  55. package/skills/cometchat-flutter-v5-events/SKILL.md +155 -0
  56. package/skills/cometchat-flutter-v5-messages/SKILL.md +258 -0
  57. package/skills/cometchat-flutter-v5-production/SKILL.md +207 -0
  58. package/skills/cometchat-flutter-v5-push/SKILL.md +284 -0
  59. package/skills/cometchat-flutter-v5-theming/SKILL.md +160 -0
  60. package/skills/cometchat-flutter-v5-troubleshooting/SKILL.md +129 -0
  61. package/skills/cometchat-flutter-v5-users-groups/SKILL.md +151 -0
  62. package/skills/cometchat-flutter-v6/SKILL.md +445 -0
  63. package/skills/cometchat-flutter-v6-calls/SKILL.md +333 -0
  64. package/skills/cometchat-flutter-v6-components/SKILL.md +365 -0
  65. package/skills/cometchat-flutter-v6-conversations/SKILL.md +210 -0
  66. package/skills/cometchat-flutter-v6-core/SKILL.md +305 -0
  67. package/skills/cometchat-flutter-v6-customization/SKILL.md +666 -0
  68. package/skills/cometchat-flutter-v6-events/SKILL.md +216 -0
  69. package/skills/cometchat-flutter-v6-features/SKILL.md +406 -0
  70. package/skills/cometchat-flutter-v6-messages/SKILL.md +333 -0
  71. package/skills/cometchat-flutter-v6-migration/SKILL.md +381 -0
  72. package/skills/cometchat-flutter-v6-placement/SKILL.md +398 -0
  73. package/skills/cometchat-flutter-v6-production/SKILL.md +632 -0
  74. package/skills/cometchat-flutter-v6-theming/SKILL.md +260 -0
  75. package/skills/cometchat-flutter-v6-troubleshooting/SKILL.md +726 -0
  76. package/skills/cometchat-flutter-v6-users-groups/SKILL.md +216 -0
  77. package/skills/cometchat-ios/SKILL.md +323 -0
  78. package/skills/cometchat-ios-components/SKILL.md +651 -0
  79. package/skills/cometchat-ios-core/SKILL.md +822 -0
  80. package/skills/cometchat-ios-customization/SKILL.md +825 -0
  81. package/skills/cometchat-ios-features/SKILL.md +725 -0
  82. package/skills/cometchat-ios-placement/SKILL.md +750 -0
  83. package/skills/cometchat-ios-production/SKILL.md +730 -0
  84. package/skills/cometchat-ios-push/SKILL.md +582 -0
  85. package/skills/cometchat-ios-theming/SKILL.md +631 -0
  86. package/skills/cometchat-ios-troubleshooting/SKILL.md +983 -0
  87. package/skills/cometchat-native-bare-patterns/SKILL.md +470 -0
  88. package/skills/cometchat-native-components/SKILL.md +594 -0
  89. package/skills/cometchat-native-core/SKILL.md +407 -0
  90. package/skills/cometchat-native-customization/SKILL.md +594 -0
  91. package/skills/cometchat-native-expo-patterns/SKILL.md +485 -0
  92. package/skills/cometchat-native-features/SKILL.md +608 -0
  93. package/skills/cometchat-native-placement/SKILL.md +500 -0
  94. package/skills/cometchat-native-production/SKILL.md +694 -0
  95. package/skills/cometchat-native-push/SKILL.md +593 -0
  96. package/skills/cometchat-native-testing/SKILL.md +583 -0
  97. package/skills/cometchat-native-theming/SKILL.md +656 -0
  98. package/skills/cometchat-native-troubleshooting/SKILL.md +433 -0
  99. package/skills/cometchat-nextjs-patterns/SKILL.md +5 -5
  100. package/skills/cometchat-production/SKILL.md +60 -0
  101. package/skills/cometchat-react-router-patterns/SKILL.md +23 -21
@@ -0,0 +1,608 @@
1
+ ---
2
+ name: cometchat-native-features
3
+ description: "Feature catalog for React Native — calls (separate SDK + WebRTC), extensions (polls / stickers / translation / link preview / collaborative doc / whiteboard / smart replies), AI agent, in-call chat. When to toggle, install, or swap."
4
+ license: "MIT"
5
+ compatibility: "Node.js >=18; React Native >=0.70; @cometchat/chat-uikit-react-native ^5"
6
+ allowed-tools: "executeBash, readFile, fileSearch, listDirectory, AskUserQuestion"
7
+ metadata:
8
+ author: "CometChat"
9
+ version: "3.0.0"
10
+ tags: "cometchat react-native features calls extensions ai"
11
+ ---
12
+
13
+ ## Purpose
14
+
15
+ Teaches Claude how to add features on top of a working CometChat React Native integration. Classifies each feature into one of four types and gives the correct recipe for each.
16
+
17
+ **Read `cometchat-native-core` + `cometchat-native-components` + (`cometchat-native-expo-patterns` or `cometchat-native-bare-patterns`) first** — a base integration must already exist before features layer on.
18
+
19
+ Ground truth: `docs/ui-kit/react-native/core-features.mdx`, `calling-integration.mdx`, `call-*.mdx`, `incoming-call.mdx`, `outgoing-call.mdx`, `extensions.mdx`, `guide-ai-agent.mdx`, `ai-assistant-chat-history.mdx`, and `@cometchat/chat-uikit-react-native@5.3.3` exports.
20
+
21
+ ---
22
+
23
+ ## 1. Feature taxonomy
24
+
25
+ Every CometChat feature falls into exactly one of four categories. The category determines the recipe:
26
+
27
+ | Category | What it means | Example features | How to enable |
28
+ |---|---|---|---|
29
+ | **Default** | Already on — no action needed. Shipped with the kit's base components. | Instant messaging, typing indicators, read receipts, reactions on messages, replies, @mentions, media upload, edit/delete, message info | Just render `CometChatMessageHeader` + `CometChatMessageList` + `CometChatMessageComposer` |
30
+ | **Extension** | Pure boolean backend toggle. CLI flips it via the dashboard API; UI Kit auto-wires the feature once enabled. | Polls, stickers, message translation, link previews, collaborative whiteboard, collaborative document, thumbnail generation | `cometchat apply-feature <id>` → hard-reload the app |
31
+ | **AI feature** | Backend AI toggle that requires an OpenAI API key on the app. CLI sets the key + flips the toggle in one call. | Smart replies, conversation summary, conversation starter | `cometchat apply-feature smart-replies --openai-key sk-…` |
32
+ | **Package-install** | Install an additional npm package + maybe native peer deps. The UI Kit auto-detects the package on next init. | Voice + video calls (`@cometchat/calls-sdk-react-native`) | `npm install ...` → pod install (iOS) → rebuild |
33
+ | **Component-swap** | Replace or wrap a UI Kit component with a customized version. | Custom text formatter (emoji shortcuts, custom tags), custom message templates, AI Agent chat history | Write a new component + pass via prop |
34
+
35
+ Reminder — don't confuse these with **customization** (per-skill-coverage under `cometchat-native-customization`). This skill is "add a feature that CometChat ships"; customization is "change how an existing feature looks or behaves".
36
+
37
+ ---
38
+
39
+ ## 2. Enabling extension and AI features (`apply-feature`)
40
+
41
+ Most extensions (polls, stickers, translation, link preview, collaborative doc/whiteboard, thumbnails) are pure boolean toggles. Use the CLI:
42
+
43
+ ### Extension features
44
+
45
+ ```bash
46
+ cometchat apply-feature polls --json
47
+ cometchat apply-feature link-preview --json
48
+ ```
49
+
50
+ The CLI reads the app ID from `.cometchat/state.json` (RN goes through `cometchat apply`), or pass `--app-id` explicitly. Bearer is from the OS keychain (`cometchat auth login` once per machine).
51
+
52
+ ### AI features (smart replies, conversation summary, conversation starter)
53
+
54
+ These need an OpenAI API key. The CLI sets the key + flips the toggle in one call:
55
+
56
+ ```bash
57
+ cometchat apply-feature smart-replies --openai-key sk-...
58
+ ```
59
+
60
+ Once any AI feature is enabled the key is stored on the app, so subsequent ai-feature applies don't need `--openai-key` repeated.
61
+
62
+ Get an OpenAI key at https://platform.openai.com/api-keys.
63
+
64
+ ### Response shapes (`--json`)
65
+
66
+ - `"status": "applied"` → done. Hard-reload (stop Metro + restart + rebuild if on iOS).
67
+ - `"status": "already-applied"` → already in the desired state.
68
+ - `"status": "auth-required"` → `cometchat auth login` first.
69
+ - `"status": "openai-key-required"` → re-run with `--openai-key sk-…`.
70
+ - `"status": "manual-action-required"` → dashboard-only feature (Giphy, Stipop, Tenor, Chatwoot, Intercom, message-shortcuts, disappearing-messages). Surface the `next_steps` verbatim — these need third-party config the user has to provide manually.
71
+ - `"status": "error"` → surface `next_steps` — includes the dashboard URL as a fallback.
72
+
73
+ ### Dashboard fallback
74
+
75
+ Only when the CLI returns `error` or isn't available:
76
+ 1. https://app.cometchat.com → your app
77
+ 2. Chat & Messaging → Features
78
+ 3. Find the extension by name → flip Status ON
79
+ 4. Hard-reload the RN app
80
+
81
+ ### What each toggle does
82
+
83
+ | Extension | UI surface when enabled |
84
+ |---|---|
85
+ | Polls | Polls option in `CometChatMessageComposer`'s attachment Action Sheet |
86
+ | Stickers | Sticker picker in the composer |
87
+ | Smart replies | Chip suggestions above the composer input after an incoming message |
88
+ | Message translation | "Translate" option in the message long-press menu |
89
+ | Link preview | Rich-card bubble for URLs in the message list |
90
+ | Collaborative document | Option in composer's Action Sheet; opens a shared doc on tap |
91
+ | Collaborative whiteboard | Option in composer's Action Sheet; opens a shared canvas |
92
+ | Thumbnail generation | Image / video bubbles show thumbnails instead of full-size downloads |
93
+
94
+ ### Gotcha — `auto_wired_in_uikit: false`
95
+
96
+ A minority of extensions need extra wiring via the `extensions` field on `CometChatUIKit.init()`. The CLI flags this in its success response:
97
+
98
+ ```json
99
+ {
100
+ "status": "enabled",
101
+ "name": "stickers",
102
+ "auto_wired_in_uikit": false,
103
+ "next_steps": [
104
+ "Pass the extension via the `extensions` field on CometChatUIKit.init({ ... })"
105
+ ]
106
+ }
107
+ ```
108
+
109
+ If `auto_wired_in_uikit` is `false`, import the matching `ExtensionsDataSource` from `@cometchat/chat-uikit-react-native` and pass it via the flat `extensions` field:
110
+
111
+ ```tsx
112
+ import {
113
+ CometChatUIKit,
114
+ StickersExtension,
115
+ PollsExtension,
116
+ } from "@cometchat/chat-uikit-react-native";
117
+
118
+ await CometChatUIKit.init({
119
+ appId: APP_ID,
120
+ region: REGION,
121
+ authKey: AUTH_KEY,
122
+ subscriptionType: "ALL_USERS",
123
+ extensions: [new StickersExtension(), new PollsExtension()], // ← new
124
+ });
125
+ ```
126
+
127
+ Query the docs MCP for the exact extension class name if you don't remember it — `extensions.mdx` lists all of them.
128
+
129
+ ---
130
+
131
+ ## 3. Calls (package-install)
132
+
133
+ Calls are the biggest "add a feature" step. They require the separate `@cometchat/calls-sdk-react-native` package, additional peer native modules (WebRTC + netinfo + background-timer + callstats), and app-side listener setup.
134
+
135
+ ### 3a — Install the calls SDK + peer deps
136
+
137
+ **Expo (managed workflow)**:
138
+
139
+ ```bash
140
+ npm install @cometchat/calls-sdk-react-native
141
+ npx expo install \
142
+ @react-native-community/netinfo \
143
+ react-native-background-timer \
144
+ react-native-callstats \
145
+ react-native-webrtc
146
+ npx expo prebuild --clean
147
+ ```
148
+
149
+ **Bare RN**:
150
+
151
+ ```bash
152
+ npm install \
153
+ @cometchat/calls-sdk-react-native \
154
+ @react-native-community/netinfo \
155
+ react-native-background-timer \
156
+ react-native-callstats \
157
+ react-native-webrtc
158
+ cd ios && pod install && cd ..
159
+ ```
160
+
161
+ ### 3b — Platform permissions (if not already from core integration)
162
+
163
+ **iOS** — `ios/<App>/Info.plist`:
164
+
165
+ ```xml
166
+ <key>NSCameraUsageDescription</key>
167
+ <string>Camera access for video calls</string>
168
+ <key>NSMicrophoneUsageDescription</key>
169
+ <string>Microphone access for voice and video calls</string>
170
+ ```
171
+
172
+ **Android** — `android/app/src/main/AndroidManifest.xml`:
173
+
174
+ ```xml
175
+ <uses-permission android:name="android.permission.INTERNET" />
176
+ <uses-permission android:name="android.permission.CAMERA" />
177
+ <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
178
+ <uses-permission android:name="android.permission.RECORD_AUDIO" />
179
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
180
+ ```
181
+
182
+ ### 3c — iOS deployment target + build settings
183
+
184
+ Calls SDK requires iOS 12+ and specific Podfile flags. Add to `ios/Podfile`:
185
+
186
+ ```ruby
187
+ post_install do |installer|
188
+ installer.pods_project.targets.each do |target|
189
+ target.build_configurations.each do |config|
190
+ config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0'
191
+ config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64 i386'
192
+ config.build_settings['ENABLE_BITCODE'] = 'NO'
193
+ end
194
+ end
195
+ end
196
+ ```
197
+
198
+ Android (`android/app/build.gradle`):
199
+
200
+ ```groovy
201
+ android {
202
+ compileSdkVersion 33
203
+ defaultConfig {
204
+ minSdkVersion 24
205
+ targetSdkVersion 33
206
+ }
207
+ }
208
+ ```
209
+
210
+ ### 3d — Register the call listener at app root
211
+
212
+ The incoming-call UI only shows up if you've registered a listener to pick up call events. Add this once at the app root (typically in `App.tsx` or Expo Router's `_layout.tsx`):
213
+
214
+ ```tsx
215
+ import React, { useEffect, useRef, useState } from "react";
216
+ import { CometChat } from "@cometchat/chat-sdk-react-native";
217
+ import { CometChatIncomingCall } from "@cometchat/chat-uikit-react-native";
218
+
219
+ function CallEventsProvider({ children }: { children: React.ReactNode }) {
220
+ const [callReceived, setCallReceived] = useState(false);
221
+ const incomingCall = useRef<CometChat.Call | null>(null);
222
+ const LISTENER_ID = "APP_CALL_LISTENER";
223
+
224
+ useEffect(() => {
225
+ CometChat.addCallListener(
226
+ LISTENER_ID,
227
+ new CometChat.CallListener({
228
+ onIncomingCallReceived: (call) => {
229
+ incomingCall.current = call;
230
+ setCallReceived(true);
231
+ },
232
+ onOutgoingCallAccepted: (call) => {
233
+ // navigate to the ongoing-call screen
234
+ },
235
+ onOutgoingCallRejected: () => {
236
+ incomingCall.current = null;
237
+ setCallReceived(false);
238
+ },
239
+ onIncomingCallCancelled: () => {
240
+ incomingCall.current = null;
241
+ setCallReceived(false);
242
+ },
243
+ onCallEndedMessageReceived: () => {
244
+ incomingCall.current = null;
245
+ setCallReceived(false);
246
+ },
247
+ })
248
+ );
249
+ return () => CometChat.removeCallListener(LISTENER_ID);
250
+ }, []);
251
+
252
+ return (
253
+ <>
254
+ {children}
255
+ {callReceived && incomingCall.current && (
256
+ <CometChatIncomingCall
257
+ call={incomingCall.current}
258
+ onAccept={() => { /* navigate to ongoing-call screen */ }}
259
+ onDecline={() => setCallReceived(false)}
260
+ />
261
+ )}
262
+ </>
263
+ );
264
+ }
265
+ ```
266
+
267
+ Wrap the app (inside the existing provider chain, below `CometChatProvider`):
268
+
269
+ ```tsx
270
+ <CometChatProvider ...>
271
+ <CallEventsProvider>
272
+ <AppNavigator />
273
+ </CallEventsProvider>
274
+ </CometChatProvider>
275
+ ```
276
+
277
+ ### 3e — Call buttons in the message header
278
+
279
+ Once the calls SDK is installed, `CometChatMessageHeader` auto-renders voice + video call buttons. To customize (e.g., hide one):
280
+
281
+ ```tsx
282
+ <CometChatMessageHeader
283
+ user={selectedUser}
284
+ hideVoiceCallButton={false}
285
+ hideVideoCallButton={false}
286
+ AuxiliaryButtonView={(user, group) => (
287
+ <CometChatCallButtons
288
+ user={user}
289
+ group={group}
290
+ onVoiceCallPress={(session) => navigation.navigate("OngoingCall", { session })}
291
+ onVideoCallPress={(session) => navigation.navigate("OngoingCall", { session })}
292
+ />
293
+ )}
294
+ />
295
+ ```
296
+
297
+ ### 3f — Ongoing call screen
298
+
299
+ Navigate to a dedicated screen that hosts `CometChatOngoingCall` when a call connects:
300
+
301
+ ```tsx
302
+ // OngoingCallScreen.tsx
303
+ import { CometChatOngoingCall } from "@cometchat/chat-uikit-react-native";
304
+
305
+ export function OngoingCallScreen({ route, navigation }: any) {
306
+ const { session } = route.params;
307
+ return (
308
+ <CometChatOngoingCall
309
+ sessionID={session.sessionId}
310
+ callType={session.type} // "audio" | "video"
311
+ onCallEnded={() => navigation.goBack()}
312
+ />
313
+ );
314
+ }
315
+ ```
316
+
317
+ ### 3g — Call logs
318
+
319
+ A history view of past calls. Typically one tab in a tab-based layout (see `cometchat-native-placement` § 2):
320
+
321
+ ```tsx
322
+ import { CometChatCallLogs } from "@cometchat/chat-uikit-react-native";
323
+
324
+ export function CallLogsScreen() {
325
+ return <CometChatCallLogs onItemPress={(callLog) => openCallDetails(callLog)} />;
326
+ }
327
+ ```
328
+
329
+ ### 3h — Verifying calls work
330
+
331
+ 1. Rebuild the app after adding the calls SDK (Expo: `expo run:ios` / `run:android`; bare: `npx react-native run-ios` / `run-android`)
332
+ 2. Log in as one user on device A, another on device B
333
+ 3. On device A, tap the voice or video call icon in the message header
334
+ 4. Device B should show `CometChatIncomingCall` within a few seconds
335
+ 5. Accept on B → both devices transition to `CometChatOngoingCall`
336
+
337
+ If incoming calls don't show: listener not registered, or the listener ID collides. See `cometchat-native-troubleshooting`.
338
+
339
+ ### 3i — Testing calls in CI
340
+
341
+ Real WebRTC calls can't run in Jest or Maestro — they need two real
342
+ devices plus a TURN server. What you CAN test:
343
+
344
+ - **Call button renders** — mount `CometChatMessageHeader` with a user
345
+ prop and assert the call `testID` is present (requires the calls SDK
346
+ import to not crash; mock `@cometchat/calls-sdk-react-native` in
347
+ your jest setup).
348
+ - **Call listener registration** — spy on `CometChat.addCallListener`
349
+ from the SDK mock and assert your `registerCallListener()` fires
350
+ exactly once per mount.
351
+ - **Incoming-call UI** — render `<CometChatIncomingCall call={mockCall} />`
352
+ with a stubbed `CometChat.Call` object; assert accept/reject buttons
353
+ are wired.
354
+
355
+ See `cometchat-native-testing § 5` for the SDK mock shape (includes a
356
+ `addCallListener` / `removeCallListener` stub) and § 10 for why actual
357
+ call E2E belongs in manual QA, not Detox/Maestro.
358
+
359
+ ---
360
+
361
+ ## 4. In-call chat (optional, during-call feature)
362
+
363
+ During an active call, users can chat without leaving the call UI. This is a toggle on the ongoing-call component:
364
+
365
+ ```tsx
366
+ <CometChatOngoingCall
367
+ sessionID={session.sessionId}
368
+ callType={session.type}
369
+ callSettingsBuilder={/* ... with enableInCallChat(true) */}
370
+ onCallEnded={() => navigation.goBack()}
371
+ />
372
+ ```
373
+
374
+ In-call chat adds a collapsible chat panel to the call screen. Participants see messages for the duration of the call.
375
+
376
+ ---
377
+
378
+ ## 5. AI Agent (component-swap + dashboard)
379
+
380
+ The AI Agent integration adds an AI-powered conversational assistant to your app. Two parts:
381
+
382
+ ### 5a — Dashboard setup
383
+
384
+ 1. https://app.cometchat.com → your app → AI → Agents
385
+ 2. Create a new agent (name, system prompt, model)
386
+ 3. Assign a UID to the agent (e.g. `ai-support-agent`)
387
+
388
+ Once the agent exists in the dashboard, users can message it like any other user.
389
+
390
+ ### 5b — Optional: AI Assistant Chat History UI
391
+
392
+ The UI Kit exports `CometChatAIAssistantChatHistory` for apps that want a dedicated AI-chat entry point (distinct from a regular chat with a human user). This component shows past AI conversations and a "New chat" trigger.
393
+
394
+ ```tsx
395
+ import { CometChatAIAssistantChatHistory } from "@cometchat/chat-uikit-react-native";
396
+
397
+ export function AIChatScreen({ navigation }: any) {
398
+ return (
399
+ <CometChatAIAssistantChatHistory
400
+ user={loggedInUser}
401
+ onMessageClicked={(message) => navigation.navigate("AIChat", { message })}
402
+ onNewChatButtonClick={() => navigation.navigate("AIChat", { new: true })}
403
+ />
404
+ );
405
+ }
406
+ ```
407
+
408
+ The actual AI-chat screen is a regular `CometChatMessageHeader` + `MessageList` + `Composer` composition targeted at the AI agent's UID.
409
+
410
+ ### 5c — AI features beyond the basic agent
411
+
412
+ See `ai-assistant-chat-history.mdx` and `guide-ai-agent.mdx` in the docs for:
413
+ - Multi-tool agents (tools registered via `setAIAssistantTools()`)
414
+ - Streaming responses (handled automatically via `CometChatAIAssistantMessageBubble`)
415
+ - Agent memory and persona
416
+
417
+ These are advanced topics — query the docs MCP for the current API if the user wants any of them.
418
+
419
+ ### 5d — Smart replies (custom chip UI)
420
+
421
+ Smart replies is an `ai-feature`. Enable with one CLI call (the first time also sets the OpenAI key on the app):
422
+
423
+ ```bash
424
+ cometchat apply-feature smart-replies --openai-key sk-...
425
+ ```
426
+
427
+ After enabling, no code changes are required — `CometChatMessageComposer` automatically renders suggested replies as chips above the input.
428
+
429
+ For a custom UI — e.g. inline chips inside a custom bubble, only on certain conversation types, or styled to match your design system — read the extension data straight off the incoming message and render your own chips:
430
+
431
+ ```tsx
432
+ import { TouchableOpacity, View, Text } from "react-native";
433
+ import { CometChat } from "@cometchat/chat-sdk-react-native";
434
+
435
+ interface SmartReply {
436
+ reply_positive?: string;
437
+ reply_neutral?: string;
438
+ reply_negative?: string;
439
+ }
440
+
441
+ export function SmartReplyChips({
442
+ message,
443
+ onPick,
444
+ }: {
445
+ message: CometChat.BaseMessage;
446
+ onPick: (text: string) => void;
447
+ }) {
448
+ const metadata = message.getMetadata() as Record<string, unknown> | undefined;
449
+ const extensions = (metadata?.["@injected"] as Record<string, unknown>)?.["extensions"] as
450
+ | Record<string, unknown>
451
+ | undefined;
452
+ const smartReply = extensions?.["smart-reply"] as SmartReply | undefined;
453
+ if (!smartReply) return null;
454
+
455
+ const replies = [
456
+ smartReply.reply_positive,
457
+ smartReply.reply_neutral,
458
+ smartReply.reply_negative,
459
+ ].filter(Boolean) as string[];
460
+
461
+ return (
462
+ <View style={{ flexDirection: "row", gap: 8, padding: 8 }}>
463
+ {replies.map((r) => (
464
+ <TouchableOpacity
465
+ key={r}
466
+ onPress={() => onPick(r)}
467
+ style={{ paddingHorizontal: 12, paddingVertical: 6, borderRadius: 16, backgroundColor: "#EAEAEA" }}
468
+ >
469
+ <Text>{r}</Text>
470
+ </TouchableOpacity>
471
+ ))}
472
+ </View>
473
+ );
474
+ }
475
+ ```
476
+
477
+ Smart replies are **server-generated** — the AI runs on CometChat's backend and attaches results to messages via the `@injected.extensions.smart-reply` metadata path. Your code just reads it.
478
+
479
+ **Common gotchas:**
480
+ - Replies only appear on incoming messages (the recipient's view), not outgoing. The dashboard generates them when the message lands.
481
+ - The metadata path is nested under `@injected.extensions.smart-reply` — not at the top level. Wrong path = `undefined`.
482
+ - If the user disables smart replies in the dashboard later, your custom UI silently shows nothing (the metadata key is just absent). Add a fallback if "no chip" feels broken.
483
+
484
+ ---
485
+
486
+ ## 6. Core features (no new code, no new install)
487
+
488
+ The following are shipped by default in every CometChat integration — they work from day 1 without any feature-enabling step. Mention them to users who ask "what do I get out of the box?":
489
+
490
+ - **Instant messaging** (text, with real-time delivery)
491
+ - **Media sharing** (images, video, audio, files)
492
+ - **Read receipts** (single tick = sent, double tick = delivered, blue = read)
493
+ - **Typing indicators**
494
+ - **@mentions** (requires `CometChatMentionsFormatter` in `textFormatters`, already in default config)
495
+ - **Reactions** (long-press any message to add emoji reaction)
496
+ - **Replies** (swipe or long-press → Reply)
497
+ - **Edit / delete** own messages
498
+ - **Message info** — sender sees delivery + read timestamps per-recipient
499
+ - **Mark as unread**
500
+ - **Voice messages** (record + send from composer)
501
+ - **Search** (`CometChatSearch` component — scoped or global)
502
+ - **Group management** (create, add members, leave, mute, transfer ownership)
503
+
504
+ If a user reports "X isn't working" for a core feature, it's likely a props issue (e.g., `hideReceipts={true}` accidentally set) or a dashboard setting, not a missing feature.
505
+
506
+ ### 6a — Presence (online / offline) in custom UI
507
+
508
+ Presence indicators appear automatically on avatars in `CometChatConversations`, `CometChatUsers`, and `CometChatGroupMembers` — no setup. For custom UI that needs a specific user's status — e.g. a "Sold by Aria Chen · online now" label on a product screen — subscribe with the SDK directly:
509
+
510
+ ```tsx
511
+ import { useEffect, useState } from "react";
512
+ import { CometChat } from "@cometchat/chat-sdk-react-native";
513
+
514
+ export function useUserPresence(uid: string): "online" | "offline" | "unknown" {
515
+ const [status, setStatus] = useState<"online" | "offline" | "unknown">("unknown");
516
+
517
+ useEffect(() => {
518
+ let cancelled = false;
519
+
520
+ // 1. Initial fetch
521
+ CometChat.getUser(uid).then((u) => {
522
+ if (cancelled) return;
523
+ setStatus(u.getStatus() === "online" ? "online" : "offline");
524
+ });
525
+
526
+ // 2. Live updates
527
+ const listenerId = `presence-${uid}`;
528
+ CometChat.addUserListener(
529
+ listenerId,
530
+ new CometChat.UserListener({
531
+ onUserOnline: (user: CometChat.User) => {
532
+ if (user.getUid() === uid) setStatus("online");
533
+ },
534
+ onUserOffline: (user: CometChat.User) => {
535
+ if (user.getUid() === uid) setStatus("offline");
536
+ },
537
+ }),
538
+ );
539
+
540
+ return () => {
541
+ cancelled = true;
542
+ CometChat.removeUserListener(listenerId);
543
+ };
544
+ }, [uid]);
545
+
546
+ return status;
547
+ }
548
+ ```
549
+
550
+ Use it: `const status = useUserPresence(product.sellerUid);`
551
+
552
+ **Common gotchas:**
553
+ - Presence events only fire for users the current user has interacted with (existing conversation, shared group, etc.). For arbitrary UIDs with no prior interaction, you may need to poll `CometChat.getUser(uid)` instead.
554
+ - `getStatus()` returns `"online"` or `"offline"` only. For a "last seen 5 min ago" label use `getLastActiveAt()` (UNIX timestamp).
555
+ - "Last seen" timestamps are **disabled by default on free-tier apps**. Enable in dashboard → Settings → Chat → Last Seen.
556
+ - Don't forget the cleanup — `removeUserListener` on unmount, or you'll leak listeners across screen re-renders.
557
+
558
+ ---
559
+
560
+ ## 7. Finding a feature's category quickly
561
+
562
+ When a user asks for a feature, use this flow:
563
+
564
+ 1. **Is it in the core-features list (§ 6)?** → Already works. Confirm no `hide*` prop is turning it off.
565
+ 2. **Is it voice / video / call history?** → Calls (§ 3). Package install.
566
+ 3. **Is it polls, stickers, message translation, link preview, collaborative doc / whiteboard, thumbnails?** → Extension (§ 2). Run `cometchat apply-feature <id>`.
567
+ 3a. **Is it smart replies, conversation summary, or conversation starter?** → AI feature (§ 2). Run `cometchat apply-feature <id> --openai-key sk-...`.
568
+ 3b. **Is it Giphy / Stipop / Tenor / Chatwoot / Intercom / Disappearing Messages / Message Shortcuts?** → Dashboard-only (§ 2). User must enter third-party config in https://app.cometchat.com → Extensions.
569
+ 4. **Is it AI agent?** → § 5.
570
+ 5. **Is it custom text formatting, custom message templates, custom slot views, custom theme?** → This is **customization**, not a feature. Route to `cometchat-native-customization` or `cometchat-native-theming`.
571
+ 6. **Not on this list?** → Check `docs/ui-kit/react-native/guide-overview.mdx` + the kit's `src/index.ts` exports. If still nothing, tell the user the feature isn't in the UI Kit; they may need to build it with the SDK directly.
572
+
573
+ ---
574
+
575
+ ## 8. Anti-patterns
576
+
577
+ 1. **Do NOT speculatively install the calls SDK.** WebRTC bloats the app binary by several MB. Install only after the user says they want calls.
578
+
579
+ 2. **Do NOT enable extensions your app doesn't use.** Each enabled extension adds data-fetching overhead and surface area for UI glitches. Turn on what the user asks for.
580
+
581
+ 3. **Do NOT modify UI Kit source to add a feature.** If the feature isn't in the default + extension + calls list, build on top (custom template, custom slot view) — don't fork the kit.
582
+
583
+ 4. **Do NOT wire the call listener per-screen.** It should be once, at the app root. Per-screen registration causes missed incoming calls when the user isn't on the registering screen.
584
+
585
+ 5. **Do NOT skip the `cometchat features enable` step if the CLI is available.** Telling the user to visit the dashboard when the CLI could have flipped the toggle for them is worse UX.
586
+
587
+ 6. **Do NOT forget `pod install` + rebuild after installing calls SDK.** The WebRTC native module won't load otherwise.
588
+
589
+ 7. **Do NOT reference AI tools, streaming, or agent memory from memory.** These APIs change across UIKit minor versions. Query the docs MCP before generating code.
590
+
591
+ ---
592
+
593
+ ## Skill routing reference
594
+
595
+ | Skill | When to route |
596
+ |---|---|
597
+ | `cometchat-native-core` | Init / login / provider chain |
598
+ | `cometchat-native-components` | Component prop reference (for `CometChatCallButtons`, `CometChatOngoingCall`, etc.) |
599
+ | `cometchat-native-placement` | Where the ongoing-call screen, call-logs tab, AI chat screen go |
600
+ | `cometchat-native-expo-patterns` | Expo-specific calls SDK setup (`expo prebuild`) |
601
+ | `cometchat-native-bare-patterns` | Bare RN calls SDK setup (Podfile flags, deployment target) |
602
+ | `cometchat-native-features` | This skill — which features exist + how to enable each |
603
+ | `cometchat-native-theming` | Theming call buttons, reaction colors, extension UI colors |
604
+ | `cometchat-native-customization` | Custom text formatters, custom message templates, event bus |
605
+ | `cometchat-native-push` | Push for calls uses a separate VoIP channel (`APNS_REACT_NATIVE_VOIP`) — see push § 7 |
606
+ | `cometchat-native-testing` | Mocking the calls SDK + incoming-call UI tests — see § 3i |
607
+ | `cometchat-native-production` | Production auth tokens (no feature concern, but the prerequisite for AI agent in prod) |
608
+ | `cometchat-native-troubleshooting` | Incoming call not ringing, extension not showing after enabling, call permissions denied |