@cometchat/skills 4.3.0 → 4.4.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.
Files changed (233) hide show
  1. package/LICENSE +21 -0
  2. package/bin/install.js +27 -0
  3. package/package.json +14 -1
  4. package/skills/cometchat/SKILL.md +233 -69
  5. package/skills/cometchat/references/asking-questions.md +48 -0
  6. package/skills/cometchat-a11y/SKILL.md +3 -2
  7. package/skills/cometchat-android-v5/SKILL.md +2 -1
  8. package/skills/cometchat-android-v5-calls/SKILL.md +36 -22
  9. package/skills/cometchat-android-v5-calls/references/README.md +1 -1
  10. package/skills/cometchat-android-v5-calls/references/add-calls-to-existing-chat.md +7 -5
  11. package/skills/cometchat-android-v5-calls/references/audio-controls.md +4 -4
  12. package/skills/cometchat-android-v5-calls/references/call-layouts.md +33 -25
  13. package/skills/cometchat-android-v5-calls/references/call-session.md +2 -2
  14. package/skills/cometchat-android-v5-calls/references/custom-ui.md +5 -5
  15. package/skills/cometchat-android-v5-calls/references/event-listeners.md +2 -2
  16. package/skills/cometchat-android-v5-calls/references/idle-timeout.md +20 -14
  17. package/skills/cometchat-android-v5-calls/references/in-call-chat.md +1 -1
  18. package/skills/cometchat-android-v5-calls/references/migration-v4-to-v5.md +43 -27
  19. package/skills/cometchat-android-v5-calls/references/participant-management.md +3 -3
  20. package/skills/cometchat-android-v5-calls/references/raise-hand.md +25 -19
  21. package/skills/cometchat-android-v5-calls/references/recording.md +2 -2
  22. package/skills/cometchat-android-v5-calls/references/ringing-integration.md +1 -1
  23. package/skills/cometchat-android-v5-calls/references/screen-sharing.md +5 -9
  24. package/skills/cometchat-android-v5-calls/references/session-settings.md +3 -3
  25. package/skills/cometchat-android-v5-calls/references/setup.md +1 -1
  26. package/skills/cometchat-android-v5-calls/references/share-invite.md +9 -4
  27. package/skills/cometchat-android-v5-calls/references/video-controls.md +4 -4
  28. package/skills/cometchat-android-v5-calls/references/voip-calling.md +2 -2
  29. package/skills/cometchat-android-v5-components/SKILL.md +4 -3
  30. package/skills/cometchat-android-v5-core/SKILL.md +5 -3
  31. package/skills/cometchat-android-v5-customization/SKILL.md +171 -7
  32. package/skills/cometchat-android-v5-extensions/SKILL.md +7 -4
  33. package/skills/cometchat-android-v5-features/SKILL.md +5 -4
  34. package/skills/cometchat-android-v5-placement/SKILL.md +2 -1
  35. package/skills/cometchat-android-v5-production/SKILL.md +2 -1
  36. package/skills/cometchat-android-v5-push/SKILL.md +2 -3
  37. package/skills/cometchat-android-v5-testing/SKILL.md +2 -1
  38. package/skills/cometchat-android-v5-theming/SKILL.md +2 -1
  39. package/skills/cometchat-android-v5-troubleshooting/SKILL.md +3 -2
  40. package/skills/cometchat-android-v6/SKILL.md +2 -1
  41. package/skills/cometchat-android-v6-builder-settings/SKILL.md +11 -7
  42. package/skills/cometchat-android-v6-calls/SKILL.md +79 -18
  43. package/skills/cometchat-android-v6-calls/references/advanced-features.md +87 -0
  44. package/skills/cometchat-android-v6-calls/references/call-layouts.md +24 -15
  45. package/skills/cometchat-android-v6-calls/references/call-session.md +2 -2
  46. package/skills/cometchat-android-v6-calls/references/device-management.md +17 -16
  47. package/skills/cometchat-android-v6-calls/references/idle-timeout.md +7 -4
  48. package/skills/cometchat-android-v6-calls/references/in-call-chat.md +13 -8
  49. package/skills/cometchat-android-v6-calls/references/raise-hand.md +6 -4
  50. package/skills/cometchat-android-v6-compose-components/SKILL.md +52 -29
  51. package/skills/cometchat-android-v6-compose-customization/SKILL.md +156 -1
  52. package/skills/cometchat-android-v6-compose-placement/SKILL.md +129 -40
  53. package/skills/cometchat-android-v6-compose-theming/SKILL.md +27 -1
  54. package/skills/cometchat-android-v6-core/SKILL.md +208 -28
  55. package/skills/cometchat-android-v6-events/SKILL.md +4 -1
  56. package/skills/cometchat-android-v6-extensions/SKILL.md +2 -1
  57. package/skills/cometchat-android-v6-features/SKILL.md +26 -2
  58. package/skills/cometchat-android-v6-kotlin-components/SKILL.md +31 -1
  59. package/skills/cometchat-android-v6-kotlin-customization/SKILL.md +172 -1
  60. package/skills/cometchat-android-v6-kotlin-placement/SKILL.md +20 -5
  61. package/skills/cometchat-android-v6-kotlin-theming/SKILL.md +36 -5
  62. package/skills/cometchat-android-v6-migration/SKILL.md +44 -42
  63. package/skills/cometchat-android-v6-production/SKILL.md +6 -3
  64. package/skills/cometchat-android-v6-push/SKILL.md +43 -2
  65. package/skills/cometchat-android-v6-testing/SKILL.md +11 -8
  66. package/skills/cometchat-android-v6-troubleshooting/SKILL.md +26 -5
  67. package/skills/cometchat-angular-calls/SKILL.md +256 -389
  68. package/skills/cometchat-angular-calls/references/add-calls-to-existing-chat.md +3 -2
  69. package/skills/cometchat-angular-calls/references/call-layouts.md +29 -12
  70. package/skills/cometchat-angular-calls/references/call-session.md +2 -2
  71. package/skills/cometchat-angular-calls/references/custom-ui.md +18 -10
  72. package/skills/cometchat-angular-calls/references/device-management.md +53 -34
  73. package/skills/cometchat-angular-calls/references/group-calls.md +45 -24
  74. package/skills/cometchat-angular-calls/references/idle-timeout.md +31 -15
  75. package/skills/cometchat-angular-calls/references/ngzone-and-async-callbacks.md +7 -6
  76. package/skills/cometchat-angular-calls/references/raise-hand.md +9 -4
  77. package/skills/cometchat-angular-calls/references/recording-screen-share.md +32 -39
  78. package/skills/cometchat-angular-calls/references/ringing-integration.md +3 -1
  79. package/skills/cometchat-angular-calls/references/share-invite.md +11 -5
  80. package/skills/cometchat-angular-calls/references/virtual-background.md +29 -0
  81. package/skills/cometchat-angular-components/SKILL.md +149 -620
  82. package/skills/cometchat-angular-core/SKILL.md +232 -312
  83. package/skills/cometchat-angular-customization/SKILL.md +415 -223
  84. package/skills/cometchat-angular-features/SKILL.md +216 -334
  85. package/skills/cometchat-angular-patterns/SKILL.md +168 -359
  86. package/skills/cometchat-angular-placement/SKILL.md +189 -560
  87. package/skills/cometchat-angular-production/SKILL.md +241 -92
  88. package/skills/cometchat-angular-push/SKILL.md +280 -294
  89. package/skills/cometchat-angular-testing/SKILL.md +430 -158
  90. package/skills/cometchat-angular-theming/SKILL.md +190 -265
  91. package/skills/cometchat-angular-troubleshooting/SKILL.md +192 -157
  92. package/skills/cometchat-astro-patterns/SKILL.md +3 -2
  93. package/skills/cometchat-calls/SKILL.md +25 -19
  94. package/skills/cometchat-calls/references/use-case-broadcast.md +15 -10
  95. package/skills/cometchat-calls/references/use-case-marketplace.md +2 -3
  96. package/skills/cometchat-calls/references/use-case-support.md +3 -4
  97. package/skills/cometchat-calls/references/use-case-team.md +23 -12
  98. package/skills/cometchat-calls/references/use-case-telehealth.md +3 -4
  99. package/skills/cometchat-components/SKILL.md +163 -25
  100. package/skills/cometchat-core/SKILL.md +258 -20
  101. package/skills/cometchat-customization/SKILL.md +50 -25
  102. package/skills/cometchat-features/SKILL.md +314 -35
  103. package/skills/cometchat-flutter-v5/SKILL.md +10 -4
  104. package/skills/cometchat-flutter-v5-calls/SKILL.md +188 -158
  105. package/skills/cometchat-flutter-v5-calls/references/add-calls-to-existing-chat.md +48 -24
  106. package/skills/cometchat-flutter-v5-calls/references/call-layouts.md +20 -15
  107. package/skills/cometchat-flutter-v5-calls/references/call-session.md +100 -145
  108. package/skills/cometchat-flutter-v5-calls/references/device-management.md +12 -8
  109. package/skills/cometchat-flutter-v5-calls/references/group-calls.md +30 -36
  110. package/skills/cometchat-flutter-v5-calls/references/idle-timeout.md +15 -13
  111. package/skills/cometchat-flutter-v5-calls/references/in-call-chat.md +12 -9
  112. package/skills/cometchat-flutter-v5-calls/references/migration-v4-to-v5.md +115 -65
  113. package/skills/cometchat-flutter-v5-calls/references/raise-hand.md +41 -30
  114. package/skills/cometchat-flutter-v5-calls/references/ringing-integration.md +17 -14
  115. package/skills/cometchat-flutter-v5-calls/references/share-invite.md +8 -2
  116. package/skills/cometchat-flutter-v5-conversations/SKILL.md +2 -1
  117. package/skills/cometchat-flutter-v5-core/SKILL.md +5 -4
  118. package/skills/cometchat-flutter-v5-customization/SKILL.md +136 -5
  119. package/skills/cometchat-flutter-v5-events/SKILL.md +2 -1
  120. package/skills/cometchat-flutter-v5-messages/SKILL.md +2 -1
  121. package/skills/cometchat-flutter-v5-production/SKILL.md +15 -6
  122. package/skills/cometchat-flutter-v5-push/SKILL.md +2 -1
  123. package/skills/cometchat-flutter-v5-testing/SKILL.md +17 -6
  124. package/skills/cometchat-flutter-v5-theming/SKILL.md +2 -1
  125. package/skills/cometchat-flutter-v5-troubleshooting/SKILL.md +7 -6
  126. package/skills/cometchat-flutter-v5-users-groups/SKILL.md +3 -2
  127. package/skills/cometchat-flutter-v6/SKILL.md +17 -16
  128. package/skills/cometchat-flutter-v6-calls/SKILL.md +72 -57
  129. package/skills/cometchat-flutter-v6-calls/references/add-calls-to-existing-chat.md +5 -3
  130. package/skills/cometchat-flutter-v6-calls/references/advanced-features.md +89 -0
  131. package/skills/cometchat-flutter-v6-calls/references/call-layouts.md +15 -12
  132. package/skills/cometchat-flutter-v6-calls/references/call-session.md +2 -2
  133. package/skills/cometchat-flutter-v6-calls/references/device-management.md +9 -3
  134. package/skills/cometchat-flutter-v6-calls/references/group-calls.md +10 -10
  135. package/skills/cometchat-flutter-v6-calls/references/idle-timeout.md +15 -7
  136. package/skills/cometchat-flutter-v6-calls/references/in-call-chat.md +6 -3
  137. package/skills/cometchat-flutter-v6-calls/references/raise-hand.md +23 -16
  138. package/skills/cometchat-flutter-v6-components/SKILL.md +32 -11
  139. package/skills/cometchat-flutter-v6-conversations/SKILL.md +39 -11
  140. package/skills/cometchat-flutter-v6-core/SKILL.md +182 -21
  141. package/skills/cometchat-flutter-v6-customization/SKILL.md +97 -25
  142. package/skills/cometchat-flutter-v6-events/SKILL.md +3 -2
  143. package/skills/cometchat-flutter-v6-features/SKILL.md +15 -6
  144. package/skills/cometchat-flutter-v6-messages/SKILL.md +111 -60
  145. package/skills/cometchat-flutter-v6-migration/SKILL.md +18 -25
  146. package/skills/cometchat-flutter-v6-placement/SKILL.md +79 -50
  147. package/skills/cometchat-flutter-v6-production/SKILL.md +13 -12
  148. package/skills/cometchat-flutter-v6-push/SKILL.md +41 -19
  149. package/skills/cometchat-flutter-v6-testing/SKILL.md +4 -4
  150. package/skills/cometchat-flutter-v6-theming/SKILL.md +38 -5
  151. package/skills/cometchat-flutter-v6-troubleshooting/SKILL.md +182 -17
  152. package/skills/cometchat-flutter-v6-users-groups/SKILL.md +12 -4
  153. package/skills/cometchat-i18n/SKILL.md +140 -79
  154. package/skills/cometchat-ios/SKILL.md +4 -2
  155. package/skills/cometchat-ios-calls/SKILL.md +225 -95
  156. package/skills/cometchat-ios-calls/references/add-calls-to-existing-chat.md +11 -9
  157. package/skills/cometchat-ios-calls/references/audio-modes-and-controls.md +45 -0
  158. package/skills/cometchat-ios-calls/references/avaudiosession-routing.md +6 -7
  159. package/skills/cometchat-ios-calls/references/call-layouts.md +31 -91
  160. package/skills/cometchat-ios-calls/references/call-session.md +51 -54
  161. package/skills/cometchat-ios-calls/references/callkit-and-pushkit.md +33 -29
  162. package/skills/cometchat-ios-calls/references/custom-ui.md +38 -38
  163. package/skills/cometchat-ios-calls/references/group-calls.md +33 -70
  164. package/skills/cometchat-ios-calls/references/idle-timeout.md +24 -25
  165. package/skills/cometchat-ios-calls/references/in-call-chat.md +19 -23
  166. package/skills/cometchat-ios-calls/references/migration-v4-to-v5.md +128 -70
  167. package/skills/cometchat-ios-calls/references/picture-in-picture.md +20 -20
  168. package/skills/cometchat-ios-calls/references/raise-hand.md +14 -227
  169. package/skills/cometchat-ios-calls/references/recording-screen-share.md +35 -122
  170. package/skills/cometchat-ios-calls/references/ringing-integration.md +17 -16
  171. package/skills/cometchat-ios-calls/references/share-invite.md +8 -12
  172. package/skills/cometchat-ios-calls/references/swiftui-uikit-hosting.md +4 -4
  173. package/skills/cometchat-ios-components/SKILL.md +200 -12
  174. package/skills/cometchat-ios-core/SKILL.md +173 -45
  175. package/skills/cometchat-ios-customization/SKILL.md +276 -110
  176. package/skills/cometchat-ios-features/SKILL.md +64 -36
  177. package/skills/cometchat-ios-placement/SKILL.md +15 -12
  178. package/skills/cometchat-ios-production/SKILL.md +12 -4
  179. package/skills/cometchat-ios-push/SKILL.md +53 -19
  180. package/skills/cometchat-ios-testing/SKILL.md +14 -9
  181. package/skills/cometchat-ios-theming/SKILL.md +39 -3
  182. package/skills/cometchat-ios-troubleshooting/SKILL.md +41 -21
  183. package/skills/cometchat-native-bare-patterns/SKILL.md +36 -19
  184. package/skills/cometchat-native-calls/SKILL.md +29 -17
  185. package/skills/cometchat-native-calls/references/add-calls-to-existing-chat.md +2 -2
  186. package/skills/cometchat-native-calls/references/call-layouts.md +15 -14
  187. package/skills/cometchat-native-calls/references/call-session.md +2 -2
  188. package/skills/cometchat-native-calls/references/custom-ui.md +12 -8
  189. package/skills/cometchat-native-calls/references/device-management.md +53 -30
  190. package/skills/cometchat-native-calls/references/group-calls.md +35 -30
  191. package/skills/cometchat-native-calls/references/idle-timeout.md +6 -6
  192. package/skills/cometchat-native-calls/references/in-call-chat.md +10 -8
  193. package/skills/cometchat-native-calls/references/migration-v4-to-v5.md +2 -2
  194. package/skills/cometchat-native-calls/references/raise-hand.md +15 -13
  195. package/skills/cometchat-native-calls/references/recording-screen-share.md +49 -170
  196. package/skills/cometchat-native-calls/references/share-invite.md +7 -5
  197. package/skills/cometchat-native-calls/references/voip-push-end-to-end.md +4 -2
  198. package/skills/cometchat-native-components/SKILL.md +84 -52
  199. package/skills/cometchat-native-core/SKILL.md +102 -33
  200. package/skills/cometchat-native-customization/SKILL.md +150 -28
  201. package/skills/cometchat-native-expo-patterns/SKILL.md +60 -29
  202. package/skills/cometchat-native-features/SKILL.md +24 -17
  203. package/skills/cometchat-native-placement/SKILL.md +19 -10
  204. package/skills/cometchat-native-production/SKILL.md +9 -3
  205. package/skills/cometchat-native-push/SKILL.md +2 -1
  206. package/skills/cometchat-native-testing/SKILL.md +1 -2
  207. package/skills/cometchat-native-theming/SKILL.md +54 -29
  208. package/skills/cometchat-native-troubleshooting/SKILL.md +11 -5
  209. package/skills/cometchat-nextjs-patterns/SKILL.md +22 -8
  210. package/skills/cometchat-placement/SKILL.md +42 -3
  211. package/skills/cometchat-production/SKILL.md +12 -5
  212. package/skills/cometchat-react-calls/SKILL.md +220 -10
  213. package/skills/cometchat-react-calls/references/add-calls-to-existing-chat.md +4 -3
  214. package/skills/cometchat-react-calls/references/call-layouts.md +5 -6
  215. package/skills/cometchat-react-calls/references/call-session.md +1 -1
  216. package/skills/cometchat-react-calls/references/custom-ui.md +61 -15
  217. package/skills/cometchat-react-calls/references/device-management.md +55 -51
  218. package/skills/cometchat-react-calls/references/group-calls.md +18 -23
  219. package/skills/cometchat-react-calls/references/idle-timeout.md +25 -12
  220. package/skills/cometchat-react-calls/references/in-call-chat.md +7 -7
  221. package/skills/cometchat-react-calls/references/migration-v4-to-v5.md +9 -11
  222. package/skills/cometchat-react-calls/references/raise-hand.md +14 -14
  223. package/skills/cometchat-react-calls/references/recording-screen-share.md +39 -38
  224. package/skills/cometchat-react-calls/references/ringing-integration.md +2 -2
  225. package/skills/cometchat-react-calls/references/share-invite.md +4 -5
  226. package/skills/cometchat-react-calls/references/testing-calls-on-web.md +20 -2
  227. package/skills/cometchat-react-calls/references/virtual-background.md +32 -0
  228. package/skills/cometchat-react-patterns/SKILL.md +45 -5
  229. package/skills/cometchat-react-push/SKILL.md +258 -72
  230. package/skills/cometchat-react-router-patterns/SKILL.md +12 -6
  231. package/skills/cometchat-react-testing/SKILL.md +14 -5
  232. package/skills/cometchat-theming/SKILL.md +181 -18
  233. package/skills/cometchat-troubleshooting/SKILL.md +40 -20
@@ -3,7 +3,6 @@ name: cometchat-native-troubleshooting
3
3
  description: "Diagnose CometChat React Native UI Kit integration failures — init/login, gesture handler, pod install, iOS privacy manifest, Android Maven, Metro cache, permissions, calls, extensions, v4-to-v5 upgrade. For push-specific symptoms see cometchat-native-push § 12."
4
4
  license: "MIT"
5
5
  compatibility: "Node.js >=18; React Native >=0.70; @cometchat/chat-uikit-react-native ^5"
6
- allowed-tools: "shell, file-read, file-search, file-list, ask-user"
7
6
  metadata:
8
7
  author: "CometChat"
9
8
  version: "3.0.0"
@@ -16,7 +15,7 @@ Teaches Claude how to diagnose and fix CometChat React Native integration failur
16
15
 
17
16
  **Read `cometchat-native-core` first** — most "why doesn't this work" issues trace to the init/login/wrapper chain explained there.
18
17
 
19
- Ground truth: `docs/ui-kit/react-native/troubleshooting.mdx`, `apple-privacy-manifest-guide.mdx`, `upgrading-from-v4.mdx`, and first-hand failure modes from real integrations.
18
+ Ground truth: `docs/ui-kit/react-native/troubleshooting.mdx`, `apple-privacy-manifest-guide.mdx`, `upgrading-from-v4.mdx`, and first-hand failure modes from real integrations. **Official docs:** https://www.cometchat.com/docs/ui-kit/react-native/overview · **Docs MCP:** `claude mcp add --transport http cometchat-docs https://www.cometchat.com/docs/mcp` (or fetch the URL directly without MCP).
20
19
 
21
20
  ---
22
21
 
@@ -90,6 +89,9 @@ done
90
89
 
91
90
  Missing peer deps → install + `pod install` (bare) or `expo install` (Expo) + rebuild.
92
91
 
92
+ > ⚠️ **`--legacy-peer-deps` silently DROPS peers.** If the project installed with `npm install --legacy-peer-deps` (common to dodge RN peer-range conflicts), npm **skips** unmet peer deps instead of erroring — you get a "successful" install with `react-native-svg` / `gesture-handler` / `safe-area-context` / async-storage missing, then a runtime crash. Re-run the check above after any `--legacy-peer-deps` install and install the missing ones **explicitly**.
93
+ > ⚠️ **`@cometchat/calls-lib-webrtc` is Cloudsmith-only — NOT on npm** (`npm view @cometchat/calls-lib-webrtc` → 404, verified). If a calls install fails resolving it, add the Cloudsmith tarball/registry per `cometchat-native-calls`; a plain `npm install @cometchat/calls-lib-webrtc` will never work.
94
+
93
95
  ---
94
96
 
95
97
  ## 2. Symptom → fix lookup tables
@@ -152,6 +154,9 @@ Quick-reference tables. Work through in order; if none match, drop into § 3 dee
152
154
  | Fast Refresh doesn't pick up new deps | Native dep change (requires rebuild) | Restart Metro + rebuild (iOS/Android) |
153
155
  | "Maximum update depth exceeded" after theme change | Theme object recreated each render | Define theme at module scope or in `useMemo(() => ..., [])` |
154
156
  | App crashes on first JS load | Entry file error (syntax or import order) | Check `index.js` — `react-native-gesture-handler` should be line 1 |
157
+ | Unhandled promise rejection at startup with `id=0` / module-load TypeError, but chat + calls work fine | Known non-blocking init artifact from the kit/calls-sdk module-level code (F77); source-map unresolvable | **Non-blocking — do NOT chase it.** Chat and calls are fully functional. Documented as a known v4.x artifact. Don't refactor user code to "fix" it. |
158
+ | Error banner shows literal `[object Object]` instead of a message | `setError(String(e))` / `setError(\`${e}\`)` — CometChatException stringifies to `[object Object]` | Use `e.message` (or a `formatCometChatError(e)` helper): `setError(e?.message ?? String(e))`. |
159
+ | (Expo) Credentials/config changes don't take effect after editing app config | `expo.extra` manifest is **cached** | Restart with `npx expo start --clear`; for a dev build, rebuild. The `expo.extra` block is baked into the manifest at build/start time. |
155
160
 
156
161
  ### 2f. Theming
157
162
 
@@ -421,10 +426,10 @@ If the user is upgrading from `@cometchat/chat-uikit-react-native@4`, these are
421
426
 
422
427
  ```bash
423
428
  # 1. Update the main kit
424
- npm install @cometchat/chat-uikit-react-native@latest
429
+ npm install @cometchat/chat-uikit-react-native@^5
425
430
 
426
431
  # 2. Install the full peer-dep set (v5 doesn't auto-install them like v4 did)
427
- npm install @cometchat/chat-sdk-react-native \
432
+ npm install @cometchat/chat-sdk-react-native@^4 \
428
433
  @react-native-async-storage/async-storage \
429
434
  @react-native-clipboard/clipboard \
430
435
  @react-native-community/datetimepicker \
@@ -460,7 +465,8 @@ cd ios && pod install && cd ..
460
465
 
461
466
  If none of the lookup tables or deep dives apply:
462
467
 
463
- 1. **Read the raw error.** RN errors are usually specific ("Module 'X' not found in app 'Y'" is different from "TurboModuleRegistry.getEnforcing").
468
+ 1. **Run `cometchat doctor`** (the structured first pass combines detect + info + verify + known-issue matching). Start here; it often pinpoints the layer (state / drift / env / deps) before you read logs.
469
+ 2. **Read the raw error.** RN errors are usually specific ("Module 'X' not found in app 'Y'" is different from "TurboModuleRegistry.getEnforcing").
464
470
  2. **Check the dev console + native logs.** For iOS: Xcode → View → Debug Area → Activate Console. For Android: `adb logcat | grep -E "cometchat|CometChat|ReactNative"`.
465
471
  3. **Search the upstream docs MCP** (`cometchat-docs` if installed).
466
472
  4. **Search the sample app** (`examples/SampleApp/` or `examples/SampleAppExpo/`) for a working version of the pattern the user is trying.
@@ -3,13 +3,14 @@ name: cometchat-nextjs-patterns
3
3
  description: "Framework-specific patterns for integrating CometChat React UI Kit v6 into Next.js projects (App Router and Pages Router). Covers SSR prevention, provider setup, route placement, API routes, and common pitfalls."
4
4
  license: "MIT"
5
5
  compatibility: "Node.js >=18; React >=18; Next.js >=13; @cometchat/chat-uikit-react ^6; @cometchat/chat-sdk-javascript ^4"
6
- allowed-tools: "shell, file-read, file-search, file-list"
7
6
  metadata:
8
7
  author: "CometChat"
9
8
  version: "3.0.0"
10
9
  tags: "chat cometchat nextjs next react ssr app-router pages-router patterns"
11
10
  ---
12
11
 
12
+ > **Ground truth:** `@cometchat/chat-uikit-react@^6` (+ `@cometchat/calls-sdk-javascript@^5`) — installed package types + `ui-kit/react`. **Official docs:** https://www.cometchat.com/docs/ui-kit/react/overview · **Docs MCP:** `claude mcp add --transport http cometchat-docs https://www.cometchat.com/docs/mcp` (or fetch the URL directly without MCP). Verify symbols against the installed package/source before relying on them.
13
+
13
14
  ## Purpose
14
15
 
15
16
  This skill teaches Claude how to integrate CometChat into a Next.js project. Next.js is the most complex framework to integrate with because of Server-Side Rendering (SSR) and the Server Component / Client Component boundary. Every CometChat component is browser-only -- getting this wrong is the #1 source of integration failures.
@@ -72,12 +73,13 @@ import React from "react";
72
73
  import React from "react";
73
74
  ```
74
75
 
75
- ### App Router: dynamic import from Server Components
76
+ ### App Router: dynamic import from a Client Component (Next.js 15+ rule)
76
77
 
77
- If you need to render a CometChat component inside a Server Component (e.g., a page that does data fetching), use `next/dynamic` with `ssr: false`:
78
+ > ⚠️ **Next.js 15+ change (verified by runtime smoke 2026-06-02):** `dynamic(..., { ssr: false })` is **FORBIDDEN in Server Components** — Next.js 15+ throws a build error. The page that owns the dynamic-import MUST be a Client Component (`"use client"` at line 1). Otherwise the build fails with `Ecmascript file had an error` even if everything else is correct.
78
79
 
79
80
  ```tsx
80
- // app/messages/page.tsx (this is a Server Component)
81
+ // app/messages/page.tsx
82
+ "use client"; // ← REQUIRED in Next.js 15+ when using `dynamic({ ssr: false })`
81
83
  import dynamic from "next/dynamic";
82
84
 
83
85
  const ChatView = dynamic(() => import("../../components/ChatView"), {
@@ -90,7 +92,11 @@ export default function MessagesPage() {
90
92
  }
91
93
  ```
92
94
 
93
- The `ChatView` component itself must still have `"use client"` at the top.
95
+ The `ChatView` component file itself must also have `"use client"` at the top. Both ends of the dynamic-import boundary need the directive.
96
+
97
+ **If you cannot make the page a Client Component** (because it needs server data-fetching), wrap your data-fetching in a separate Server Component sibling and pass results down via props to a Client Component that owns the CometChat subtree.
98
+
99
+ **Build still fails after applying both `"use client"` and `dynamic(... ssr:false)`?** Add `export const dynamic = "force-dynamic";` at the top of the page to opt out of static prerendering entirely (or `export const runtime = "edge";` for edge runtime). This is sometimes needed in Next.js 16 even with everything else correct — verified during 2026-06-02 smoke against Next.js 16.2.7. Skill-side suspicion: kit's module-eval-time `window` references still trip static prerender even via dynamic boundary.
94
100
 
95
101
  ### Pages Router: dynamic import
96
102
 
@@ -190,7 +196,8 @@ export function CometChatProvider({ children }: CometChatProviderProps) {
190
196
 
191
197
  setIsReady(true);
192
198
  } catch (e) {
193
- setError(String(e));
199
+ setError(formatCometChatError(e)); // from cometchat-core §6 errors.ts — NOT String(e),
200
+ // which renders "[object Object]" on kit errors (ENG-35719)
194
201
  }
195
202
  }
196
203
 
@@ -239,6 +246,13 @@ export default function RootLayout({ children }: { children: React.ReactNode })
239
246
 
240
247
  **Note:** Importing a `"use client"` component from a Server Component is fine. Next.js renders the Server Component on the server and defers the Client Component to the browser. The `CometChatProvider` only runs its `useEffect` (and init) in the browser.
241
248
 
249
+ > ⚠️ **Option A REQUIRES `force-dynamic` on the layout (verified — real build, Next 16.2.9 + kit 6.5.1).** Mounting the provider in `app/layout.tsx` pulls the kit module into the layout's module graph, so `next build` evaluates it during the **static prerender** of *every* route — including `/` (which imports no CometChat code) and the framework-generated `/_not-found` — and crashes with `ReferenceError: window is not defined`. `"use client"` does NOT prevent this in Next 16. The per-page `export const dynamic = "force-dynamic"` from §"Build still fails…" cannot fix it, because `/_not-found` has no page file to annotate. **The fix is to put the directive on the LAYOUT, where it cascades to all routes including `/_not-found`:**
250
+ > ```tsx
251
+ > // app/layout.tsx — add this alongside the provider mount
252
+ > export const dynamic = "force-dynamic";
253
+ > ```
254
+ > If you would rather keep static prerendering for non-chat routes, use **Option B** (scoped route group) so `/` and `/_not-found` never import the kit — that is the cleaner choice for marketing/SSG-heavy sites.
255
+
242
256
  ### Where to mount: Option B -- Scoped (chat only on chat routes)
243
257
 
244
258
  Use a route group to scope the provider to chat-related routes:
@@ -836,7 +850,7 @@ If the project has a custom `pages/_document.tsx` for font preloading or third-p
836
850
 
837
851
  ## 12. Complete integration checklist (App Router)
838
852
 
839
- 1. Install packages: `npm install @cometchat/chat-uikit-react @cometchat/chat-sdk-javascript`
853
+ 1. Install packages: `npm install @cometchat/chat-uikit-react@^6 @cometchat/chat-sdk-javascript@^4` — **⚠️ keep the `@^6` major pin; never install bare.** v7 is on npm — a bare `npm install @cometchat/chat-uikit-react` pulls it once it's tagged `latest`, and these v6 skills break against the v7 API.
840
854
  2. Create `.env.local` with `NEXT_PUBLIC_COMETCHAT_APP_ID`, `NEXT_PUBLIC_COMETCHAT_REGION`, `NEXT_PUBLIC_COMETCHAT_AUTH_KEY`
841
855
  3. Import `@cometchat/chat-uikit-react/css-variables.css` in `app/globals.css`
842
856
  4. Create `app/providers/CometChatProvider.tsx` with `"use client"` (section 3)
@@ -847,7 +861,7 @@ If the project has a custom `pages/_document.tsx` for font preloading or third-p
847
861
 
848
862
  ## 13. Complete integration checklist (Pages Router)
849
863
 
850
- 1. Install packages: `npm install @cometchat/chat-uikit-react @cometchat/chat-sdk-javascript`
864
+ 1. Install packages: `npm install @cometchat/chat-uikit-react@^6 @cometchat/chat-sdk-javascript@^4` — **⚠️ keep the `@^6` major pin; never install bare.** v7 is on npm — a bare `npm install @cometchat/chat-uikit-react` pulls it once it's tagged `latest`, and these v6 skills break against the v7 API.
851
865
  2. Create `.env.local` with `NEXT_PUBLIC_COMETCHAT_APP_ID`, `NEXT_PUBLIC_COMETCHAT_REGION`, `NEXT_PUBLIC_COMETCHAT_AUTH_KEY`
852
866
  3. Import `@cometchat/chat-uikit-react/css-variables.css` in `pages/_app.tsx`
853
867
  4. Create `components/CometChatProvider.tsx` (section 3 code, without `"use client"`)
@@ -3,13 +3,14 @@ name: cometchat-placement
3
3
  description: "Production integration patterns -- how to add CometChat as a route, modal, drawer, embedded panel, or widget in an existing project. Teaches Claude WHERE to put chat."
4
4
  license: "MIT"
5
5
  compatibility: "@cometchat/chat-uikit-react ^6; @cometchat/chat-sdk-javascript ^4"
6
- allowed-tools: "shell, file-read, file-search, file-list"
7
6
  metadata:
8
7
  author: "CometChat"
9
8
  version: "3.0.0"
10
9
  tags: "chat cometchat react placement route modal drawer widget embedded integration"
11
10
  ---
12
11
 
12
+ > **Ground truth:** `@cometchat/chat-uikit-react@^6` components composed for placement + `docs/ui-kit/react`. **Official docs:** https://www.cometchat.com/docs/ui-kit/react/overview · **Docs MCP:** `claude mcp add --transport http cometchat-docs https://www.cometchat.com/docs/mcp` (or fetch the URL directly without MCP). Verify symbols against the installed package/source before relying on them.
13
+
13
14
  ## Purpose
14
15
 
15
16
  This skill teaches you WHERE to put CometChat in an existing project. It covers five placement patterns: route, modal, drawer, embedded panel, and floating widget. Each pattern includes step-by-step instructions and complete code examples.
@@ -168,6 +169,30 @@ chat products.
168
169
 
169
170
  ---
170
171
 
172
+ > **Composer choice for narrow/two-pane panes:** the canonical React v6 sample apps use **`CometChatCompactMessageComposer`** (not `CometChatMessageComposer`) in the two-pane messages view — it's the kit's space-optimized composer for a sidebar-width pane (`cometchat-uikit-react-v6/sample-app/src/components/CometChatMessages/CometChatMessages.tsx:85`). Both compile and work; prefer `CometChatCompactMessageComposer` for the split/two-pane layouts below and `CometChatMessageComposer` for full-width single-thread layouts.
173
+
174
+ ## Height & scroll — the message-view column MUST be bounded
175
+
176
+ Every header+list+composer example below puts the three components as **direct
177
+ flex children** of a `display:flex; flexDirection:column` column. That works ONLY
178
+ if the column has a bounded height — i.e. the full chain (`html`/`body`/`#root` →
179
+ …→ this column) uses a definite **`height`** (e.g. `#root { height: 100vh }`),
180
+ never `min-height`, and every flex ancestor of `CometChatMessageList` has
181
+ `minHeight: 0`. Delete the Vite/CRA starter `#root { min-height: 100vh; max-width: … }`.
182
+
183
+ If the list still won't scroll (most common symptom), or you wrap the list in its
184
+ own `<div>` for custom chrome/tabs, you hit the kit's auto-injected `.cometchat`
185
+ element — see **`cometchat-react-patterns` → "Container height (and the flex-shrink
186
+ trap)" Bug 3**: give the list its own wrapper class with BOTH `.your-list-wrapper
187
+ { flex: 1 1 0; min-height: 0; height: 100%; overflow: hidden }` (the **explicit
188
+ `height: 100%` is required** — a flex-grow-only height is indefinite, so the kit's
189
+ injected child collapses to content height and clips) AND a child rule
190
+ `.your-list-wrapper > .cometchat { height: 100%; overflow: hidden }` (inline styles
191
+ can't target the injected child). Those two rules are the single most common fix for
192
+ "I set heights everywhere and it still won't scroll."
193
+
194
+ ---
195
+
171
196
  ## Thread replies — hidden by default in every example below
172
197
 
173
198
  Every `<CometChatMessageList ...>` in the placement patterns below
@@ -607,6 +632,17 @@ The `CometChatProvider` (or equivalent init logic) MUST be at the app root, NOT
607
632
 
608
633
  A side panel that slides in from the right. Better than a modal for ongoing conversations because the user can keep it open while browsing.
609
634
 
635
+ > ⚠️ **Known kit-side traps in narrow containers (≤ ~480px). Mitigate, don't ignore (ENG-35702/03/04/06):**
636
+ >
637
+ > 1. **Unread-count badges clip at the right edge in 320px panes** — kit's conversation-list item doesn't reserve trailing padding for the pill. Workaround until the kit fix lands: target `.cometchat-conversation-list-item__badge { margin-right: 8px; flex-shrink: 0; }` in your overrides, OR widen the drawer to ≥ 480px on the inner content (use `width: min(420px, 100vw)` + 8px inner padding).
638
+ > 2. **`Delete Conversation?` confirmation card overflows the list pane** — kit renders the dialog inside the list column instead of portalling to a top-level scrim. There's no clean CSS workaround today; if the integration depends on right-click delete, raise the drawer width above ~480px so the card fits inside.
639
+ > 3. **Composer attachment popover (`+` button) anchors to the wrong ancestor** — opens at viewport bottom-right instead of above the trigger when mounted inside a drawer/modal. Workaround: ensure the drawer container has `position: relative` (NOT just `position: fixed`) on its inner card so absolute popovers anchor correctly. If the popover still misaligns, mount the composer in a full-screen-on-mobile variant (the `right: -100%` recipe from §"Recipe — breakpoint-aware drawer").
640
+ > 4. **Voice recorder bubble UI is broken at kit v6.x** — the in-bubble recorder shows visual artifacts AND the pause-resume timer restarts at 00:00 instead of continuing. There is no client-side workaround; if voice messages are part of the integration's core surface, document the limitation for the customer and consider hiding the voice button (`<CometChatMessageComposer hideVoiceRecordingButton={true} />`) until the kit fix ships.
641
+ > 5. **`CometChatMessageList` does NOT auto-resubscribe on conversation switch** — passing a new `user` or `group` prop keeps the old listeners. **Required workaround when switching conversations inside a single drawer/modal:** pass `key={user?.getUid() ?? group?.getGuid()}` to force a remount + listener re-subscribe. Without it, switching from Alice → Bob silently shows Alice's messages with Bob's header. (ENG-35702)
642
+ > 6. **`CometChatMessageList` may render BLANK on conversations with unread messages** — kit-side data-path bug, no header or empty-state, just blank. No client-side workaround today; if the customer reports a blank list, capture the screenshot + UID/GUID + unread count and file a kit ticket. (ENG-35702 kit-side blocker)
643
+ >
644
+ > These are kit-side bugs filed in Linear (ENG-35702, 35703, 35704, 35706); the workarounds above are interim until the next kit release.
645
+
610
646
  ### Steps
611
647
 
612
648
  #### 1. Create a ChatDrawer component
@@ -688,9 +724,12 @@ export function ChatDrawer({ isOpen, onClose, targetUserId, targetGroupId }: Cha
688
724
  style={{
689
725
  position: "fixed",
690
726
  top: 0,
691
- right: isOpen ? 0 : "-400px", // matches width; slides off-screen when closed
727
+ // Breakpoint-aware: full-width on mobile (≤ 640px), 400px on desktop.
728
+ // The "-100%" closed offset slides the drawer off-screen at any width,
729
+ // so mobile-full-screen works without recomputing the offset (ENG-35715).
730
+ right: isOpen ? 0 : "-100%",
692
731
  bottom: 0,
693
- width: "400px",
732
+ width: "min(400px, 100vw)",
694
733
  maxWidth: "100vw",
695
734
  zIndex: 1000,
696
735
  backgroundColor: "var(--cometchat-background-color-01, #fff)",
@@ -3,13 +3,14 @@ name: cometchat-production
3
3
  description: "Production readiness for CometChat — server-side token auth, user management CRUD, environment hardening, and security checklist. Replaces dev-mode authKey with server-side tokens."
4
4
  license: "MIT"
5
5
  compatibility: "Node.js >=18; @cometchat/chat-uikit-react ^6; @cometchat/chat-sdk-javascript ^4"
6
- allowed-tools: "shell, file-read, file-search, file-list"
7
6
  metadata:
8
7
  author: "CometChat"
9
8
  version: "3.0.0"
10
9
  tags: "cometchat production auth token security user-management rest-api"
11
10
  ---
12
11
 
12
+ > **Ground truth:** `docs/fundamentals/user-auth` + per-platform UI Kit. **Official docs:** https://www.cometchat.com/docs/fundamentals/user-auth · **Docs MCP:** `claude mcp add --transport http cometchat-docs https://www.cometchat.com/docs/mcp` (or fetch the URL directly without MCP). Verify symbols against the installed package/source before relying on them.
13
+
13
14
  ## Purpose
14
15
 
15
16
  This skill teaches Claude how to harden a CometChat integration for production. It covers two critical areas:
@@ -71,8 +72,10 @@ The CometChat REST API requires two headers:
71
72
 
72
73
  | Key type | Where to find | Purpose | Security |
73
74
  |---|---|---|---|
74
- | **Auth Key** | Dashboard → Your App → API & Auth Keys → "Auth Keys" table | Client-side SDK: `CometChatUIKit.login(uid)` in dev mode | Exposed in browser. Dev only. |
75
- | **REST API Key** | Dashboard → Your App → API & Auth Keys → "Rest API Keys" table | Server-to-server: token generation, user CRUD, message send | Server only. Never expose to client. |
75
+ | **Auth Key** (`authOnly` scope) | Dashboard → Your App → API & Auth Keys → "Auth Keys" table | Client-side SDK `CometChatUIKit.login(uid)` in dev mode; server-side it can **create users + mint auth tokens** (`POST /v3/users`, `POST /v3/users/{uid}/auth_tokens`) but **NOT** update/delete users | Exposed in browser. Dev only. |
76
+ | **REST API Key** (`fullAccess` scope) | Dashboard → Your App → API & Auth Keys → "Rest API Keys" table | Server-to-server: token generation, **full** user CRUD (incl. **update/delete**), message send | Server only. Never expose to client. |
77
+
78
+ > **Scope split (verified against `fundamentals/key-concepts.mdx` + the chat-apis `apikey` scope enum `fullAccess`/`authOnly`):** the Auth Key can *create & login* users and mint tokens, but **`PUT`/`DELETE /v3/users/{uid}` require a `fullAccess` REST API Key** — an `authOnly` Auth Key is rejected. So a user-management endpoint that does update/delete MUST use `COMETCHAT_REST_API_KEY`, not the Auth Key. (Heads-up: the CLI's `add-user-mgmt` / `production-auth` scaffolds currently name the server var `COMETCHAT_AUTH_KEY`; for full CRUD, populate it with — or rename it to — a `fullAccess` REST API Key. Tracked as a CLI-alignment follow-up.)
76
79
 
77
80
  The `.env` should have both for production:
78
81
  ```env
@@ -585,8 +588,12 @@ async function refreshSession(uid: string): Promise<void> {
585
588
  CometChat.addConnectionListener(
586
589
  "auth-refresh-listener",
587
590
  new CometChat.ConnectionListener({
588
- onDisconnected: () => {
589
- const uid = CometChatUIKit.getLoggedInUser()?.getUid();
591
+ onDisconnected: async () => {
592
+ // Web kit method is getLoggedinUser() (lowercase "i") and is ASYNC —
593
+ // it returns a Promise, so you must await it (you can't chain ?.getUid()
594
+ // on the call directly). The synchronous capital-I form is the Angular kit.
595
+ const me = await CometChatUIKit.getLoggedinUser();
596
+ const uid = me?.getUid();
590
597
  if (uid) {
591
598
  refreshSession(uid).catch((e) => {
592
599
  console.error("CometChat refresh failed; user may need to re-login", e);
@@ -1,15 +1,16 @@
1
1
  ---
2
2
  name: cometchat-react-calls
3
- description: CometChat Calls SDK integration for web React apps (Vite, CRA, Next.js, React Router, Astro). Covers @cometchat/calls-sdk-javascript install, dual-SDK init (Chat SDK + Calls SDK), getRTCToken, the kit's CometChatIncomingCall / CometChatOutgoingCall / CometChatOngoingCall components, CallButtons composition, getUserMedia permissions, browser TURN/STUN handling, and additive-vs-standalone modes.
3
+ description: CometChat Calls SDK integration for web React apps (Vite, CRA, Next.js, React Router, Astro). Covers @cometchat/calls-sdk-javascript install, dual-SDK init (Chat SDK + Calls SDK), generateToken (v4's getRTCToken was removed in v5), the kit's CometChatIncomingCall / CometChatOutgoingCall / CometChatOngoingCall components, CallButtons composition, getUserMedia permissions, browser TURN/STUN handling, and additive-vs-standalone modes.
4
4
  license: "MIT"
5
5
  compatibility: "React >= 18, Next.js >= 13, React Router v6/v7, Astro >= 4; @cometchat/calls-sdk-javascript ^5 (v5.0.0 stable shipped; pin to `@5` because the npm `latest` dist-tag still points at v4.2.6 — see §Install); @cometchat/chat-sdk-javascript ^4.x; @cometchat/chat-uikit-react ^6.x (additive mode)"
6
- allowed-tools: "shell, file-read, file-search, file-list, ask-user"
7
6
  metadata:
8
7
  author: "CometChat"
9
8
  version: "4.0.0"
10
9
  tags: "cometchat react calls voice video webrtc nextjs react-router astro getRTCToken getusermedia browser-permissions vite cra"
11
10
  ---
12
11
 
12
+ > **Ground truth:** `@cometchat/chat-uikit-react@^6` (+ `@cometchat/calls-sdk-javascript@^5`) — installed package types + `ui-kit/react`. **Official docs:** https://www.cometchat.com/docs/calls/javascript/overview · **Docs MCP:** `claude mcp add --transport http cometchat-docs https://www.cometchat.com/docs/mcp` (or fetch the URL directly without MCP). Verify symbols against the installed package/source before relying on them.
13
+
13
14
  ## ⚠️ STOP — mandatory precondition before any code
14
15
 
15
16
  **Before writing one line of code, you MUST resolve `mode = ringing | session`.** This decides which entire integration shape you scaffold — they don't share UI, navigation, or surface.
@@ -80,6 +81,25 @@ If you can't use flex (e.g. fixed-height modal), just give the container explici
80
81
 
81
82
  ---
82
83
 
84
+ ## ⚠️ Idle timeout is in MILLISECONDS (the "Are you still there? → instant exit" bug)
85
+
86
+ The idle-timeout values are **milliseconds, not seconds.** This is the single most common calls-config footgun (customer-reported 2026-06): setting `idleTimeoutPeriodBeforePrompt: 180` thinking "180 seconds" means **180 ms** — so the moment you join a session alone, the "Are you still there?" prompt fires and the call exits in a fraction of a second.
87
+
88
+ ```ts
89
+ // ✗ WRONG — read as 180ms / 30ms → prompt + exit almost instantly on join
90
+ const settings = { idleTimeoutPeriodBeforePrompt: 180, idleTimeoutPeriodAfterPrompt: 30 };
91
+
92
+ // ✓ RIGHT — milliseconds. (defaults: 60_000 / 120_000)
93
+ const settings = {
94
+ idleTimeoutPeriodBeforePrompt: 180_000, // 180s before the prompt
95
+ idleTimeoutPeriodAfterPrompt: 60_000, // 60s grace before disconnect
96
+ };
97
+ ```
98
+
99
+ Set them as `SessionSettings` **object fields** (used with `joinSession(token, settings, container)`): `{ idleTimeoutPeriodBeforePrompt: 180_000, idleTimeoutPeriodAfterPrompt: 60_000 }`. ⚠️ There are **no** `setIdleTimeoutPeriodBeforePrompt`/`AfterPrompt` builder methods — `CallSettingsBuilder` has only a single `setIdleTimeoutPeriod(ms)`; the before/after split exists **only** as the two object fields. **`idleTimeoutPeriodAfterPrompt` has a 60_000 ms (60s) minimum** — smaller values are silently clamped to 60s. To effectively disable it, use a huge value (`86_400_000` = 24h), never `0` or a tiny number. The timer only counts down when you're the **only** participant — so a single-person session/test triggers it fastest. Full recipe (prompt UI + extend/leave): `references/idle-timeout.md`.
100
+
101
+ ---
102
+
83
103
  ## ⚠️ Next.js / SSR — mandatory bundler config
84
104
 
85
105
  Both SDKs ship code that **breaks Next.js's SSR pass**:
@@ -217,10 +237,25 @@ Production-grade voice + video calling for React-family web apps. Loaded by `com
217
237
  - Framework-specific patterns: `cometchat-react-patterns` / `cometchat-nextjs-patterns` / `cometchat-react-router-patterns` / `cometchat-astro-patterns`
218
238
 
219
239
  **Ground truth:**
220
- - SDK source — `~/Downloads/calls-sdk/calls-sdk-javascript-5/package/`
221
- - Sample apps — `~/Downloads/calls-sdk/calls-sdk-javascript-5/sample-apps/{react,vue,angular,svelte,ionic}/`
240
+ - SDK source — `calls-sdk-javascript-5/package/`
241
+ - Sample apps — `calls-sdk-javascript-5/sample-apps/{react,vue,angular,svelte,ionic}/`
222
242
  - Public docs — https://www.cometchat.com/docs/calls/javascript/overview
223
243
 
244
+ ## When to use
245
+
246
+ - React-family web apps with voice/video calling: Vite + React, Next.js (App or Pages Router), React Router v6/v7, Astro with React islands.
247
+ - The user wants 1:1 OR group calls AND wants the calls UI surface (not pure server-side / signaling-only).
248
+ - Either calling mode applies — ringing (kit-driven incoming call screen) OR session (meeting-room URL pattern).
249
+
250
+ ## When NOT to use
251
+
252
+ - **Chat-only integrations (no calling at all)** — skip this skill entirely. Load only `cometchat-core` + `cometchat-react-patterns` + `cometchat-components`. Don't install `@cometchat/calls-sdk-javascript` — the calls SDK alone is ~700 KB; with the kit + chat SDK the full production bundle of a chat-**and**-calls app is ~4.8 MB JS (verified — real `vite build`). That's expected; a green build also emits benign `COMMONJS_VARIABLE_IN_ESM` warnings from the calls SDK's own code and a >500 KB chunk-size warning — these are NOT failures.
253
+ - **Native mobile (Android / iOS / RN / Flutter)** — load the cohort-specific calls skill (`cometchat-native-calls`, `cometchat-android-v6-calls`, `cometchat-ios-calls`, `cometchat-flutter-v6-calls`). The Calls SDK is platform-specific; APIs and lifecycle differ.
254
+ - **Angular** — load `cometchat-angular-calls`. Same underlying JS Calls SDK but wrapped in Angular Services + `@Output()` event bindings (NOT React-style callback props — verified runtime smoke 2026-06-02 caught the v4→v5 binding inversion).
255
+ - **SDK-only (no UI Kit)** — `cometchat-react-calls` §4c covers the SDK-only path in detail; this is the right skill, but you're using a specific subset. Don't import `<CometChatCallButtons>` / `<CometChatOngoingCall>` / `<CometChatIncomingCall>` from `@cometchat/chat-uikit-react` in that mode.
256
+ - **Server-side token-mint server work** — load `cometchat-production` for the REST-API token recipes; this skill is client-side.
257
+ - **Visual Builder calls** — load `cometchat-core` §11 + the framework-specific patterns; the Visual Builder generates calls wiring differently.
258
+
224
259
  ---
225
260
 
226
261
  ## 1. The seven hard rules — web specialization
@@ -242,11 +277,13 @@ const initiated = await CometChat.initiateCall(outgoing);
242
277
  // ✓ RIGHT — join WebRTC session (Calls SDK v5)
243
278
  import { CometChatCalls } from "@cometchat/calls-sdk-javascript";
244
279
 
245
- // v5 — plain SessionSettings object, no Builder
280
+ // v5 — plain SessionSettings object, no Builder.
281
+ // `as const` keeps the string literals narrow ("VIDEO"/"TILE") so they satisfy
282
+ // the SDK's SessionType / Layout unions — a bare object widens them to `string`.
246
283
  const sessionSettings = {
247
284
  sessionType: "VIDEO", // or "VOICE"
248
285
  layout: "TILE",
249
- };
286
+ } as const;
250
287
 
251
288
  // v5 — generateToken takes ONLY sessionId (Calls SDK has its own auth state
252
289
  // after CometChatCalls.login(); no authToken arg needed).
@@ -288,9 +325,11 @@ function endCall() {
288
325
 
289
326
  Skipping this leaves the camera light on until the tab is closed. Same canonical bug as iOS rule 1.5.
290
327
 
291
- ### 1.4 Server-minted auth tokens for production
328
+ ### 1.4 Calls login the DEFAULT path needs NONE; only `directCalling`/SDK-only do
292
329
 
293
- In v5 the Calls SDK has **its own login step**it no longer piggybacks on the Chat SDK's auth context implicitly. After `CometChat.login()` resolves on the chat side, call **`CometChatCalls.login(uid, apiKey)`** for dev or **`CometChatCalls.loginWithAuthToken(authToken)`** for production. The auth token is the same token your backend mints via the CometChat Create-Auth-Token API; the Calls SDK and Chat SDK accept it interchangeably.
330
+ > **For the common case additive ringing / default calling do NOT call `CometChatCalls.login`.** Install the calls SDK, let the call buttons appear automatically in `CometChatMessageHeader`, and mount `<CometChatIncomingCall />` once at the app root. That's the whole wiring. **Both canonical React v6 sample apps do calls this exact way with ZERO `CometChatCalls.login`/`CometChatCalls.init`** (verified: `cometchat-uikit-react-v6/sample-app/src/components/CometChatHome/CometChatHome.tsx:1740` mounts only `<CometChatIncomingCall />`; no `CometChatCalls.login` anywhere in either sample). The kit's default `defaultCalling` mode rides the Chat SDK's signaling adding a calls-login step here is needless plumbing, and an empty/wrong arg makes it **silently no-op**.
331
+
332
+ **`CometChatCalls.login` is required ONLY for** (a) `CallWorkflow.directCalling` (conference-style 1:1) or (b) the SDK-only / custom-WebRTC surface (§4c). In those cases — and only those — the v5 Calls SDK needs its own login: after `CometChat.login()` resolves on the chat side, call **`CometChatCalls.login(uid, apiKey)`** for dev or **`CometChatCalls.loginWithAuthToken(authToken)`** for production. The auth token is the same one your backend mints via the CometChat Create-Auth-Token API; the Calls SDK and Chat SDK accept it interchangeably.
294
333
 
295
334
  ```ts
296
335
  // Dev
@@ -300,8 +339,12 @@ await CometChatCalls.login(uid, import.meta.env.VITE_COMETCHAT_API_KEY);
300
339
  await CometChatCalls.loginWithAuthToken(authTokenFromBackend);
301
340
  ```
302
341
 
342
+ > **About `VITE_COMETCHAT_API_KEY`:** `CometChatCalls.login(uid, apiKey)` takes the app's **Auth Key** — the same value `cometchat-core` writes as `VITE_COMETCHAT_AUTH_KEY` (the env-prefix table establishes `APP_ID`/`REGION`/`AUTH_KEY`, not a separate `API_KEY`). In dev you can reuse `VITE_COMETCHAT_AUTH_KEY` here; if you prefer the `_API_KEY` name for readability, add it to your `.env` with the same Auth Key value. Don't leave it undefined — an empty arg makes the Calls login silently no-op (see the `directCalling` trap above).
343
+
303
344
  `cometchat-production` (web) covers the token-endpoint pattern.
304
345
 
346
+ > ⚠️ **`CallWorkflow.directCalling` silently fails without this login.** When you opt 1:1 calls into the conference-style UI by passing `callWorkflow={CallWorkflow.directCalling}` to `<CometChatCallButtons>` / `<CometChatOngoingCall>` etc., the kit routes through the Calls SDK directly and **requires `CometChatCalls.login()` to have completed**. Without it, calls **ring for ~2 seconds then drop with no error message** — the most painful failure mode in this skill. The UI Kit's default `defaultCalling` mode does NOT have this requirement (it uses the Chat SDK's signaling). Rule when emitting `directCalling`: always include the `CometChatCalls.login(...)` call alongside the Chat login above (ENG-35709).
347
+
305
348
  ### 1.5 Hangup cleanup — see rule 1.3
306
349
 
307
350
  ### 1.6 Permissions — `getUserMedia` prompts
@@ -328,6 +371,69 @@ There are no manifest-level permission declarations on web. HTTPS is required
328
371
 
329
372
  Mounting it inside a route component means it disappears on navigation — calls only ring on the screen where it's mounted. That's the canonical "calls don't work" bug on web.
330
373
 
374
+ ### 1.8 Init order — Chat init → Chat login → Calls init → Calls login (ENG-35708)
375
+
376
+ The order is load-bearing. Two crashes from real testers trace back to this:
377
+
378
+ - **`CometChatCalls.init` before `CometChat.login` → calls integration broke.** The Calls SDK reads context from the Chat SDK that only exists once a Chat session is established. Swapping init order silently fails or returns 401s on the first `generateToken`.
379
+ - **Crash on `Start Call` when only the Calls SDK was initialized.** No Chat SDK init at all → the ringing flow can't fire `initiateCall` because the Chat SDK isn't there.
380
+
381
+ **The only correct order in additive mode (chat + calls):**
382
+
383
+ ```
384
+ CometChat.init(appId, settings)
385
+ → CometChat.login(uid, authKey) // OR loginWithAuthToken(token)
386
+ → CometChatCalls.init({appId, region})
387
+ → CometChatCalls.login(uid, apiKey) // OR loginWithAuthToken(serverToken)
388
+ ```
389
+
390
+ In **standalone session-mode** (`product === "voice-video"`, no chat), use ONLY the Calls SDK — never call `CometChat.init` / `CometChat.login` at all. The kit's session-mode sample doesn't import the Chat SDK; matching that shape eliminates a class of "Chat init failed mid-meeting" failures.
391
+
392
+ ### 1.9 Don't double-up call buttons (ENG-35708)
393
+
394
+ Two testers reported call buttons appearing twice on the message screen. Cause: the kit's `<CometChatMessageHeader user={user} />` already renders `<CometChatCallButtons>` internally when a `user` prop is set (and the kit's default messages page mounts the header). Adding your own `<CometChatCallButtons user={user} />` next to either of those produces a duplicate set.
395
+
396
+ **Rule before emitting `<CometChatCallButtons>`:**
397
+
398
+ 1. Check whether the surrounding kit component already shows them. `CometChatMessageHeader` (any path that auto-renders the header) and the kit's default messages page include call buttons by default. (Note: there is no `CometChatConversationsWithMessages` composite in v6 — it was removed.)
399
+ 2. If yes, do NOT add a second `<CometChatCallButtons>`. To swap appearance or behavior, use the kit's `messageHeaderView` slot or set the relevant `hide*` flag instead of adding another instance.
400
+ 3. If no — you're on a custom screen that does not use those kit components — then `<CometChatCallButtons user={user} />` is appropriate. Mount it once, beside the user-info block.
401
+
402
+ ### 1.10 `CometChatOngoingCall` expects a `callSettingsBuilder`, NOT a built `CallSettings` (ENG-35708)
403
+
404
+ `CallSettingsBuilder` is not a bare export of either package — access it via the kit re-export: `import { CometChatUIKitCalls } from "@cometchat/chat-uikit-react"`, then `new CometChatUIKitCalls.CallSettingsBuilder()`. The prop shape is the **builder instance** (not the built settings object). The agent emitted:
405
+
406
+ ```tsx
407
+ // ✗ Wrong — TypeScript error on the prop type
408
+ const callSettings = new CometChatUIKitCalls.CallSettingsBuilder().enableDefaultLayout(true).build();
409
+ <CometChatOngoingCall callSettingsBuilder={callSettings} />
410
+ ```
411
+
412
+ The correct usage is:
413
+
414
+ ```tsx
415
+ // ✓ Right. Verified against the kit's CometChatOngoingCallProps (6.5.x):
416
+ // sessionID: string ← REQUIRED (non-optional) — omitting it TS-errors
417
+ // callSettingsBuilder?: ... ← OPTIONAL; the kit defaults to new CometChatUIKitCalls.CallSettingsBuilder()
418
+ // There is NO .setSessionID() on the builder — the session id is its OWN prop.
419
+ // The builder holds only configuration setters (enableDefaultLayout /
420
+ // setIsAudioOnlyCall / show*Button).
421
+ const callSettingsBuilder = new CometChatUIKitCalls.CallSettingsBuilder()
422
+ .enableDefaultLayout(true)
423
+ .setIsAudioOnlyCall(false);
424
+ <CometChatOngoingCall sessionID={sessionId} callSettingsBuilder={callSettingsBuilder} />
425
+ ```
426
+
427
+ > **Prefer the additive path over a manual `<CometChatOngoingCall>` mount.** Mounting `<CometChatIncomingCall />` at the app root and letting the kit drive the Outgoing → Ongoing transition needs no `sessionID` plumbing and is the build-clean, recommended approach (§1.x). Reach for a manual `<CometChatOngoingCall>` only when you're building a custom call screen — and then `sessionID` is mandatory.
428
+
429
+ Why this shape: the kit composes the builder with internal listeners (call-end, error, recording state) before calling `.build()`. Pre-building forecloses that composition. Pass the builder; let the kit build.
430
+
431
+ > ⚠️ **`callSettingsBuilder` is a different shape on different components** (verified vs the v6 React kit source — do not assume one form):
432
+ > - `<CometChatOngoingCall>` → a **builder instance** (`callSettingsBuilder={new CometChatUIKitCalls.CallSettingsBuilder()...}`), prop typed `typeof CometChatUIKitCalls.CallSettings`.
433
+ > - `<CometChatCallButtons>` → a **callback**: `callSettingsBuilder={(isAudioOnlyCall, user?, group?) => new CometChatUIKitCalls.CallSettingsBuilder()...}`.
434
+ > - `<CometChatIncomingCall>` (and Outgoing) → a **callback** taking the call: `callSettingsBuilder={(call) => new CometChatUIKitCalls.CallSettingsBuilder()...}`.
435
+ > All three are optional — omit the prop and the kit uses its own default builder (the simplest correct path). Only the OngoingCall form takes a bare instance; passing an instance where a callback is expected is a TS error.
436
+
331
437
  ---
332
438
 
333
439
  ## 2. Setup
@@ -380,7 +486,10 @@ export async function initCometChat() {
380
486
  export async function loginCometChat(uid: string) {
381
487
  await CometChat.login(uid, import.meta.env.VITE_COMETCHAT_AUTH_KEY);
382
488
 
383
- // v5 — Calls SDK login. Either form is fine; loginWithAuthToken is for production.
489
+ // v5 — Calls SDK login. Only needed for CallWorkflow.directCalling or the
490
+ // SDK-only/custom-WebRTC surface (see §1.4) — for the COMMON additive/default
491
+ // ringing path you can OMIT this whole block (the kit rides the Chat SDK's
492
+ // signaling). Shown here for completeness; harmless when included with a valid key.
384
493
  if (!CometChatCalls.getLoggedInUser()) {
385
494
  await CometChatCalls.login(uid, import.meta.env.VITE_COMETCHAT_API_KEY);
386
495
  // OR: await CometChatCalls.loginWithAuthToken(serverMintedToken);
@@ -390,6 +499,8 @@ export async function loginCometChat(uid: string) {
390
499
 
391
500
  The module-level `initialized` flag prevents StrictMode double-init in React 18+ dev mode. The `getLoggedInUser()` guard prevents re-login on hot reload.
392
501
 
502
+ > ⚠️ **Additive mode: the chat layer must init via `CometChatUIKit.init()`, not raw `CometChat.init()`.** The example above shows `CometChat.init()` for the SDK-only path. But when you use the kit's call components (`<CometChatCallButtons>` / `<CometChatIncomingCall>` / `<CometChatOngoingCall>`), they read `uiKitSettings` that **only `CometChatUIKit.init(new UIKitSettingsBuilder()…build())` sets** — your `cometchat-core` setup already does this. Initializing the chat layer with raw `CometChat.init()` instead leaves the components logging **`uiKitSettings not available`** (non-fatal — calls still connect — but a real DX smell). In additive mode, keep `CometChatUIKit.init()` as your chat init and have this calls module ADD only `CometChatCalls.init()` + `CometChatCalls.login()` on top. *(Verified by a two-user live call smoke 2026-06-04: with `CometChatUIKit.init()` the ring→accept→join flow runs with zero console errors; with raw `CometChat.init()` both sides log the warning.)*
503
+
393
504
  ### Framework-specific env prefixes (already covered by `cometchat-core`)
394
505
 
395
506
  | Framework | Env prefix |
@@ -464,7 +575,7 @@ When `product === "voice-video"` and there is no existing chat UI integration.
464
575
 
465
576
  ### 4a. Standalone — Session mode (meeting-room UX, no ringing)
466
577
 
467
- Calls SDK ONLY. NO Chat SDK. Matches the upstream sample at `~/Downloads/calls-sdk/calls-sdk-javascript-5/sample-apps/cometchat-calls-sample-app-react/`. The skill scaffolds:
578
+ Calls SDK ONLY. NO Chat SDK. Matches the upstream sample at `calls-sdk-javascript-5/sample-apps/cometchat-calls-sample-app-react/`. The skill scaffolds:
468
579
 
469
580
  1. **`cometchat/init.ts`** — `CometChatCalls.init({ appId, region, authKey })` ONLY. No `CometChat.init`, no `CometChat.login`. Pass `authKey` at init time so subsequent `CometChatCalls.login(uid)` calls need no second arg.
470
581
  2. **`cometchat/CometChatProvider.tsx`** — Runs Calls SDK init on mount, exposes `loggedInUser` via `CometChatCalls.getLoggedInUser()`, gates children on success.
@@ -487,6 +598,104 @@ Dual-SDK: Chat SDK signaling channel + Calls SDK media channel. The skill scaffo
487
598
  7. **Optional Web Push** — Service Worker registration + push subscription endpoint, if the user opts in.
488
599
  8. **HTTPS check** — warns if dev server is HTTP non-localhost.
489
600
 
601
+ ### 4c. SDK-only — without any UI Kit call components (ENG-35707)
602
+
603
+ When the user wants to build their own call UI (custom controls, a custom in-call screen) but still wants ringing semantics, they're on the SDK-only path: Chat SDK for signaling + Calls SDK for media, NO `<CometChatCallButtons>` / `<CometChatOngoingCall>` / `<CometChatIncomingCall>` from the UI Kit. The previous version of this skill was UI-Kit-first and these gotchas were silent. Cover them explicitly when you scaffold this shape.
604
+
605
+ #### Constants — two enums, same meaning, easy to confuse
606
+
607
+ | Constant | Source | Use it for |
608
+ |---|---|---|
609
+ | `CometChat.CALL_TYPE.AUDIO` / `.VIDEO` | `@cometchat/chat-sdk-javascript` | The **Chat SDK** call entity — passed to `new CometChat.Call(receiver, callType, receiverType)` and to `CometChat.initiateCall`. |
610
+ | `CometChat.RECEIVER_TYPE.USER` / `.GROUP` | `@cometchat/chat-sdk-javascript` | The **Chat SDK** call entity — passed alongside `callType`. |
611
+ | `CometChatCalls.constants.TYPE.VOICE` / `.VIDEO` | `@cometchat/calls-sdk-javascript` | The **Calls SDK** session-type enum. Matches the `SessionSettings` `sessionType` value (`'VOICE'` / `'VIDEO'`). |
612
+
613
+ These are NOT interchangeable. `CometChat.CALL_TYPE.AUDIO` (Chat SDK) ≠ `CometChatCalls.constants.TYPE.VOICE` (Calls SDK) even though they mean the same thing. Use the Chat SDK enum on the `Call` entity you pass to `initiateCall`; use the Calls SDK enum on `SessionSettings.sessionType`.
614
+
615
+ > Note: `CallSettingsBuilder` has **no** `setCallType(...)` method — that lives on `CallLogRequestBuilder` (and takes `'video' | 'audio'` for filtering call logs). The audio knob for a session is `CallSettingsBuilder().setIsAudioOnlyCall(true)`, or `sessionType: 'VOICE'` in the `SessionSettings` object form. (Verified against the calls-sdk `index.d.ts`.)
616
+
617
+ #### Audio-only calls — `setIsAudioOnlyCall(true)` on `CallSettingsBuilder`
618
+
619
+ The audio-only knob lives on the Calls SDK's `CallSettingsBuilder`, not on the Chat SDK call entity. You set the Chat SDK call type to `AUDIO` for the ringing/signaling channel, and then ALSO set `setIsAudioOnlyCall(true)` on the call settings used for `joinSession`:
620
+
621
+ ```typescript
622
+ // joinSession's 2nd arg is a SessionSettings OBJECT (NOT the output of
623
+ // CallSettingsBuilder.build() — that's a CallSettings, accepted only by the
624
+ // deprecated startSession). The session is carried by the `token` (from
625
+ // generateToken(sessionId)); there is no sessionId/setSessionID in the settings.
626
+ // Voice-only: set sessionType: 'VOICE' (the object equivalent of the v4
627
+ // builder's setIsAudioOnlyCall(true)).
628
+ const settings = { sessionType: 'VOICE' };
629
+
630
+ const result = await CometChatCalls.joinSession(token, settings, containerRef.current);
631
+ ```
632
+
633
+ Without `sessionType: 'VOICE'`, voice calls still acquire the camera (it's just not rendered) — which trips the browser permission prompt and lights the camera indicator. Always pair `CALL_TYPE.AUDIO` (Chat) + `sessionType: 'VOICE'` in the join settings (Calls) for voice calls.
634
+
635
+ #### Container-mount timing — `joinSession` MUST fire after the container is in the DOM
636
+
637
+ This is the most painful SDK-only failure mode. The natural site to call `joinSession` is the call-listener event `onOutgoingCallAccepted` (caller side) or `onIncomingCallReceived` → user-accepts (receiver side). But those events fire BEFORE your in-call panel has rendered — the container `<div ref={containerRef}>` is still `null`. `joinSession(token, settings, null)` throws `Container dimensions and number of tiles must be positive` (or silently no-ops in some kit versions).
638
+
639
+ **Pattern: drive the container via state and join in a `useEffect` that depends on both the call state AND the container ref.**
640
+
641
+ ```tsx
642
+ function CallScreen() {
643
+ const [phase, setPhase] = useState<"idle" | "joining" | "in-call">("idle");
644
+ const [callToken, setCallToken] = useState<string | null>(null);
645
+ const containerRef = useRef<HTMLDivElement>(null);
646
+
647
+ // Step 1: register call listeners
648
+ useEffect(() => {
649
+ const listenerID = "call-screen-" + Date.now();
650
+ CometChat.addCallListener(listenerID, new CometChat.CallListener({
651
+ onOutgoingCallAccepted: async (call: any) => {
652
+ // DO NOT call joinSession here — the container ref is still null.
653
+ // Just flip the phase and let the effect below handle it.
654
+ const tokenRes = await CometChatCalls.generateToken(call.getSessionId(), authToken);
655
+ setCallToken(tokenRes.token);
656
+ setPhase("in-call");
657
+ },
658
+ onIncomingCallReceived: (call: any) => { /* show your accept UI */ },
659
+ }));
660
+ return () => CometChat.removeCallListener(listenerID);
661
+ }, []);
662
+
663
+ // Step 2: when phase flips to "in-call" AND container is mounted, join
664
+ useEffect(() => {
665
+ if (phase !== "in-call" || !callToken || !containerRef.current) return;
666
+ const container = containerRef.current;
667
+ if (container.clientWidth === 0 || container.clientHeight === 0) return; // not laid out yet
668
+ // session is carried by callToken (from generateToken). joinSession takes a
669
+ // SessionSettings OBJECT — {} uses the default layout. (Do NOT pass
670
+ // CallSettingsBuilder.build() here — that CallSettings type is for the
671
+ // deprecated startSession, and is incompatible with joinSession.)
672
+ CometChatCalls.joinSession(callToken, {}, container);
673
+ }, [phase, callToken]);
674
+
675
+ return (
676
+ <>
677
+ {phase === "in-call" && (
678
+ <div ref={containerRef} style={{ position: "fixed", inset: 0, width: "100vw", height: "100vh" }} />
679
+ )}
680
+ </>
681
+ );
682
+ }
683
+ ```
684
+
685
+ The key idea: the call-listener handler doesn't call `joinSession` directly. It updates state. The effect that depends on `phase` AND the ref runs ONLY after React has committed the container `<div>` to the DOM. This is the same race as "modal `<dialog>` mounted before `showModal()`" — it's a React/DOM-timing issue, not a SDK bug.
686
+
687
+ #### Group calls vs 1:1 calls — defaults differ
688
+
689
+ - **1:1 calls** use the ringing pattern: `new CometChat.Call(receiverUid, CALL_TYPE.VIDEO, RECEIVER_TYPE.USER)` → `CometChat.initiateCall(call)` → receiver gets `onIncomingCallReceived`. Default call type for a 1:1 video chat is video; for audio chat, audio.
690
+ - **Group calls** in the UI Kit go through a **custom-message broadcast** (`CometChatCallButtons` sends `CustomMessage type="meeting"`), not `initiateCall`. SDK-only groups: send your own custom message + `CometChatCalls.joinSession` with a shared sessionId — there is no "ring a group" primitive.
691
+ - **Group call default is voice** in the kit's `CometChatCallButtons` for groups; 1:1 default is video. If you're building custom buttons, replicate this — group calls are usually meeting-style (voice + screen share); 1:1s are usually video.
692
+
693
+ Cross-reference: `cometchat-native-calls` §3 documents the same group-call custom-message pattern for React Native (memory: [[project_group_calls_kit_semantic]]).
694
+
695
+ #### Container CSS — non-zero dimensions before `joinSession`
696
+
697
+ Already covered in the §⚠️ "Call container — must have non-zero dimensions" callout at the top, but it bears repeating in the SDK-only flow because there's no UI Kit component wrapping the container. Inline-render the container with `position: fixed; inset: 0; width: 100vw; height: 100vh` (full-screen overlay) OR `display: flex; flex: 1; min-height: 600px` (embedded). NEVER `display: none` + toggle — the container measures zero while hidden and `joinSession` throws.
698
+
490
699
  ## 5. Additive integration
491
700
 
492
701
  When `cometchat-core` integration already exists. The skill:
@@ -532,6 +741,7 @@ When `cometchat-core` integration already exists. The skill:
532
741
 
533
742
  ## 8. Pointers
534
743
 
744
+ - `references/virtual-background.md` — blur / custom image / clear (web-only; native iOS/Android don't support it)
535
745
  - `cometchat-core` — provider pattern, init guard, login order
536
746
  - `cometchat-components` — full UI Kit catalog (additive mode)
537
747
  - `cometchat-{nextjs,react,react-router,astro}-patterns` — framework-specific SSR guards, route placement