{"id":"8da60337-b75c-41ff-aab2-29c0994fe093","shortId":"HZ3yEZ","kind":"skill","title":"cometchat-native-features","tagline":"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.","description":"## Purpose\n\nTeaches 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.\n\n**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.\n\nGround 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.\n\n---\n\n## 1. Feature taxonomy\n\nEvery CometChat feature falls into exactly one of four categories. The category determines the recipe:\n\n| Category | What it means | Example features | How to enable |\n|---|---|---|---|\n| **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` |\n| **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 |\n| **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-…` |\n| **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 |\n| **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 |\n\nReminder — 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\".\n\n---\n\n## 2. Enabling extension and AI features (`apply-feature`)\n\nMost extensions (polls, stickers, translation, link preview, collaborative doc/whiteboard, thumbnails) are pure boolean toggles. Use the CLI:\n\n### Extension features\n\n```bash\ncometchat apply-feature polls --json\ncometchat apply-feature link-preview --json\n```\n\nThe 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).\n\n### AI features (smart replies, conversation summary, conversation starter)\n\nThese need an OpenAI API key. The CLI sets the key + flips the toggle in one call:\n\n```bash\ncometchat apply-feature smart-replies --openai-key sk-...\n```\n\nOnce any AI feature is enabled the key is stored on the app, so subsequent ai-feature applies don't need `--openai-key` repeated.\n\nGet an OpenAI key at https://platform.openai.com/api-keys.\n\n### Response shapes (`--json`)\n\n- `\"status\": \"applied\"` → done. Hard-reload (stop Metro + restart + rebuild if on iOS).\n- `\"status\": \"already-applied\"` → already in the desired state.\n- `\"status\": \"auth-required\"` → `cometchat auth login` first.\n- `\"status\": \"openai-key-required\"` → re-run with `--openai-key sk-…`.\n- `\"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.\n- `\"status\": \"error\"` → surface `next_steps` — includes the dashboard URL as a fallback.\n\n### Dashboard fallback\n\nOnly when the CLI returns `error` or isn't available:\n1. https://app.cometchat.com → your app\n2. Chat & Messaging → Features\n3. Find the extension by name → flip Status ON\n4. Hard-reload the RN app\n\n### What each toggle does\n\n| Extension | UI surface when enabled |\n|---|---|\n| Polls | Polls option in `CometChatMessageComposer`'s attachment Action Sheet |\n| Stickers | Sticker picker in the composer |\n| Smart replies | Chip suggestions above the composer input after an incoming message |\n| Message translation | \"Translate\" option in the message long-press menu |\n| Link preview | Rich-card bubble for URLs in the message list |\n| Collaborative document | Option in composer's Action Sheet; opens a shared doc on tap |\n| Collaborative whiteboard | Option in composer's Action Sheet; opens a shared canvas |\n| Thumbnail generation | Image / video bubbles show thumbnails instead of full-size downloads |\n\n### Gotcha — `auto_wired_in_uikit: false`\n\nA minority of extensions need extra wiring via the `extensions` field on `CometChatUIKit.init()`. The CLI flags this in its success response:\n\n```json\n{\n  \"status\": \"enabled\",\n  \"name\": \"stickers\",\n  \"auto_wired_in_uikit\": false,\n  \"next_steps\": [\n    \"Pass the extension via the `extensions` field on CometChatUIKit.init({ ... })\"\n  ]\n}\n```\n\nIf `auto_wired_in_uikit` is `false`, import the matching `ExtensionsDataSource` from `@cometchat/chat-uikit-react-native` and pass it via the flat `extensions` field:\n\n```tsx\nimport {\n  CometChatUIKit,\n  StickersExtension,\n  PollsExtension,\n} from \"@cometchat/chat-uikit-react-native\";\n\nawait CometChatUIKit.init({\n  appId: APP_ID,\n  region: REGION,\n  authKey: AUTH_KEY,\n  subscriptionType: \"ALL_USERS\",\n  extensions: [new StickersExtension(), new PollsExtension()],   // ← new\n});\n```\n\nQuery the docs MCP for the exact extension class name if you don't remember it — `extensions.mdx` lists all of them.\n\n---\n\n## 3. Calls (package-install)\n\nCalls 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.\n\n### 3a — Install the calls SDK + peer deps\n\n**Expo (managed workflow)**:\n\n```bash\nnpm install @cometchat/calls-sdk-react-native\nnpx expo install \\\n  @react-native-community/netinfo \\\n  react-native-background-timer \\\n  react-native-callstats \\\n  react-native-webrtc\nnpx expo prebuild --clean\n```\n\n**Bare RN**:\n\n```bash\nnpm install \\\n  @cometchat/calls-sdk-react-native \\\n  @react-native-community/netinfo \\\n  react-native-background-timer \\\n  react-native-callstats \\\n  react-native-webrtc\ncd ios && pod install && cd ..\n```\n\n### 3b — Platform permissions (if not already from core integration)\n\n**iOS** — `ios/<App>/Info.plist`:\n\n```xml\n<key>NSCameraUsageDescription</key>\n<string>Camera access for video calls</string>\n<key>NSMicrophoneUsageDescription</key>\n<string>Microphone access for voice and video calls</string>\n```\n\n**Android** — `android/app/src/main/AndroidManifest.xml`:\n\n```xml\n<uses-permission android:name=\"android.permission.INTERNET\" />\n<uses-permission android:name=\"android.permission.CAMERA\" />\n<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\" />\n<uses-permission android:name=\"android.permission.RECORD_AUDIO\" />\n<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />\n```\n\n### 3c — iOS deployment target + build settings\n\nCalls SDK requires iOS 12+ and specific Podfile flags. Add to `ios/Podfile`:\n\n```ruby\npost_install do |installer|\n  installer.pods_project.targets.each do |target|\n    target.build_configurations.each do |config|\n      config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0'\n      config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64 i386'\n      config.build_settings['ENABLE_BITCODE'] = 'NO'\n    end\n  end\nend\n```\n\nAndroid (`android/app/build.gradle`):\n\n```groovy\nandroid {\n    compileSdkVersion 33\n    defaultConfig {\n        minSdkVersion 24\n        targetSdkVersion 33\n    }\n}\n```\n\n### 3d — Register the call listener at app root\n\nThe 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`):\n\n```tsx\nimport React, { useEffect, useRef, useState } from \"react\";\nimport { CometChat } from \"@cometchat/chat-sdk-react-native\";\nimport { CometChatIncomingCall } from \"@cometchat/chat-uikit-react-native\";\n\nfunction CallEventsProvider({ children }: { children: React.ReactNode }) {\n  const [callReceived, setCallReceived] = useState(false);\n  const incomingCall = useRef<CometChat.Call | null>(null);\n  const LISTENER_ID = \"APP_CALL_LISTENER\";\n\n  useEffect(() => {\n    CometChat.addCallListener(\n      LISTENER_ID,\n      new CometChat.CallListener({\n        onIncomingCallReceived: (call) => {\n          incomingCall.current = call;\n          setCallReceived(true);\n        },\n        onOutgoingCallAccepted: (call) => {\n          // navigate to the ongoing-call screen\n        },\n        onOutgoingCallRejected: () => {\n          incomingCall.current = null;\n          setCallReceived(false);\n        },\n        onIncomingCallCancelled: () => {\n          incomingCall.current = null;\n          setCallReceived(false);\n        },\n        onCallEndedMessageReceived: () => {\n          incomingCall.current = null;\n          setCallReceived(false);\n        },\n      })\n    );\n    return () => CometChat.removeCallListener(LISTENER_ID);\n  }, []);\n\n  return (\n    <>\n      {children}\n      {callReceived && incomingCall.current && (\n        <CometChatIncomingCall\n          call={incomingCall.current}\n          onAccept={() => { /* navigate to ongoing-call screen */ }}\n          onDecline={() => setCallReceived(false)}\n        />\n      )}\n    </>\n  );\n}\n```\n\nWrap the app (inside the existing provider chain, below `CometChatProvider`):\n\n```tsx\n<CometChatProvider ...>\n  <CallEventsProvider>\n    <AppNavigator />\n  </CallEventsProvider>\n</CometChatProvider>\n```\n\n### 3e — Call buttons in the message header\n\nOnce the calls SDK is installed, `CometChatMessageHeader` auto-renders voice + video call buttons. To customize (e.g., hide one):\n\n```tsx\n<CometChatMessageHeader\n  user={selectedUser}\n  hideVoiceCallButton={false}\n  hideVideoCallButton={false}\n  AuxiliaryButtonView={(user, group) => (\n    <CometChatCallButtons\n      user={user}\n      group={group}\n      onVoiceCallPress={(session) => navigation.navigate(\"OngoingCall\", { session })}\n      onVideoCallPress={(session) => navigation.navigate(\"OngoingCall\", { session })}\n    />\n  )}\n/>\n```\n\n### 3f — Ongoing call screen\n\nNavigate to a dedicated screen that hosts `CometChatOngoingCall` when a call connects:\n\n```tsx\n// OngoingCallScreen.tsx\nimport { CometChatOngoingCall } from \"@cometchat/chat-uikit-react-native\";\n\nexport function OngoingCallScreen({ route, navigation }: any) {\n  const { session } = route.params;\n  return (\n    <CometChatOngoingCall\n      sessionID={session.sessionId}\n      callType={session.type}   // \"audio\" | \"video\"\n      onCallEnded={() => navigation.goBack()}\n    />\n  );\n}\n```\n\n### 3g — Call logs\n\nA history view of past calls. Typically one tab in a tab-based layout (see `cometchat-native-placement` § 2):\n\n```tsx\nimport { CometChatCallLogs } from \"@cometchat/chat-uikit-react-native\";\n\nexport function CallLogsScreen() {\n  return <CometChatCallLogs onItemPress={(callLog) => openCallDetails(callLog)} />;\n}\n```\n\n### 3h — Verifying calls work\n\n1. Rebuild the app after adding the calls SDK (Expo: `expo run:ios` / `run:android`; bare: `npx react-native run-ios` / `run-android`)\n2. Log in as one user on device A, another on device B\n3. On device A, tap the voice or video call icon in the message header\n4. Device B should show `CometChatIncomingCall` within a few seconds\n5. Accept on B → both devices transition to `CometChatOngoingCall`\n\nIf incoming calls don't show: listener not registered, or the listener ID collides. See `cometchat-native-troubleshooting`.\n\n### 3i — Testing calls in CI\n\nReal WebRTC calls can't run in Jest or Maestro — they need two real\ndevices plus a TURN server. What you CAN test:\n\n- **Call button renders** — mount `CometChatMessageHeader` with a user\n  prop and assert the call `testID` is present (requires the calls SDK\n  import to not crash; mock `@cometchat/calls-sdk-react-native` in\n  your jest setup).\n- **Call listener registration** — spy on `CometChat.addCallListener`\n  from the SDK mock and assert your `registerCallListener()` fires\n  exactly once per mount.\n- **Incoming-call UI** — render `<CometChatIncomingCall call={mockCall} />`\n  with a stubbed `CometChat.Call` object; assert accept/reject buttons\n  are wired.\n\nSee `cometchat-native-testing § 5` for the SDK mock shape (includes a\n`addCallListener` / `removeCallListener` stub) and § 10 for why actual\ncall E2E belongs in manual QA, not Detox/Maestro.\n\n---\n\n## 4. In-call chat (optional, during-call feature)\n\nDuring an active call, users can chat without leaving the call UI. This is a toggle on the ongoing-call component:\n\n```tsx\n<CometChatOngoingCall\n  sessionID={session.sessionId}\n  callType={session.type}\n  callSettingsBuilder={/* ... with enableInCallChat(true) */}\n  onCallEnded={() => navigation.goBack()}\n/>\n```\n\nIn-call chat adds a collapsible chat panel to the call screen. Participants see messages for the duration of the call.\n\n---\n\n## 5. AI Agent (component-swap + dashboard)\n\nThe AI Agent integration adds an AI-powered conversational assistant to your app. Two parts:\n\n### 5a — Dashboard setup\n\n1. https://app.cometchat.com → your app → AI → Agents\n2. Create a new agent (name, system prompt, model)\n3. Assign a UID to the agent (e.g. `ai-support-agent`)\n\nOnce the agent exists in the dashboard, users can message it like any other user.\n\n### 5b — Optional: AI Assistant Chat History UI\n\nThe 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.\n\n```tsx\nimport { CometChatAIAssistantChatHistory } from \"@cometchat/chat-uikit-react-native\";\n\nexport function AIChatScreen({ navigation }: any) {\n  return (\n    <CometChatAIAssistantChatHistory\n      user={loggedInUser}\n      onMessageClicked={(message) => navigation.navigate(\"AIChat\", { message })}\n      onNewChatButtonClick={() => navigation.navigate(\"AIChat\", { new: true })}\n    />\n  );\n}\n```\n\nThe actual AI-chat screen is a regular `CometChatMessageHeader` + `MessageList` + `Composer` composition targeted at the AI agent's UID.\n\n### 5c — AI features beyond the basic agent\n\nSee `ai-assistant-chat-history.mdx` and `guide-ai-agent.mdx` in the docs for:\n- Multi-tool agents (tools registered via `setAIAssistantTools()`)\n- Streaming responses (handled automatically via `CometChatAIAssistantMessageBubble`)\n- Agent memory and persona\n\nThese are advanced topics — query the docs MCP for the current API if the user wants any of them.\n\n### 5d — Smart replies (custom chip UI)\n\nSmart replies is an `ai-feature`. Enable with one CLI call (the first time also sets the OpenAI key on the app):\n\n```bash\ncometchat apply-feature smart-replies --openai-key sk-...\n```\n\nAfter enabling, no code changes are required — `CometChatMessageComposer` automatically renders suggested replies as chips above the input.\n\nFor 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:\n\n```tsx\nimport { TouchableOpacity, View, Text } from \"react-native\";\nimport { CometChat } from \"@cometchat/chat-sdk-react-native\";\n\ninterface SmartReply {\n  reply_positive?: string;\n  reply_neutral?: string;\n  reply_negative?: string;\n}\n\nexport function SmartReplyChips({\n  message,\n  onPick,\n}: {\n  message: CometChat.BaseMessage;\n  onPick: (text: string) => void;\n}) {\n  const metadata = message.getMetadata() as Record<string, unknown> | undefined;\n  const extensions = (metadata?.[\"@injected\"] as Record<string, unknown>)?.[\"extensions\"] as\n    | Record<string, unknown>\n    | undefined;\n  const smartReply = extensions?.[\"smart-reply\"] as SmartReply | undefined;\n  if (!smartReply) return null;\n\n  const replies = [\n    smartReply.reply_positive,\n    smartReply.reply_neutral,\n    smartReply.reply_negative,\n  ].filter(Boolean) as string[];\n\n  return (\n    <View style={{ flexDirection: \"row\", gap: 8, padding: 8 }}>\n      {replies.map((r) => (\n        <TouchableOpacity\n          key={r}\n          onPress={() => onPick(r)}\n          style={{ paddingHorizontal: 12, paddingVertical: 6, borderRadius: 16, backgroundColor: \"#EAEAEA\" }}\n        >\n          <Text>{r}</Text>\n        </TouchableOpacity>\n      ))}\n    </View>\n  );\n}\n```\n\nSmart 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.\n\n**Common gotchas:**\n- Replies only appear on incoming messages (the recipient's view), not outgoing. The dashboard generates them when the message lands.\n- The metadata path is nested under `@injected.extensions.smart-reply` — not at the top level. Wrong path = `undefined`.\n- 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.\n\n---\n\n## 6. Core features (no new code, no new install)\n\nThe 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?\":\n\n- **Instant messaging** (text, with real-time delivery)\n- **Media sharing** (images, video, audio, files)\n- **Read receipts** (single tick = sent, double tick = delivered, blue = read)\n- **Typing indicators**\n- **@mentions** (requires `CometChatMentionsFormatter` in `textFormatters`, already in default config)\n- **Reactions** (long-press any message to add emoji reaction)\n- **Replies** (swipe or long-press → Reply)\n- **Edit / delete** own messages\n- **Message info** — sender sees delivery + read timestamps per-recipient\n- **Mark as unread**\n- **Voice messages** (record + send from composer)\n- **Search** (`CometChatSearch` component — scoped or global)\n- **Group management** (create, add members, leave, mute, transfer ownership)\n\nIf 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.\n\n### 6a — Presence (online / offline) in custom UI\n\nPresence 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:\n\n```tsx\nimport { useEffect, useState } from \"react\";\nimport { CometChat } from \"@cometchat/chat-sdk-react-native\";\n\nexport function useUserPresence(uid: string): \"online\" | \"offline\" | \"unknown\" {\n  const [status, setStatus] = useState<\"online\" | \"offline\" | \"unknown\">(\"unknown\");\n\n  useEffect(() => {\n    let cancelled = false;\n\n    // 1. Initial fetch\n    CometChat.getUser(uid).then((u) => {\n      if (cancelled) return;\n      setStatus(u.getStatus() === \"online\" ? \"online\" : \"offline\");\n    });\n\n    // 2. Live updates\n    const listenerId = `presence-${uid}`;\n    CometChat.addUserListener(\n      listenerId,\n      new CometChat.UserListener({\n        onUserOnline: (user: CometChat.User) => {\n          if (user.getUid() === uid) setStatus(\"online\");\n        },\n        onUserOffline: (user: CometChat.User) => {\n          if (user.getUid() === uid) setStatus(\"offline\");\n        },\n      }),\n    );\n\n    return () => {\n      cancelled = true;\n      CometChat.removeUserListener(listenerId);\n    };\n  }, [uid]);\n\n  return status;\n}\n```\n\nUse it: `const status = useUserPresence(product.sellerUid);`\n\n**Common gotchas:**\n- 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.\n- `getStatus()` returns `\"online\"` or `\"offline\"` only. For a \"last seen 5 min ago\" label use `getLastActiveAt()` (UNIX timestamp).\n- \"Last seen\" timestamps are **disabled by default on free-tier apps**. Enable in dashboard → Settings → Chat → Last Seen.\n- Don't forget the cleanup — `removeUserListener` on unmount, or you'll leak listeners across screen re-renders.\n\n---\n\n## 7. Finding a feature's category quickly\n\nWhen a user asks for a feature, use this flow:\n\n1. **Is it in the core-features list (§ 6)?** → Already works. Confirm no `hide*` prop is turning it off.\n2. **Is it voice / video / call history?** → Calls (§ 3). Package install.\n3. **Is it polls, stickers, message translation, link preview, collaborative doc / whiteboard, thumbnails?** → Extension (§ 2). Run `cometchat apply-feature <id>`.\n3a. **Is it smart replies, conversation summary, or conversation starter?** → AI feature (§ 2). Run `cometchat apply-feature <id> --openai-key sk-...`.\n3b. **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.\n4. **Is it AI agent?** → § 5.\n5. **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`.\n6. **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.\n\n---\n\n## 8. Anti-patterns\n\n1. **Do NOT speculatively install the calls SDK.** WebRTC bloats the app binary by several MB. Install only after the user says they want calls.\n\n2. **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.\n\n3. **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.\n\n4. **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.\n\n5. **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.\n\n6. **Do NOT forget `pod install` + rebuild after installing calls SDK.** The WebRTC native module won't load otherwise.\n\n7. **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.\n\n---\n\n## Skill routing reference\n\n| Skill | When to route |\n|---|---|\n| `cometchat-native-core` | Init / login / provider chain |\n| `cometchat-native-components` | Component prop reference (for `CometChatCallButtons`, `CometChatOngoingCall`, etc.) |\n| `cometchat-native-placement` | Where the ongoing-call screen, call-logs tab, AI chat screen go |\n| `cometchat-native-expo-patterns` | Expo-specific calls SDK setup (`expo prebuild`) |\n| `cometchat-native-bare-patterns` | Bare RN calls SDK setup (Podfile flags, deployment target) |\n| `cometchat-native-features` | This skill — which features exist + how to enable each |\n| `cometchat-native-theming` | Theming call buttons, reaction colors, extension UI colors |\n| `cometchat-native-customization` | Custom text formatters, custom message templates, event bus |\n| `cometchat-native-push` | Push for calls uses a separate VoIP channel (`APNS_REACT_NATIVE_VOIP`) — see push § 7 |\n| `cometchat-native-testing` | Mocking the calls SDK + incoming-call UI tests — see § 3i |\n| `cometchat-native-production` | Production auth tokens (no feature concern, but the prerequisite for AI agent in prod) |\n| `cometchat-native-troubleshooting` | Incoming call not ringing, extension not showing after enabling, call permissions denied |","tags":["cometchat","native","features","skills","agent-skills","ai-agent","chat","claude-code","cursor","messaging","nextjs","react"],"capabilities":["skill","source-cometchat","skill-cometchat-native-features","topic-agent-skills","topic-ai-agent","topic-chat","topic-claude-code","topic-cometchat","topic-cursor","topic-messaging","topic-nextjs","topic-react","topic-react-native","topic-ui-kit"],"categories":["cometchat-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/cometchat/cometchat-skills/cometchat-native-features","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add cometchat/cometchat-skills","source_repo":"https://github.com/cometchat/cometchat-skills","install_from":"skills.sh"}},"qualityScore":"0.463","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 27 github stars · SKILL.md body (24,595 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T19:04:54.547Z","embedding":null,"createdAt":"2026-05-07T13:05:14.840Z","updatedAt":"2026-05-18T19:04:54.547Z","lastSeenAt":"2026-05-18T19:04:54.547Z","tsv":"'/api-keys.':505 '/info.plist':965 '/netinfo':907,935 '1':114,613,1329,1637,2142,2362,2524,2700 '10':1533 '12':994,2014 '12.0':1018 '16':2018 '2':361,617,1310,1355,1643,2377,2544,2569,2587,2612,2725 '24':1043 '3':621,851,1368,1652,2552,2555,2756 '33':1040,1045 '3a':886,2575 '3b':954,2597 '3c':984 '3d':1046 '3e':1194 '3f':1246 '3g':1287 '3h':1325 '3i':1421,3046 '4':630,1383,1545,2623,2791 '5':1393,1521,1611,2462,2628,2629,2826 '5.3.3':112 '5a':1634 '5b':1679 '5c':1766 '5d':1818 '6':2016,2119,2533,2660,2860 '6a':2284 '7':2507,2879,3031 '8':2001,2003,2696 'absent':2110 'accept':1394 'accept/reject':1512 'access':969,975 'accident':2274 'across':2502,2894 'action':145,555,653,702,716 'activ':1557 'actual':1536,1747 'ad':1334 'add':42,345,860,999,1073,1593,1622,2111,2205,2247,2738,2764 'addcalllisten':1529 'addit':263,870 'advanc':1801 'agent':26,316,1613,1620,1642,1647,1658,1663,1666,1763,1772,1784,1795,2627,2887,3062 'ago':2464 'ai':25,217,220,315,365,435,474,488,1612,1619,1625,1641,1661,1681,1698,1715,1749,1762,1767,1829,2029,2585,2626,2883,2945,3061 'ai-assistant-chat-history.mdx':109,1774 'ai-chat':1697,1748 'ai-featur':487,1828 'ai-pow':1624 'ai-support-ag':1660 'aichat':1739,1743 'aichatscreen':1729 'alreadi':93,142,524,526,959,2194,2534 'already-appli':523 'also':1839 'android':981,1035,1038,1343,1354 'android/app/build.gradle':1036 'android/app/src/main/androidmanifest.xml':982 'anoth':1364 'anti':2698 'anti-pattern':2697 'api':186,226,447,1810,2892 'apn':3025 'app':216,230,408,420,484,616,636,814,882,1052,1078,1123,1185,1332,1631,1640,1692,1846,2481,2711,2731,2807 'app-id':419 'app-sid':881 'app.cometchat.com':614,1638,2621 'app.tsx':1082 'appear':2055,2293 'appid':813 'appli':210,249,368,392,398,416,463,490,510,525,1850,2573,2591 'apply-featur':209,248,367,391,397,462,1849,2572,2590 'arbitrari':2438 'arch':1022 'area':2745 'aria':2318 'arm64':1025 'ask':2154,2517,2754 'assert':1459,1490,1511 'assign':1653 'assist':1628,1682 'attach':652,2036 'audio':1283,2175 'auth':430,533,536,819,3052 'auth-requir':532 'authkey':818 'auto':190,274,736,767,784,1209 'auto-detect':273 'auto-rend':1208 'auto-wir':189 'automat':1792,1867,2294 'auxiliarybuttonview':1228 'avail':612,2839 'avatar':2296 'await':811 'b':1367,1385,1396 'backend':178,219,2034 'background':877,911,939 'background-tim':876 'backgroundcolor':2019 'bare':86,925,1344,2965,2967 'base':90,152,1303 'bash':389,460,896,927,1847 'basic':1771 'bearer':423 'behav':360 'belong':1539 'beyond':1769 'biggest':859 'binari':2712 'bitcod':1030 'bloat':2709 'blue':2185 'boolean':177,382,1992 'borderradius':2017 'box':2162 'broken':2118 'bubbl':689,726,1886 'build':988,2690,2778 'bus':3012 'button':1196,1214,1450,1513,2995 'call':10,29,103,240,283,459,852,856,889,972,980,990,1049,1057,1071,1124,1133,1135,1139,1145,1171,1178,1195,1203,1213,1248,1260,1288,1295,1327,1336,1377,1404,1423,1428,1449,1461,1467,1479,1500,1504,1537,1548,1553,1558,1565,1575,1591,1600,1610,1835,2549,2551,2706,2724,2776,2796,2816,2869,2939,2942,2957,2969,2994,3019,3038,3042,3070,3078 'call-log':2941 'calleventsprovid':1105 'calling-integration.mdx':102 'calllog':1322,1324 'calllogsscreen':1318 'callreceiv':1110,1168 'callsettingsbuild':1583 'callstat':879,916,944 'calltyp':1281,1581 'camera':968 'cancel':2360,2370,2405 'canva':721 'card':688 'catalog':6 'categori':126,128,132,2512 'caus':2813 'cd':949,953 'certain':1889 'chain':1190,2919 'chang':353,1863,2893 'channel':3024 'chat':30,317,618,1549,1561,1592,1596,1683,1699,1706,1720,1750,2486,2946 'chatwoot':564,2603 'check':2665 'chen':2319 'children':1106,1107,1167 'chip':663,1822,1872,1882,1912,2116 'ci':1425 'class':838 'classifi':53 'claud':39 'clean':924 'cleanup':2493 'cli':180,231,386,405,450,606,755,1834,2837,2849 'code':1862,2047,2124,2904 'collabor':20,202,204,377,696,710,2564 'collaps':1595 'collid':1415 'color':2997,3000 'cometchat':2,49,70,74,78,84,118,208,247,339,349,390,396,415,429,461,535,1097,1307,1418,1518,1848,1923,2032,2136,2339,2571,2589,2652,2657,2831,2913,2921,2932,2950,2963,2977,2990,3002,3014,3033,3048,3066 'cometchat-native-bare-pattern':83,2962 'cometchat-native-compon':73,2920 'cometchat-native-cor':69,2912 'cometchat-native-custom':338,2651,3001 'cometchat-native-expo-pattern':77,2949 'cometchat-native-featur':1,2976 'cometchat-native-plac':1306,2931 'cometchat-native-product':3047 'cometchat-native-push':3013 'cometchat-native-test':1517,3032 'cometchat-native-them':2656,2989 'cometchat-native-troubleshoot':1417,3065 'cometchat.addcalllistener':1127,1484 'cometchat.adduserlistener':2384 'cometchat.basemessage':1943 'cometchat.call':1117,1509 'cometchat.calllistener':1131 'cometchat.getuser':2365,2449 'cometchat.removecalllistener':1163 'cometchat.removeuserlistener':2407 'cometchat.user':2390,2398 'cometchat.userlistener':2387 'cometchat/calls-sdk-react-native':284,868,899,930,1474 'cometchat/chat-sdk-react-native':1099,1925,2341 'cometchat/chat-uikit-react-native':111,795,810,1103,1267,1315,1726 'cometchat/state.json':411 'cometchataiassistantchathistori':1690,1724,1733 'cometchataiassistantmessagebubbl':1794 'cometchatcallbutton':1231,2928 'cometchatcalllog':1313,1320 'cometchatconvers':2298 'cometchatgroupmemb':2301 'cometchatincomingcal':1101,1170,1388,1503 'cometchatmentionsformatt':2191 'cometchatmessagecompos':174,650,1866 'cometchatmessagehead':172,1207,1221,1453,1755 'cometchatmessagelist':173 'cometchatongoingcal':1257,1265,1278,1401,1578,2929 'cometchatprovid':1192 'cometchatsearch':2239 'cometchatuikit':806 'cometchatuikit.init':753,782,812 'cometchatus':2299 'common':2051,2418 'communiti':906,934 'compilesdkvers':1039 'compon':76,153,292,300,322,1576,1615,1712,2240,2923,2924 'component-swap':291,1614 'compos':660,667,700,714,1757,2237 'composit':1758 'concern':3056 'config':582,1012,2197,2619 'config.build':1013,1019,1027 'confirm':2536 'confus':329 'connect':1261 'const':1109,1114,1120,1274,1948,1956,1970,1983,2350,2380,2414 'convers':243,245,439,441,1627,1716,1890,2433,2580,2583 'core':72,961,2120,2263,2530,2915 'core-featur':2529 'correct':64 'could':2850 'coverag':336 'crash':1472 'creat':1644,2246 'current':1809,2427 'custom':303,305,310,312,332,341,351,1216,1821,1878,1885,2100,2289,2305,2632,2635,2638,2641,2645,2654,2781,2783,3004,3005,3008 'dashboard':185,558,596,601,1617,1635,1670,2066,2097,2278,2484,2610,2846 'dashboard-on':557,2609 'data':1902,2740 'data-fetch':2739 'day':2141 'dedic':1253,1696 'default':141,2133,2196,2476,2774 'defaultconfig':1041 'delet':2216 'deliv':2184 'deliveri':2170,2223 'deni':3080 'dep':269,892 'deploy':986,1016,2974 'design':1897 'desir':529 'detect':275 'determin':129 'detox/maestro':1544 'devic':1362,1366,1370,1384,1398,1440 'direct':2331,2695 'disabl':2092,2474 'disappear':570,2605 'disappearing-messag':569 'distinct':1702 'doc':21,707,832,1779,1805,2565,2900 'doc/whiteboard':378 'docs/ui-kit/react-native/core-features.mdx':101 'docs/ui-kit/react-native/guide-overview.mdx':2666 'document':205,697 'doesn':2732 'done':511 'doubl':2182 'download':734 'durat':1607 'during-cal':1551 'e.g':1217,1659,1880,2271,2314 'e2e':1538 'eaeaea':2020 'edit':2215 'edit/delete':167 'emoji':308,2206 'enabl':140,195,362,477,645,764,1029,1831,1860,2147,2482,2728,2736,2833,2987,3077 'enableincallchat':1585 'end':1032,1033,1034 'enter':2615 'entri':1700 'error':590,608 'etc':2436,2930 'event':1072,2421,3011 'everi':117,2135 'exact':122,836,1494 'exampl':136 'exclud':1021 'exist':94,356,1188,1667,2432,2984 'explicit':422 'expo':80,893,901,922,1084,1338,1339,2952,2955,2960 'expo-specif':2954 'export':113,1268,1316,1689,1727,1937,2342,2671 'extens':14,175,363,371,387,624,641,744,750,776,779,802,824,837,1901,1957,1964,1972,2568,2622,2729,2737,2775,2998,3073 'extensions.mdx':107,846 'extensionsdatasourc':793 'extra':746 'fall':120 'fallback':600,602,2113 'fals':740,771,789,1113,1151,1156,1161,1182,1225,1227,2361 'featur':4,5,43,55,96,115,119,137,193,211,218,250,347,357,366,369,388,393,399,436,464,475,489,560,620,862,1554,1768,1830,1851,2121,2146,2264,2283,2510,2520,2531,2574,2586,2592,2648,2679,2766,2769,2832,2979,2983,3055 'feature-en':2145 'feel':2117 'fetch':2364,2741 'field':751,780,803 'file':2176 'filter':1991 'find':622,2508 'fire':1493,2423 'first':88,538,1837 'flag':756,998,2973 'flat':801 'flexdirect':1998 'flip':181,235,454,627,2852 'flow':2523 'follow':2129 'forget':2491,2863 'fork':2788 'format':2634 'formatt':307,3007 'four':59,125 'free':2479 'free-tier':2478 'full':732 'full-siz':731 'function':1104,1269,1317,1728,1938,2343 'gap':2000 'generat':207,723,2027,2067,2903 'get':498,2158 'getlastactiveat':2467 'getstatus':2452 'giphi':561,2600 'give':62 'glitch':2748 'global':2243 'go':2948 'goe':413 'gotcha':735,2052,2419 'groovi':1037 'ground':99 'group':1230,1234,1235,2244,2435 'guide-ai-agent.mdx':108,1776 'handl':1791 'hard':213,513,632 'hard-reload':212,512,631 'header':1200,1382 'hide':1218,2538 'hidereceipt':2272 'hidevideocallbutton':1226 'hidevoicecallbutton':1224 'histori':318,1291,1684,2550 'host':1256 'human':1709 'i386':1026 'icon':1378 'id':409,421,815,1122,1129,1165,1414 'imag':724,2173 'import':790,805,1089,1096,1100,1264,1312,1469,1723,1914,1922,2333,2338 'in-cal':27,1546,1589 'includ':594,1527 'incom':671,1056,1403,1499,1906,2057,2815,3041,3069 'incoming-cal':1055,1498,3040 'incoming-call.mdx':105 'incomingcal':1115 'incomingcall.current':1134,1148,1153,1158,1169,1172 'indic':157,2188,2292 'info':169,2220 'init':280,2916 'initi':2363 'inject':1959 'injected.extensions.smart':2042,2079 'inlin':1881 'input':668,1875 'insid':1186,1883 'instal':34,260,261,286,288,855,887,898,902,929,952,1004,1006,1206,2127,2554,2704,2716,2865,2868 'installer.pods_project.targets.each':1007 'instant':154,2163 'instead':729,2451 'integr':52,91,962,1621,2137 'interact':2430,2443 'intercom':565,2604 'interfac':1926 'io':289,521,950,963,964,985,993,1341,1351 'ios/podfile':1001 'iphoneo':1015 'iphonesimul':1024 'isn':610,2258,2680,2770,2820 'issu':2270 'jest':1433,1477 'json':395,403,508,762 'key':227,234,256,448,453,470,479,496,501,542,550,820,1843,1857,2007,2107,2595 'keychain':428 'kit':150,188,272,299,1688,2668,2685,2761,2790 'label':2322,2465 'land':2072 'last':2460,2470,2487 'later':2098 'layer':97 'layout':1304 'layout.tsx':1087 'leak':2500 'leav':1563,2249 'let':2359 'level':2085 'like':1675,2267 'link':18,200,375,401,684,2562 'link-preview':400 'list':695,847,2532,2664,2777 'listen':884,1050,1067,1121,1125,1128,1164,1408,1413,1480,2501,2797 'listenerid':2381,2385,2408 'live':2378 'll':2499 'load':2877 'log':1289,1356,2943 'loggedinus':1735 'login':431,537,2917 'long':681,2200,2212 'long-press':680,2199,2211 'look':358 'machin':434 'maestro':1435 'manag':894,2245 'manual':554,588,1541 'manual-action-requir':553 'mark':2229 'match':792,1895 'may':2445,2687 'mayb':266 'mb':2715 'mcp':833,1806,2901 'mdx':104 'mean':135 'media':165,2171 'member':2248 'memori':1796,2888,2890 'mention':164,2149,2189 'menu':683 'messag':155,162,168,198,313,567,571,619,672,673,679,694,1199,1381,1604,1673,1737,1740,1907,1940,1942,2039,2058,2071,2164,2203,2218,2219,2233,2560,2606,2607,2636,3009 'message-shortcut':566 'message.getmetadata':1950 'messagelist':1756 'metadata':1949,1958,2044,2074,2106 'metro':516 'microphon':974 'min':2463 'minor':742,2896 'minsdkvers':1042 'miss':2282,2814 'mock':1473,1488,1525,3036 'mockcal':1505 'model':1651 'modifi':2759 'modul':873,2874 'mount':1452,1497 'multi':1782 'multi-tool':1781 'must':92,2614 'mute':2250 'name':626,765,839,1648 'nativ':3,9,51,71,75,79,85,267,340,872,905,910,915,919,933,938,943,947,1308,1348,1419,1519,1921,2653,2658,2873,2914,2922,2933,2951,2964,2978,2991,3003,3015,3027,3034,3049,3067 'navig':1140,1174,1250,1272,1730 'navigation.goback':1286,1588 'navigation.navigate':1238,1243,1738,1742 'need':146,444,493,578,745,1437,2308,2446,2688 'negat':1935,1990 'nest':2077 'netinfo':875 'neutral':1932,1988 'new':321,825,827,829,1130,1646,1719,1744,2123,2126,2386 'next':279,574,592,772 'noth':2104,2674 'npm':264,285,897,928 'npx':900,921,1345 'nscamerausagedescript':967 'nsmicrophoneusagedescript':973 'null':1118,1119,1149,1154,1159,1982 'object':1510 'offlin':2287,2348,2355,2376,2403,2456 'onaccept':1173 'oncallend':1285,1587 'oncallendedmessagereceiv':1157 'ondeclin':1180 'one':57,123,239,458,1219,1297,1359,1833 'ongo':1144,1177,1247,1574,2938 'ongoing-cal':1143,1176,1573,2937 'ongoingcal':1239,1244 'ongoingcallscreen':1270 'ongoingcallscreen.tsx':1263 'onincomingcallcancel':1152 'onincomingcallreceiv':1132 'onitempress':1321 'onlin':2286,2320,2347,2354,2374,2375,2395,2454 'onmessageclick':1736 'onnewchatbuttonclick':1741 'onoutgoingcallaccept':1138 'onoutgoingcallreject':1147 'onpick':1941,1944,2010 'onpress':2009 'onuserofflin':2396 'onuseronlin':2388 'onvideocallpress':1241 'onvoicecallpress':1236 'open':704,718 'openai':225,255,446,469,495,500,541,549,1842,1856,2594 'openai-key':254,468,494,548,1855,2593 'openai-key-requir':540 'opencalldetail':1323 'option':648,676,698,712,1550,1680 'os':427 'otherwis':2878 'outgo':2064 'outgoing-call.mdx':106 'overhead':2742 'ownership':2252 'packag':259,265,277,854,869,2553 'package-instal':258,853 'pad':2002 'paddinghorizont':2013 'paddingvert':2015 'panel':1597 'part':1633 'parti':581,2618 'particip':1602 'pass':323,418,774,797 'past':1294,1714 'path':2045,2075,2087 'pattern':81,87,2699,2953,2966 'peer':268,871,891 'per':334,433,1496,2227,2799,2810 'per-recipi':2226 'per-screen':2798,2809 'per-skill-coverag':333 'permiss':956,3079 'persona':1798 'pick':1069 'picker':657 'placement':1309,2934 'platform':955 'platform.openai.com':504 'platform.openai.com/api-keys.':503 'plus':1441 'pod':287,951,2864 'podfil':997,2972 'point':1701 'poll':15,196,372,394,646,647,2448,2558 'pollsextens':808,828 'posit':1929,1986 'post':1003 'power':1626 'prebuild':923,2961 'prerequisit':3059 'presenc':2285,2291,2382,2420 'present':1464 'press':682,2201,2213 'preview':19,201,376,402,685,2563 'prior':2442 'prod':3064 'product':2325,3050,3051 'product.selleruid':2417 'prompt':1650 'prop':325,1457,2269,2539,2925 'provid':587,1189,2918 'pure':176,381 'purpos':37 'push':3016,3017,3030 'qa':1542 'queri':830,1803,2898 'quick':2513 'r':2005,2008,2011,2021 're':545,2505 're-rend':2504 're-run':544 'react':8,50,904,909,914,918,932,937,942,946,1090,1095,1347,1920,2337,3026 'react-nat':1346,1919 'react-native-background-tim':908,936 'react-native-callstat':913,941 'react-native-commun':903,931 'react-native-webrtc':917,945 'react.reactnode':1108 'reaction':160,2198,2207,2996 'read':68,158,406,1899,2049,2177,2186,2224 'real':1426,1439,2168 'real-tim':2167 'rebuild':290,518,1330,2866 'receipt':159,2178 'recip':65,131 'recipi':2060,2228 'record':1952,1961,1966,2234 'refer':2882,2907,2926 'region':816,817 'regist':1047,1065,1410,1786,2824 'registercalllisten':1492 'registr':1481,2812 'regular':1705,1754 'reload':214,514,633 'rememb':844 'remind':326 'removecalllisten':1530 'removeuserlisten':2494 'render':171,1210,1451,1502,1868,1909,2506 'repeat':497 'replac':294 'repli':24,163,242,253,438,467,662,1820,1825,1854,1870,1928,1931,1934,1975,1984,2023,2043,2053,2080,2094,2208,2214,2579 'replies.map':2004 'report':2256 'requir':223,534,543,556,865,992,1465,1865,2190 'respons':506,761,1790 'restart':517 'result':2037 'return':607,1162,1166,1277,1319,1732,1981,1995,2371,2404,2410,2453 'rich':687 'rich-card':686 'ring':3072 'rn':412,635,926,2968 'root':1053,1079,2808 'rout':1271,2649,2906,2911 'route.params':1276 'router':1085 'row':1999 'rubi':1002 'run':546,1340,1342,1350,1353,1431,2030,2570,2588 'run-android':1352 'run-io':1349 'say':2721 'scope':2241 'screen':1146,1179,1249,1254,1601,1751,2326,2503,2800,2811,2825,2940,2947 'sdk':12,890,991,1023,1204,1337,1468,1487,1524,2330,2694,2707,2870,2958,2970,3039 'search':2238 'second':1392 'see':1305,1416,1516,1603,1773,2222,3029,3045 'seen':2461,2471,2488 'selectedus':1223 'send':2235 'sender':2221 'sent':2181 'separ':11,867,3022 'server':1444,2026 'server-gener':2025 'session':1237,1240,1242,1245,1275 'session.sessionid':1280,1580 'session.type':1282,1582 'sessionid':1279,1579 'set':232,451,989,1014,1020,1028,1840,2275,2279,2485 'setaiassistanttool':1788 'setcallreceiv':1111,1136,1150,1155,1160,1181 'setstatus':2352,2372,2394,2402 'setup':885,1478,1636,2303,2959,2971 'sever':2714 'shape':507,1526 'share':706,720,2172,2434 'sheet':654,703,717 'ship':147,350,2131 'shortcut':309,568,2608 'show':727,1060,1387,1407,1713,2103,3075 'side':883 'silent':2102 'singl':2179 'size':733 'sk':257,471,551,1858,2596 'skill':335,343,2905,2908,2981 'skill-cometchat-native-features' 'skip':2829 'slot':2639,2784 'smart':23,241,252,437,466,661,1819,1824,1853,1974,2022,2093,2578 'smart-repli':251,465,1852,1973 'smartrepli':1927,1971,1977,1980 'smartreply.reply':1985,1987,1989 'smartreplychip':1939 'sold':2316 'sourc':2762 'source-cometchat' 'specif':996,2310,2956 'specul':2703 'spi':1482 'src/index.ts':2670 'starter':246,442,2584 'state':530 'status':509,522,531,539,552,589,628,763,2313,2351,2411,2415 'step':575,593,773,863,2148,2834 'sticker':16,197,373,655,656,766,2559 'stickersextens':807,826 'still':2673 'stipop':562,2601 'stop':515 'store':481 'straight':1903 'stream':1789,2885 'string':1930,1933,1936,1946,1953,1962,1967,1994,2346 'stub':1508,1531 'style':1893,1997,2012 'subscrib':2327 'subscriptiontyp':821 'subsequ':486 'success':760 'suggest':664,1869 'summari':244,440,2581 'support':1662 'surfac':572,591,643,2744 'swap':36,293,1616 'swipe':2209 'system':1649,1898 'tab':1298,1302,2944 'tab-bas':1301 'tag':311 'tap':709,1372 'target':987,1009,1017,1759,2975 'target.build_configurations.each':1010 'targetsdkvers':1044 'taxonomi':116 'teach':38 'tell':2675,2840 'templat':314,2637,2782,3010 'tenor':563,2602 'test':1422,1448,1520,3035,3044 'testid':1462 'text':306,1917,1945,2165,2633,3006 'textformatt':2193 'theme':2642,2659,2992,2993 'third':580,2617 'third-parti':579,2616 'thumbnail':206,379,722,728,2567 'tick':2180,2183 'tier':2480 'time':1838,2169 'timer':878,912,940 'timestamp':2225,2469,2472 'toggl':33,179,221,237,383,456,639,1570,2854 'token':3053 'tool':1783,1785,2884 'top':45,2084,2780 'topic':1802 'topic-agent-skills' 'topic-ai-agent' 'topic-chat' 'topic-claude-code' 'topic-cometchat' 'topic-cursor' 'topic-messaging' 'topic-nextjs' 'topic-react' 'topic-react-native' 'topic-ui-kit' 'touchableopac':1915,2006 'transfer':2251 'transit':1399 'translat':17,199,374,674,675,2561 'trigger':1721 'troubleshoot':1420,3068 'true':1137,1586,1745,2273,2406 'truth':100 'tsx':804,1088,1193,1220,1262,1311,1577,1722,1913,2332 'turn':1443,2541,2749 'two':1438,1632 'type':60,156,1891,2187 'typic':1080,1296 'u':2368 'u.getstatus':2373 'ui':187,271,298,642,1058,1501,1566,1685,1687,1823,1879,2101,2290,2306,2684,2747,2760,2999,3043 'uid':1655,1765,2345,2366,2383,2393,2401,2409,2439,2450 'uikit':739,770,787,2895 'undefin':1955,1969,1978,2088 'unix':2468 'unknown':1954,1963,1968,2349,2356,2357 'unmount':2496 'unread':2231 'updat':2379 'upload':166 'url':597,691 'use':384,2412,2466,2521,2734,3020 'useeffect':1091,1126,2334,2358 'user':584,823,1222,1229,1232,1233,1360,1456,1559,1671,1678,1710,1734,1813,2091,2152,2255,2311,2389,2397,2425,2428,2516,2613,2677,2720,2753,2819,2842 'user.getuid':2392,2400 'useref':1092,1116 'usest':1093,1112,2335,2353 'useuserpres':2344,2416 'ux':2859 've':1064 'verbatim':576 'verifi':1326 'version':304,2897 'via':183,324,748,777,799,1787,1793,2040 'video':282,725,971,979,1212,1284,1376,2174,2548 'view':1292,1916,1996,2062,2640,2785 'visit':2844 'voic':281,977,1211,1374,2232,2547 'void':1947 'voip':3023,3028 'want':1694,1814,2723 'webrtc':13,874,920,948,1427,2708,2872 'whiteboard':22,203,711,2566 'wire':191,737,747,768,785,1515,2794 'within':1389 'without':1562,2143 'won':2875 'work':48,1328,2139,2260,2535 'workflow':895 'wors':2858 'wrap':296,1183 'write':319 'wrong':2086 'x':2257 'xml':966,983","prices":[{"id":"fd70fda4-33c7-4764-9182-0f3101241202","listingId":"8da60337-b75c-41ff-aab2-29c0994fe093","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"cometchat","category":"cometchat-skills","install_from":"skills.sh"},"createdAt":"2026-05-07T13:05:14.840Z"}],"sources":[{"listingId":"8da60337-b75c-41ff-aab2-29c0994fe093","source":"github","sourceId":"cometchat/cometchat-skills/cometchat-native-features","sourceUrl":"https://github.com/cometchat/cometchat-skills/tree/main/skills/cometchat-native-features","isPrimary":false,"firstSeenAt":"2026-05-07T13:05:14.840Z","lastSeenAt":"2026-05-18T19:04:54.547Z"}],"details":{"listingId":"8da60337-b75c-41ff-aab2-29c0994fe093","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"cometchat","slug":"cometchat-native-features","github":{"repo":"cometchat/cometchat-skills","stars":27,"topics":["agent-skills","ai-agent","chat","claude-code","cometchat","cursor","messaging","nextjs","react","react-native","ui-kit"],"license":null,"html_url":"https://github.com/cometchat/cometchat-skills","pushed_at":"2026-05-18T05:04:24Z","description":"Add CometChat chat to any React, Next.js, React Native, Angular, Android, iOS, or Flutter project through your AI coding agent. Works with Claude Code, Cursor, Codex, VS Code Copilot, Windsurf, Cline, Kiro, and 50+ more agents.","skill_md_sha":"a7daab20aa4b5765291f9df34ed8c5c154353255","skill_md_path":"skills/cometchat-native-features/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/cometchat/cometchat-skills/tree/main/skills/cometchat-native-features"},"layout":"multi","source":"github","category":"cometchat-skills","frontmatter":{"name":"cometchat-native-features","license":"MIT","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.","compatibility":"Node.js >=18; React Native >=0.70; @cometchat/chat-uikit-react-native ^5"},"skills_sh_url":"https://skills.sh/cometchat/cometchat-skills/cometchat-native-features"},"updatedAt":"2026-05-18T19:04:54.547Z"}}