@cometchat/skills 5.0.0 → 5.0.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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +8 -0
- package/MIGRATING.md +187 -0
- package/README.md +19 -1
- package/RULES.md +12 -1
- package/bin/cometchat-skills.mjs +106 -6
- package/package.json +8 -3
- package/peers.yaml +46 -3
- package/registry/android-calls-v5.json +40 -0
- package/registry/android-v6.json +40 -0
- package/registry/angular-v5.json +40 -0
- package/registry/flutter-calls-v5.json +40 -0
- package/registry/flutter-v6.json +40 -0
- package/registry/ios-calls-v5.json +40 -0
- package/registry/ios-v5.json +55 -0
- package/registry/rn-calls-v5.json +40 -0
- package/registry/rn-v5.json +40 -0
- package/registry/sdk-android-v5.json +40 -0
- package/registry/sdk-jsv4.json +40 -0
- package/registry/web-calls-v5.json +40 -0
- package/registry/web-v7.json +55 -0
- package/skills/cometchat/SKILL.md +8 -3
- package/skills/cometchat-a11y/SKILL.md +49 -0
- package/skills/cometchat-analytics/SKILL.md +61 -0
- package/skills/cometchat-android-v6-core/references/docs-map.md +2 -2
- package/skills/cometchat-android-v6-production/SKILL.md +1 -0
- package/skills/cometchat-angular-v5-production/SKILL.md +1 -0
- package/skills/cometchat-audit/SKILL.md +61 -0
- package/skills/cometchat-compliance/SKILL.md +63 -0
- package/skills/cometchat-flutter-v6-customization/SKILL.md +1 -1
- package/skills/cometchat-flutter-v6-migration/references/migration-guide.md +8 -7
- package/skills/cometchat-flutter-v6-production/SKILL.md +1 -0
- package/skills/cometchat-i18n/SKILL.md +50 -0
- package/skills/cometchat-ios-core/SKILL.md +3 -2
- package/skills/cometchat-ios-core/references/anti-patterns.md +33 -0
- package/skills/cometchat-ios-core/references/docs-map.md +4 -3
- package/skills/cometchat-ios-core/references/layout.md +33 -0
- package/skills/cometchat-ios-production/SKILL.md +82 -0
- package/skills/cometchat-ios-testing/SKILL.md +57 -0
- package/skills/cometchat-ios-troubleshooting/SKILL.md +45 -0
- package/skills/cometchat-migrate-from-getstream/SKILL.md +65 -0
- package/skills/cometchat-migrate-from-getstream/references/concept-map.md +98 -0
- package/skills/cometchat-migrate-from-getstream/references/data-migration.md +74 -0
- package/skills/cometchat-migrate-from-getstream/references/feature-map.md +108 -0
- package/skills/cometchat-migrate-from-getstream/references/inventory.md +82 -0
- package/skills/cometchat-migrate-from-getstream/references/native-build.md +9 -0
- package/skills/cometchat-migrate-from-getstream/references/report-template.md +59 -0
- package/skills/cometchat-migrate-from-sendbird/SKILL.md +64 -0
- package/skills/cometchat-migrate-from-sendbird/references/concept-map.md +99 -0
- package/skills/cometchat-migrate-from-sendbird/references/data-migration.md +74 -0
- package/skills/cometchat-migrate-from-sendbird/references/feature-map.md +104 -0
- package/skills/cometchat-migrate-from-sendbird/references/inventory.md +86 -0
- package/skills/cometchat-migrate-from-sendbird/references/native-build.md +10 -0
- package/skills/cometchat-migrate-from-sendbird/references/report-template.md +59 -0
- package/skills/cometchat-migrate-from-twilio/SKILL.md +52 -0
- package/skills/cometchat-migrate-from-twilio/references/concept-map.md +49 -0
- package/skills/cometchat-migrate-from-twilio/references/data-migration.md +50 -0
- package/skills/cometchat-migrate-from-twilio/references/feature-map.md +27 -0
- package/skills/cometchat-migrate-from-twilio/references/inventory.md +53 -0
- package/skills/cometchat-migrate-from-twilio/references/report-template.md +52 -0
- package/skills/cometchat-moderation/SKILL.md +58 -0
- package/skills/cometchat-onboarding/SKILL.md +4 -1
- package/skills/cometchat-onboarding/references/platforms.md +15 -0
- package/skills/cometchat-react-native-core/SKILL.md +25 -3
- package/skills/cometchat-react-native-core/references/docs-map.md +2 -1
- package/skills/cometchat-react-native-production/SKILL.md +1 -0
- package/skills/cometchat-react-native-sdk/SKILL.md +16 -9
- package/skills/cometchat-react-native-troubleshooting/SKILL.md +58 -0
- package/skills/cometchat-react-v7-core/SKILL.md +4 -4
- package/skills/cometchat-react-v7-core/references/anti-patterns.md +1 -1
- package/skills/cometchat-react-v7-core/references/component-props.md +1 -1
- package/skills/cometchat-react-v7-core/references/layout.md +4 -12
- package/skills/cometchat-react-v7-production/SKILL.md +84 -0
- package/skills/cometchat-react-v7-testing/SKILL.md +60 -0
- package/skills/cometchat-react-v7-troubleshooting/SKILL.md +47 -0
- package/skills/cometchat-security/SKILL.md +80 -0
- package/skills/cometchat-self-host/SKILL.md +56 -0
- package/test-suite/catalogs/flutter-calls-v5.json +1 -1
- package/test-suite/scripts/lint-skills.mjs +30 -7
- package/test-suite/scripts/verify-family-agnostic.mjs +5 -1
- package/skills/cometchat-react-v7-core/references/i18n-rtl-a11y.md +0 -22
- package/skills/cometchat-react-v7-core/references/troubleshooting.md +0 -28
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
<!-- family-agnostic: per-platform-by-design — this reference IS the per-platform Twilio inventory + target-family table; one row per platform by design. -->
|
|
2
|
+
# Twilio Conversations inventory — what to find, and where it goes
|
|
3
|
+
|
|
4
|
+
Search case-insensitively. Skip `node_modules/`, `Pods/`, `build/`, `.dart_tool/`, `.gradle/`, `.git/`. "Twilio" is distinctive; match the package + class names below. Twilio Conversations is **headless** — the app has its own UI on the Twilio client, so most hits are in a data/service layer, and each becomes a ledger row (`file:line → purpose`).
|
|
5
|
+
|
|
6
|
+
## Target family (where each platform lands)
|
|
7
|
+
| App platform (detect `framework`) | Twilio packages you'll see | CometChat family (`peers.yaml`) | Default = client/SDK mode → | Optional (fresh UI) → |
|
|
8
|
+
|---|---|---|---|---|
|
|
9
|
+
| React / Next / Vite / CRA / Astro | `@twilio/conversations` (+ `twilio-chat` if legacy) | `react-v7` | the core's Chat SDK fallback (`@cometchat/chat-sdk-javascript`) | `cometchat-react-v7-core` UI Kit |
|
|
10
|
+
| Angular | `@twilio/conversations` | `angular-v5` | JS Chat SDK | `cometchat-angular-v5-core` |
|
|
11
|
+
| React Native / Expo | `@twilio/conversations` (RN-compatible) | `react-native` | `cometchat-react-native-sdk` | `cometchat-react-native-core` |
|
|
12
|
+
| iOS (Swift) | `TwilioConversationsClient` (pod/SPM `twilio-conversations`) | `ios` | the iOS core's SDK fallback (`CometChatSDK`) | `cometchat-ios-core` |
|
|
13
|
+
| Android | `com.twilio:conversations-android` | `android-v6` | `cometchat-android-v5-sdk` | `cometchat-android-v6-core` |
|
|
14
|
+
| Flutter | `twilio_conversations` | `flutter-v6` | the Flutter core's SDK fallback (`cometchat_sdk`) | `cometchat-flutter-v6-core` |
|
|
15
|
+
| Server (Node, Python, Go, Java, Ruby, PHP, C#) | `twilio` server SDK → Conversations REST; access-token minting | — (REST) | — | CometChat REST (`/rest-api/…`) |
|
|
16
|
+
|
|
17
|
+
Because Twilio ships no UI Kit, the **default** target is client/SDK mode (keep the app's UI). Offer the UI Kit path only if the user wants CometChat's prebuilt UI. A platform not in this table → STOP: report only.
|
|
18
|
+
|
|
19
|
+
## Grep signals
|
|
20
|
+
**Manifests**: `package.json`, `Podfile`, `Package.swift`, `build.gradle(.kts)`, `pubspec.yaml`, `requirements.txt`, `go.mod`, `Gemfile`, `composer.json`, `*.csproj` → `twilio/conversations`, `twilio-conversations`, `twilio_conversations`, `@twilio/conversations`, `twilio-chat` (legacy Programmable Chat), `TwilioConversationsClient`, `com.twilio:conversations`.
|
|
21
|
+
|
|
22
|
+
**Client / auth**:
|
|
23
|
+
- JS: `Client` / `Conversations.Client`, `new Client(token)`, `Client.create(token)`, `client.updateToken(...)`, `'stateChanged'` → `'initialized'`, `'tokenAboutToExpire'` / `'tokenExpired'`.
|
|
24
|
+
- iOS: `TwilioConversationsClient.conversationsClient(withToken:...)`.
|
|
25
|
+
- Android: `ConversationsClient.create(...)`.
|
|
26
|
+
- Flutter: `TwilioConversations.create(...)`.
|
|
27
|
+
- **Access token fetch**: a call to your server for a Twilio JWT (the client never holds the API secret).
|
|
28
|
+
|
|
29
|
+
**Conversations (channels)**:
|
|
30
|
+
- `client.getConversationBySid` / `getConversationByUniqueName` / `createConversation` / `getSubscribedConversations`.
|
|
31
|
+
- `conversation.add(...)` / `join()` / `leave()` / `delete()`, `friendlyName`, `uniqueName`, `attributes`.
|
|
32
|
+
|
|
33
|
+
**Participants**:
|
|
34
|
+
- `conversation.getParticipants()`, `add(identity)` / `addNonChatParticipant` (SMS/WhatsApp), `removeParticipant`, `participant.identity`.
|
|
35
|
+
|
|
36
|
+
**Messages**:
|
|
37
|
+
- `conversation.sendMessage(...)` (text or a `MessageBuilder` with media), `getMessages(...)`, `message.body`, `message.attributes`, `message.media` / `attachedMedia`, `updateBody`, `remove`.
|
|
38
|
+
- Delivery/read: `conversation.setAllMessagesRead()`, `getUnreadMessagesCount()`, `advanceLastReadMessageIndex`, `AggregatedDeliveryReceipt` / `DetailedDeliveryReceipt`.
|
|
39
|
+
- Typing: `conversation.typing()`, `'typingStarted'` / `'typingEnded'`.
|
|
40
|
+
|
|
41
|
+
**Events**: `client.on('conversationAdded'|'messageAdded'|'participantJoined'|'typingStarted'|'connectionStateChanged'|...)`, `conversation.on('messageAdded'|...)`.
|
|
42
|
+
|
|
43
|
+
**Media**: `message.media.getContentTemporaryUrl()`, `MessageBuilder.addMedia(...)`, `media.filename`/`contentType`/`size`.
|
|
44
|
+
|
|
45
|
+
**Other**: `user`/`User` (friendlyName, attributes, online/notifiable), push (`client.setPushRegistrationId` / FCM/APNs binding), `attributes` (JSON on conversation/message/participant/user).
|
|
46
|
+
|
|
47
|
+
**Legacy Programmable Chat** (`twilio-chat`, deprecated): `Channel`, `Member`, `Message`, `client.getChannelBySid` — same shapes as Conversations; map identically and note it's the legacy SDK.
|
|
48
|
+
|
|
49
|
+
**Server**: `AccessToken` + `ChatGrant`/`ConversationsGrant` (API Key SID/Secret + Conversations Service SID), Conversations REST (`conversations.v1.conversations…`), webhooks (`onMessageAdded`, `onConversationAdded`, scoped/global).
|
|
50
|
+
|
|
51
|
+
**Env / config**: `TWILIO_ACCOUNT_SID`, `TWILIO_API_KEY`, `TWILIO_API_SECRET`, `TWILIO_CONVERSATIONS_SERVICE_SID`, `VITE_TWILIO_*`, tokens endpoints; CI secrets `TWILIO_*`.
|
|
52
|
+
|
|
53
|
+
**Tests / mocks**: `jest.mock('@twilio/conversations')`, fake `Client`/`Conversation`.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Report template — `COMETCHAT_MIGRATION.md`
|
|
2
|
+
|
|
3
|
+
Write this at the repo root from the ledger. Keep an empty section's heading with "None." Then END the chat reply with sections 3 and 5 pasted in full (SKILL step 11).
|
|
4
|
+
|
|
5
|
+
```markdown
|
|
6
|
+
# Twilio Conversations → CometChat migration
|
|
7
|
+
|
|
8
|
+
**Branch:** cometchat-migration (from <base>; <n> uncommitted files came along) · **Platform:** <framework> → CometChat <family label> · **Mode:** client/SDK (default) | UI Kit
|
|
9
|
+
**Build:** ✅ passes (`<command>`) | ❌ <n> errors (below) · **Twilio residue:** none | <paths>
|
|
10
|
+
|
|
11
|
+
## 1. Summary
|
|
12
|
+
<2–4 sentences: what the app did on Twilio Conversations (headless client + own UI), what it does now (CometChat Chat SDK behind the same UI, or UI Kit), the headline removals.>
|
|
13
|
+
|
|
14
|
+
## 2. Migrated
|
|
15
|
+
| Twilio feature | CometChat equivalent | Files |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| Conversations client + access-token login | CometChat init + `loginWithAuthToken` | src/chat/client.ts, server/token.ts |
|
|
18
|
+
| Conversation list / messages / participants | conversations + messages request builders + group members | src/chat/*, … |
|
|
19
|
+
|
|
20
|
+
## 3. Removed — not available in CometChat
|
|
21
|
+
| Feature | What it did | Removed from | What users lose | Evidence (features.json · docs query → result) | Closest CometChat alternative |
|
|
22
|
+
|---|---|---|---|---|---|
|
|
23
|
+
| Non-chat participants (SMS / WhatsApp / MMS) | Bridged the conversation to phone numbers via `addNonChatParticipant` | src/…, server/… | Reaching users over SMS/WhatsApp from the chat | Not in features.json · UI Kit `"sms whatsapp participant"` → no page · SDK `"non-chat participant sms"` → no page (Twilio omnichannel is vendor-specific) | — (use a separate SMS provider if still needed) |
|
|
24
|
+
|
|
25
|
+
## 4. Behavior changes (migrated, works differently)
|
|
26
|
+
- Presence/online model differs from Twilio's `notifiable`/`online` user flags.
|
|
27
|
+
- Conversations with exactly two participants are now 1:1 user conversations, not two-person groups.
|
|
28
|
+
|
|
29
|
+
## 5. Your action items
|
|
30
|
+
1. Add your CometChat credentials to an untracked env file (App ID, Region, Auth Key for dev). Placeholders are there now — never commit them.
|
|
31
|
+
2. Create a REST API key; set `COMETCHAT_REST_API_KEY` on the server (token endpoint + data script).
|
|
32
|
+
3. Import history: `scripts/cometchat-migration/README.md` (dry run first). Re-host media — Twilio media URLs expire.
|
|
33
|
+
4. Enable in the CometChat dashboard: <extensions / AI the migrated features need>.
|
|
34
|
+
5. Push: upload FCM/APNs credentials to CometChat.
|
|
35
|
+
6. Point webhooks at the new receiver; pick events.
|
|
36
|
+
7. Before production: server-minted auth tokens (already wired if a token server existed).
|
|
37
|
+
8. Remove `TWILIO_*` secrets from CI/hosting; close the Twilio Conversations service after cut-over.
|
|
38
|
+
|
|
39
|
+
## 6. Defaults taken (no questions were asked)
|
|
40
|
+
- <e.g. "client/SDK mode: kept the app's UI, swapped the data layer to the CometChat Chat SDK"; "skipped: <step> — <why>">
|
|
41
|
+
|
|
42
|
+
## 7. Verification
|
|
43
|
+
- Build: `<command>` → <result>
|
|
44
|
+
- Residue search: `twilio` (case-insensitive, excl. node_modules/dist/.git) → <result>
|
|
45
|
+
- Tests: <ran / none / updated n, removed m>
|
|
46
|
+
- Pre-existing issues (failing before the migration): <list or none>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Rules for the lists:
|
|
50
|
+
- Every REMOVE row names concrete files + UI entry points AND its evidence (features.json + both docs queries). Debug/QA-only code goes in a Dev/QA-only subsection, no evidence needed.
|
|
51
|
+
- "Closest CometChat alternative" must be a real documented capability or `—`. Never invent one.
|
|
52
|
+
- Order action items by what unblocks running the app first: credentials → data → production hardening.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cometchat-moderation
|
|
3
|
+
description: "Trust & Safety for CometChat — auto-moderate text/image/video/file with dashboard rules + keyword lists, block or flag-for-review, let users report messages, and keep an audit trail. Cross-family: rules/lists/queues are dashboard+REST; report/block UI is built into each family's UI Kit. Triggers: 'add moderation', 'profanity filter', 'image moderation', 'block bad words', 'report a message', 'flag inappropriate content', 'content safety', 'spam/scam detection', 'CSAM/minor safety', 'malware scan attachments', 'moderation queue'."
|
|
4
|
+
license: "MIT"
|
|
5
|
+
compatibility: "CometChat Moderation (dashboard rules/lists + Flagged/Blocked/Reviewed queues) · Moderation REST API v3 · per-family UI Kit report/block + Chat SDK flagging."
|
|
6
|
+
metadata:
|
|
7
|
+
author: "CometChat"
|
|
8
|
+
version: "1.0.0"
|
|
9
|
+
tags: "cometchat moderation trust-safety profanity image-moderation spam csam malware report flag audit"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
> **Ground truth:** capabilities and rule names are FETCHED from the live docs — `{DOCS_BASE}/moderation/overview`, `/moderation/{rules-management,lists-management,flagged-messages,blocked-messages,reviewed-messages}`, `{DOCS_BASE}/rest-api/moderation-apis/overview`, and the client hooks `{DOCS_BASE}/ui-kit/<family>/core-features#moderation` (built-in report) + `{DOCS_BASE}/sdk/<platform>/ai-moderation` (SDK flagging). `DOCS_BASE = https://www.cometchat.com/docs`; append `.md`. Most of this is dashboard configuration; verify the exact rule/list options and any REST shapes against the docs before asserting them.
|
|
13
|
+
|
|
14
|
+
## Use this skill when
|
|
15
|
+
Making a chat safe/compliant: profanity/toxicity filtering, image/video safety, spam/scam detection, malware scanning of attachments, letting users report content, a moderator review queue, or an audit trail for T&S. Trust & Safety is a procurement gate for social, gaming, marketplace, dating, education and healthcare apps.
|
|
16
|
+
|
|
17
|
+
## How it works
|
|
18
|
+
Every message runs through the **rule engine** as it's sent; a rule either lets it through, **blocks** it (hidden immediately), or **flags** it for a moderator. Users can also **report** a message manually, which flags it. Blocked/flagged items land in dashboard queues; a moderator's decision (approve/block/mark reviewed) moves it to the audit trail.
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
send → rules → pass → delivered
|
|
22
|
+
→ block → Blocked Messages
|
|
23
|
+
→ flag → Flagged Messages → moderator → Reviewed Messages (audit)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 1. Configure rules + lists (dashboard / REST)
|
|
27
|
+
- **Rules Management** (`/moderation/rules-management`): turn on the built-in rules you need and set each to **block** or **flag**. Available categories (fetch the current list — it grows):
|
|
28
|
+
- **Text:** word-pattern match (profanity), contact/email removal, spam & scam, platform circumvention, toxicity, hate & harassment, self-harm, explicit content, privacy/sensitive-info, impersonation, violent/terroristic, non-consensual sexual content.
|
|
29
|
+
- **Image:** unsafe/prohibited, minor-safety/CSAM, graphic violence, explicit/sexual, hate symbols, fraud (fake IDs), **malware scan**.
|
|
30
|
+
- **Video / Audio / File:** **malware & virus scan** of attachments.
|
|
31
|
+
- **Lists Management** (`/moderation/lists-management`): your own keyword / regex / sentence lists, linked to rules — this is the "banned words" surface. Lists are reusable across rules.
|
|
32
|
+
- **Programmatic setup:** the **Moderation REST API** (`/rest-api/moderation-apis/overview`) manages rules + keyword lists from your server (e.g. per-tenant config, CI-seeded rules). Fetch its shapes before writing calls.
|
|
33
|
+
|
|
34
|
+
## 2. Wire the client (per family — built into the UI Kit)
|
|
35
|
+
- **Report a message:** the UI Kits ship a built-in **Report Message** action on the message — enable it via that family's moderation feature (`{DOCS_BASE}/ui-kit/<family>/core-features#moderation`; wire through `cometchat-<family>-features`). No hand-rolled report UI.
|
|
36
|
+
- **Blocked content:** rule-blocked messages simply don't render for recipients; nothing extra to build.
|
|
37
|
+
- **SDK path (custom UI / headless):** flag messages directly with the Chat SDK (`{DOCS_BASE}/sdk/<platform>/ai-moderation`) — the per-feature fallback when a family has no drop-in.
|
|
38
|
+
|
|
39
|
+
## 3. Moderator review + audit
|
|
40
|
+
- **Flagged Messages** / **Blocked Messages** dashboards: moderators review, approve false positives, or confirm blocks — and use them to refine rules.
|
|
41
|
+
- **Reviewed Messages** is the **audit trail** of every moderation decision (who did what, when) for compliance records — pair with `cometchat-compliance` for retention/eDiscovery of these records.
|
|
42
|
+
|
|
43
|
+
## Legacy extensions — migrate, don't double-run
|
|
44
|
+
If the app still uses the **legacy extensions** (Profanity Filter, Data Masking, Image Moderation), **disable them before enabling the new moderation rules.** Running both processes every message twice → performance issues and message delays. Treat this as a required migration step, not optional.
|
|
45
|
+
|
|
46
|
+
## Enablement note
|
|
47
|
+
Moderation is a dashboard/plan capability — enable it on the app (and on the **production** app, not just dev). `npx @cometchat/skills-cli@3 features` can toggle app extensions/AI after `auth login`; the rule/list configuration itself is done in the dashboard or via the Moderation REST API.
|
|
48
|
+
|
|
49
|
+
## Common pitfalls
|
|
50
|
+
1. **Legacy extensions left on** alongside new rules — double-processing, delays. Disable the old ones first.
|
|
51
|
+
2. **Rules configured on dev only** — content ships unmoderated in production; enable on the production app.
|
|
52
|
+
3. **Hand-rolling a report button** — the UI Kit already ships Report Message; wire the built-in.
|
|
53
|
+
4. **Block vs flag confused** — block hides immediately (good for clear violations); flag routes to a human (good for borderline). Set each rule deliberately.
|
|
54
|
+
5. **No one watching the queues** — flagged content needs a moderator workflow; wire notifications/ownership.
|
|
55
|
+
6. **Assuming a rule exists** — fetch the current rule catalog; don't promise a category the docs don't list.
|
|
56
|
+
|
|
57
|
+
## Verify it works
|
|
58
|
+
A message with a banned word/keyword is blocked or flagged per the rule · an unsafe image is caught · an attachment is malware-scanned · a user's Report action flags a message into the queue · a moderator decision appears in Reviewed Messages · legacy extensions are off · rules are enabled on the production app.
|
|
@@ -34,7 +34,7 @@ A SHORT, consultative Q&A (clarification contract: ask **and wait**); every ques
|
|
|
34
34
|
1. **Archetype / shape** — `1:1`/marketplace · `support` · `community`/groups · `full-messenger` · `embedded`. Infer from routes (seller/product → `1:1`; `/support` → `support`; `/community`/`/groups` → `community`). "Detected `<signal>` → recommend `<archetype>` — keep or change?"
|
|
35
35
|
2. **Features** — WHICH capabilities (from the detected platform's manifest — `features.json` react-v7 / `features.angular-v5.json` angular-v5 / `features.ios-v5.json` iOS / … — grouped; naming only one hands the wrong menu to every other family): **Core chat** (1:1 + groups, messages, **threads**, media/attachments, typing, receipts, **reactions, mentions** — the last two are ON BY DEFAULT in v7 core, NOT extensions to enable — AUDIT-077) is the recommended default and always included; then offer the add-ons — **voice/video calls · search · polls/stickers · translation · push notifications · AI/smart-replies · moderation · AI agents**. Do NOT list `reactions`/`mentions` as add-ons (they're core), and never offer a `deprecated:true` feature (email-replies · e2e-encryption · live-streaming). **First SUBTRACT what's already present (AUDIT-043)** — `detect`/existing-integration for wired features, and ASK which dashboard-gated extensions are already enabled (the CLI can't read per-app enabled-state); don't re-offer an already-on feature like translation. Ask "core chat + which of these?" Don't ask about individual components/props (the core decides those). **Each chosen feature maps to a UI Kit component where one exists, or an SDK method where it doesn't** (AI agents · campaigns · advanced/AI moderation · bots · webhooks · transient messages → SDK) — the plan's **Feature coverage** section records which, so nothing is silently dropped or hand-rolled.
|
|
36
36
|
3. **Design / theming** — HOW it should look. Present the light/dark MODE and the palette, and **ALWAYS include the AUTO option**: **(a)** **Auto — follow the device's light/dark (OS) setting** — the RECOMMENDED default for a fresh app (whether the kit follows the OS BY ITSELF differs per platform — **iOS does, with no host code, so do not offer to wire it there; web does not** — `references/platforms.md`, AUDIT-004), **(b)** a fixed **light** preset, **(c)** a fixed **dark** preset, **(d)** **match your existing design system** (recommended when discovery detected Tailwind/MUI/Chakra/a token theme — reuse it), **(e)** a **brand palette** (your colors as the platform's theme tokens — CSS custom properties on web, `UIColor`/`dynamicColor` on iOS), or **(f)** a **custom design system**. All map to the UI Kit's theme tokens / `customization`. Recommend from the detected `styling` signal: none → **auto + default tokens**; a design system detected → **auto + match**. **Omitting the auto / follow-system option is a defect (AUDIT-042) — the kit supports it and it's the pack's fresh-app default; never present a light-only menu.**
|
|
37
|
-
4. **Scope / placement** — smallest surface that satisfies the archetype (default) vs. the full combined app;
|
|
37
|
+
4. **Scope / placement** — smallest surface that satisfies the archetype (default) vs. the full combined app; the placement shapes differ by platform (`references/platforms.md`). Default to the SMALLEST reasonable production-ready surface.
|
|
38
38
|
The archetype → capability translation is in `references/archetypes.md`; the feature menu is the DETECTED platform's manifest (`references/platforms.md`) — never offer a feature that platform does not ship. Recommend, don't interrogate.
|
|
39
39
|
|
|
40
40
|
### 3. PLAN — share the FULL plan artifact BEFORE anything is written
|
|
@@ -62,6 +62,9 @@ This skill does **discover + understand + plan**. The framework core does **cred
|
|
|
62
62
|
- Onboarding OWNS: whole-repo discovery, intent elicitation with recommendations, the plan artifact, the modify/approve gate, the scoped directive.
|
|
63
63
|
- The core OWNS (do NOT restate or fork here): credential fetch/provision + env write (`references/setup-credentials.md`), init→login→render, component/prop selection, the production-ready build. It REUSES this discovery (re-reads the same signals + any `.cometchat` config, skips re-setup) — one detection approach, two consumers.
|
|
64
64
|
|
|
65
|
+
## Competitor SDK present (`migrate_from` non-null)
|
|
66
|
+
Name the vendor in the plan and offer the one-prompt migration; on "migrate"/"replace" hand straight to that entry's `skill` (no plan gate — it runs end-to-end). Never install CometChat alongside Sendbird/Stream silently.
|
|
67
|
+
|
|
65
68
|
## Re-entry (already-integrated repo)
|
|
66
69
|
If beat-1 discovery shows CometChat already wired for the current major (`existing_cometchat: true`, no `version_conflict`), do NOT re-run the full journey. Summarize what's already integrated, ask what the user wants to ADD or CHANGE, and route that incremental ask straight to the framework core (or the calls/features/customization skill it names) — onboarding is the FIRST-contact front door, not a gate on every subsequent change.
|
|
67
70
|
|
|
@@ -77,6 +77,21 @@ composite chat component** — the host composes header + list + composer and ow
|
|
|
77
77
|
navigation, so "a chat screen" is a composition task, not a single drop-in. On Android the
|
|
78
78
|
headless calls family is receive-only for screen share and has no virtual background — do not offer either.
|
|
79
79
|
|
|
80
|
+
## Scope / placement (beat 4)
|
|
81
|
+
|
|
82
|
+
The placement vocabulary is platform-specific — offer only the shapes that exist on the detected
|
|
83
|
+
platform, never the web menu everywhere:
|
|
84
|
+
|
|
85
|
+
- **Web (React · Angular):** full-page · **embedded** in an existing route/section · a docked
|
|
86
|
+
**sidebar / side-panel** · a **popup / floating widget**.
|
|
87
|
+
- **Mobile (iOS · Android · React Native · Flutter):** a **full-screen route** · a dedicated **tab** ·
|
|
88
|
+
a **pushed navigation-stack screen** (list → detail) · a **modal / bottom-sheet** · **embedded** as a
|
|
89
|
+
panel inside an existing screen. There is **no sidebar and no popup** on mobile — do not offer them.
|
|
90
|
+
The concrete recipes live in `cometchat-<family>-placement` (iOS also: iPad split view; Android: the
|
|
91
|
+
Activity/Fragment flow per `android_variant`).
|
|
92
|
+
|
|
93
|
+
Default to the SMALLEST reasonable production-ready surface, not the full combined app.
|
|
94
|
+
|
|
80
95
|
## SDK-fallback lookup
|
|
81
96
|
|
|
82
97
|
Per-feature fallback resolves through the DETECTED platform's core docs-map, never React's by
|
|
@@ -42,6 +42,11 @@ npm install @react-native-clipboard/clipboard \
|
|
|
42
42
|
`cd ios && pod install` for bare RN. **A missing native module fails at MOUNT, not at build** — the
|
|
43
43
|
error names a NativeModule, not CometChat, so it reads as unrelated.
|
|
44
44
|
|
|
45
|
+
⚠️ **React Native >= 0.87:** RN removed `InteractionManager` from core and the kit (through 5.5.0)
|
|
46
|
+
still calls it in the composer's iOS send path, so **sending a message throws on iOS** — it builds,
|
|
47
|
+
typechecks and bundles clean. Fix and shim: `cometchat-react-native-troubleshooting` -> *Sending a
|
|
48
|
+
message throws on iOS*.
|
|
49
|
+
|
|
45
50
|
|
|
46
51
|
## Setup & credentials (essentials — full detail: `references/setup-credentials.md`)
|
|
47
52
|
1. **Detect** the project: Expo (`app.json`/`app.config.js`) or bare RN (`metro.config.js`). Reuse an existing `.cometchat/config.json` or env if present — skip re-setup.
|
|
@@ -276,9 +281,9 @@ function SearchScreen({ route, navigation }) {
|
|
|
276
281
|
}
|
|
277
282
|
```
|
|
278
283
|
|
|
279
|
-
> **
|
|
280
|
-
>
|
|
281
|
-
>
|
|
284
|
+
> **Search:** `CometChatSearch` is documented at `{DOCS_BASE}/ui-kit/react-native/search` (fetch it
|
|
285
|
+
> via `references/docs-map.md`); wire `onConversationClicked` / `onMessageClicked` and its `onBack`.
|
|
286
|
+
> (Formerly tracked as gap RN-G1 — the page has since been published.)
|
|
282
287
|
|
|
283
288
|
**Every affordance that is visible by default is wired or hidden.** A tap target that does nothing is
|
|
284
289
|
a defect, and so is an opened surface with no way back — if you open search or a thread, wire its
|
|
@@ -304,6 +309,23 @@ a defect, and so is an opened surface with no way back — if you open search or
|
|
|
304
309
|
- Every emitted symbol appears in `catalogs/rn-v5.json`.
|
|
305
310
|
- Code compiles against the pinned kit: `npm run verify:fences:rn-v5`.
|
|
306
311
|
- Oracles agree with the kit and docs: `npm run verify:sync:rn-v5`.
|
|
312
|
+
- **`tsc --noEmit` in the APP is not clean, and that is not the app's bug.** The kit ships raw
|
|
313
|
+
`src/*.tsx` as its `main`/`module` with no built declarations, so TypeScript follows the import and
|
|
314
|
+
typechecks the kit itself (`NodeJS` namespace, implicit `any`, `isolatedModules` re-exports,
|
|
315
|
+
`User | null`, and on RN 0.87 a `RefObject<TextInputType>` mismatch). Gate on the **Metro bundle**
|
|
316
|
+
instead — `npx react-native bundle --platform ios|android --dev false --entry-file index.js
|
|
317
|
+
--bundle-output /dev/null` — and if you want a typecheck, filter the kit's own files out of the
|
|
318
|
+
output. Never "fix" node_modules, and never report the app as failing typecheck because of them.
|
|
319
|
+
- **Getting the app to actually RUN on a shared machine.** React Native asks for Metro on port 8081
|
|
320
|
+
and takes whatever answers: another project's packager serves a foreign bundle, and the app dies
|
|
321
|
+
with `Invariant Violation: TurboModuleRegistry.getEnforcing('PlatformConstants')` — a version
|
|
322
|
+
mismatch that reads like a missing native module. iOS: point the app at your packager with
|
|
323
|
+
`xcrun simctl spawn <udid> defaults write <bundle-id> RCT_jsLocation "localhost:<port>"`
|
|
324
|
+
(`RCT_METRO_PORT` does not change the runtime URL). Android: `adb reverse tcp:8081 tcp:<port>`, and
|
|
325
|
+
when that silently does nothing — it does on some emulators — embed the bundle instead:
|
|
326
|
+
`npx react-native bundle --platform android --dev false --entry-file index.js --bundle-output
|
|
327
|
+
android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res`, then
|
|
328
|
+
`run-android`. Remove that file before going back to Fast Refresh.
|
|
307
329
|
- On a device: chat fills the screen, the composer survives the keyboard, back works, gestures respond.
|
|
308
330
|
|
|
309
331
|
## Explain what you built (REQUIRED close)
|
|
@@ -93,6 +93,7 @@ tokens, or feature enablement.
|
|
|
93
93
|
| events | `/ui-kit/react-native/events` |
|
|
94
94
|
| calls (UI) | `/ui-kit/react-native/calling-integration` · `call-features` · `call-buttons` · `call-logs` · `incoming-call` · `outgoing-call` |
|
|
95
95
|
| AI / smart replies | `/ui-kit/react-native/ai-features` |
|
|
96
|
+
| search | `/ui-kit/react-native/search` |
|
|
96
97
|
| full-screen recipes | `/ui-kit/react-native/react-native-conversation` · `expo-conversation` |
|
|
97
98
|
| task guides | `/ui-kit/react-native/guide-new-chat` · `guide-group-chat` · `guide-search-messages` · `guide-threaded-messages` · `guide-block-unblock-user` · `guide-message-privately` |
|
|
98
99
|
|
|
@@ -101,7 +102,7 @@ If a needed component/prop/SDK method is NOT covered by the docs, **FLAG it for
|
|
|
101
102
|
(page · section · change · reason) and record it. Do **not** quietly read the kit source and bake the
|
|
102
103
|
answer as if it were documented — that hides the gap and the next agent re-derives it.
|
|
103
104
|
|
|
104
|
-
**Known open gaps for React Native (tracked on ENG-38205 as `RN-G*`):**
|
|
105
|
+
**Known open gaps for React Native (tracked on ENG-38205 as `RN-G*`):**
|
|
105
106
|
reactions undocumented · no per-bubble pages · attachment cluster undocumented · `ConversationStarter`
|
|
106
107
|
/ `SmartReplies` undocumented · the `DataSourceDecorator` chain undocumented · six pages **import
|
|
107
108
|
symbols the kit does not export** · the events page names APIs that do not exist.
|
|
@@ -14,6 +14,7 @@ metadata:
|
|
|
14
14
|
|
|
15
15
|
## Companion skills (read first)
|
|
16
16
|
- `cometchat-react-native-core` — install, provider chain, init→login→render. Assumed, not repeated here.
|
|
17
|
+
- `cometchat-security` — the enterprise auth model this client-side hardening plugs into: wiring your IdP / SSO into the token flow (your IdP → your server → mint the CometChat auth token; CometChat is **not** an IdP), token expiry/refresh + re-login, RBAC roles + group (SBAC) scopes, and Auth Key vs auth token vs REST API Key. Load it for a security review or any SSO question.
|
|
17
18
|
|
|
18
19
|
## Use this skill when
|
|
19
20
|
- "is this safe to ship" · "swap the auth key for a token" · "prepare the release build"
|
|
@@ -71,20 +71,27 @@ is real.
|
|
|
71
71
|
|
|
72
72
|
## Ordering — the invariant
|
|
73
73
|
|
|
74
|
-
`
|
|
75
|
-
Anything else fails quietly rather than throwing.
|
|
74
|
+
Init (`initFromSettings`) must resolve before `login()`. `login()` must resolve before you fetch or
|
|
75
|
+
send. Anything else fails quietly rather than throwing.
|
|
76
76
|
|
|
77
77
|
```tsx
|
|
78
78
|
import { CometChat } from "@cometchat/chat-sdk-react-native";
|
|
79
79
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
80
|
+
// DEFAULT via skills: the ai-agent / telemetry-attributed init — persists integrationSource="ai-agent"
|
|
81
|
+
// (RULES §Ordering), the SDK sibling of the UI Kit's initFromSettings. Web/JS settings-OBJECT form,
|
|
82
|
+
// NOT the classic AppSettingsBuilder + init(APP_ID, settings). initFromSettings is @nodoc (ai-agent-only).
|
|
83
|
+
await CometChat.initFromSettings({
|
|
84
|
+
appId: APP_ID,
|
|
85
|
+
region: REGION,
|
|
86
|
+
credentials: { authKey: AUTH_KEY }, // dev only; prod logs in with an auth token
|
|
87
|
+
chatSDK: { presenceSubscription: { type: "ALL_USERS" } }, // = the old .subscribePresenceForAllUsers()
|
|
88
|
+
});
|
|
87
89
|
await CometChat.login(UID, AUTH_KEY); // dev only; production passes an auth token
|
|
90
|
+
|
|
91
|
+
// FALLBACK only (non-skills / doc-following context) — the publicly-documented classic path:
|
|
92
|
+
// const settings = new CometChat.AppSettingsBuilder()
|
|
93
|
+
// .setRegion(REGION).subscribePresenceForAllUsers().autoEstablishSocketConnection(true).build();
|
|
94
|
+
// await CometChat.init(APP_ID, settings);
|
|
88
95
|
```
|
|
89
96
|
|
|
90
97
|
⚠️ `login` is **variadic and untyped** in the `.d.ts` (`login(...args: any)`), so TypeScript will
|
|
@@ -65,6 +65,64 @@ The navigator's header plus `CometChatMessageHeader`. Set `headerShown: false` o
|
|
|
65
65
|
A fixed height somewhere in the ancestor chain, or the message screen is nested **inside** the tab
|
|
66
66
|
navigator so the tab bar overlaps it. Put the message screen on the stack **above** the tabs.
|
|
67
67
|
|
|
68
|
+
### Sending a message throws on iOS (React Native >= 0.87)
|
|
69
|
+
React Native **0.87 removed `InteractionManager` from core**, and `CometChatMessageComposer` (kit
|
|
70
|
+
through 5.5.0) still calls `InteractionManager.runAfterInteractions()` in four **iOS-only** branches
|
|
71
|
+
of its send path. Tapping send throws and the message never leaves the device. Android is unaffected;
|
|
72
|
+
so is RN <= 0.86, where the export is deprecated but still resolves — which is why the same code
|
|
73
|
+
sends fine on an older app and dies on a fresh template.
|
|
74
|
+
|
|
75
|
+
| Where | What you see |
|
|
76
|
+
|---|---|
|
|
77
|
+
| dev build | `Uncaught Error: InteractionManager has been removed from react-native core. Please refactor long tasks into smaller ones, and use 'requestIdleCallback' instead.` in `CometChatMessageComposer` -> `sendTextMessage` |
|
|
78
|
+
| release build | the same line reads `undefined` -> `TypeError: Cannot read property 'runAfterInteractions' of undefined` |
|
|
79
|
+
| CI | **nothing** — it typechecks, bundles and builds on both platforms; only a person tapping send sees it |
|
|
80
|
+
|
|
81
|
+
Until the kit drops the call, restore a minimal implementation **before the kit loads** — the first
|
|
82
|
+
import in `index.js`:
|
|
83
|
+
|
|
84
|
+
```js
|
|
85
|
+
// interactionManagerCompat.js — delete when the kit stops calling InteractionManager.
|
|
86
|
+
const ReactNative = require('react-native');
|
|
87
|
+
|
|
88
|
+
const missing = () => {
|
|
89
|
+
try {
|
|
90
|
+
return !ReactNative.InteractionManager;
|
|
91
|
+
} catch {
|
|
92
|
+
return true; // RN >= 0.87 in __DEV__: the getter throws.
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
if (missing()) {
|
|
97
|
+
Object.defineProperty(ReactNative, 'InteractionManager', {
|
|
98
|
+
configurable: true,
|
|
99
|
+
get: () => ({
|
|
100
|
+
runAfterInteractions: (task) => {
|
|
101
|
+
const run = () => (typeof task === 'function' ? task() : task && task.gen && task.gen());
|
|
102
|
+
let settle;
|
|
103
|
+
const ran = new Promise((resolve) => { settle = resolve; });
|
|
104
|
+
const timer = setTimeout(() => { run(); settle(); }, 0); // resolve AFTER the task runs
|
|
105
|
+
return {
|
|
106
|
+
then: (onResolve, onReject) => ran.then(onResolve, onReject),
|
|
107
|
+
done: (onDone) => { ran.then(onDone); },
|
|
108
|
+
cancel: () => clearTimeout(timer),
|
|
109
|
+
};
|
|
110
|
+
},
|
|
111
|
+
createInteractionHandle: () => 0,
|
|
112
|
+
clearInteractionHandle: () => {},
|
|
113
|
+
setDeadline: () => {},
|
|
114
|
+
addListener: () => ({ remove: () => {} }),
|
|
115
|
+
}),
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### `ReferenceError: Property '<name>' doesn't exist` right after a `try`/`catch`
|
|
121
|
+
Hermes loses a `catch (error)` binding that is only read inside a closure created in the same block —
|
|
122
|
+
`catch (error) { setLogs((prev) => [describe(error), ...prev]) }` throws the first time the catch
|
|
123
|
+
runs, while the identical code with the value read first works. It typechecks and bundles either way.
|
|
124
|
+
Read the caught value into a local, then use the local inside the closure.
|
|
125
|
+
|
|
68
126
|
### Calls do not ring
|
|
69
127
|
| Cause | Fix |
|
|
70
128
|
|---|---|
|
|
@@ -49,7 +49,7 @@ Init/provider: `CometChatUIKit`, `UIKitSettingsBuilder`, `CometChatProvider`, `C
|
|
|
49
49
|
|
|
50
50
|
## Hot-path props (BAKED — the golden path needs NO fetch)
|
|
51
51
|
The ~12 props you actually wire for "add chat". Do NOT fetch docs for these; do NOT read `.d.ts`.
|
|
52
|
-
- `CometChatConversations`: `onItemClick(conversation)` (select → drives the message pane) · `activeConversation` · `showSearchBar` (default `true`; wire `onSearchBarClicked`→`CometChatSearch` or set `false`) · `selectionMode` (default `"none"`) · `conversationsRequestBuilder` — **scope the list to the REQUEST**: a 1:1/DM-only ask → `new CometChat.ConversationsRequestBuilder().setConversationType("user")` so the app's seeded groups don't show (`"group"` for groups-only); pass the builder INSTANCE, not `.build()`. See the data-scope note below.
|
|
52
|
+
- `CometChatConversations`: `onItemClick(conversation)` (select → drives the message pane) · `activeConversation` · `showSearchBar` (default `true`; wire `onSearchBarClicked`→`CometChatSearch` or set `false`) · `selectionMode` (default `"none"`) · `conversationsRequestBuilder` — **scope the list to the REQUEST**: a 1:1/DM-only ask → `new CometChat.ConversationsRequestBuilder().setLimit(30).setConversationType("user")` so the app's seeded groups don't show (`"group"` for groups-only); pass the builder INSTANCE, not `.build()`. **`.setLimit(n)` is REQUIRED on a custom builder** — without it the list renders the kit's "something went wrong" state (verified 7.2.0, AUDIT-245; STOPGAP: the docs' filter-recipe table omits it — remove this note once that docs recipe is fixed). See the data-scope note below.
|
|
53
53
|
- `CometChatMessageHeader`: `onItemClick` (open profile) · `showSearchOption` (default `true`) + `onSearchOptionClicked` → **open a SCOPED `CometChatSearch` (`uid`/`guid` of the current chat) in the side panel (in-chat message search, default-on; opt-out via `showSearchOption={false}`)** · `hideBackButton` (default `false`) + `onBack` (mobile → pop to list).
|
|
54
54
|
- `CometChatMessageList`: `onThreadRepliesClick(message)` → **open the thread panel (DEFAULT — threaded replies ship with a first-time "add chat")**; `hideReplyInThreadOption` ONLY if the user explicitly opts out of threads.
|
|
55
55
|
- `CometChatMessageComposer`: `placeholder` (default `"Type a message..."`); a plain send needs no props.
|
|
@@ -64,7 +64,7 @@ Wire every default-on affordance so nothing dead-ends, and keep these INVARIANTS
|
|
|
64
64
|
- **Threads are DEFAULT** (ship with a first-time "add chat"). Wire `CometChatMessageList onThreadRepliesClick(m)` → a thread panel (`CometChatThreadHeader` + a thread `CometChatMessageList` + `CometChatMessageComposer`) with a close/back round-trip. **The thread list AND composer take BOTH the current target (`user` OR `group`, same as the main pane) AND `parentMessageId`; passing `parentMessageId` ALONE silently NEVER SENDS (AUDIT-060).** Set `hideReplyInThreadOption` only on explicit opt-out. **Differentiate the thread MESSAGE LIST** (not just the wrapper): scope `--cometchat-message-list-bg: var(--cometchat-background-color-01)` on the thread wrapper — the list paints its own opaque bg so a wrapper bg can't reach it (verified vs 7.1.0; recipe in `cometchat-react-v7-customization`).
|
|
65
65
|
- **Two searches, both default-on, both need the FULL round-trip (AUDIT-017).** GLOBAL conversation search over the LIST column (`CometChatConversations onSearchBarClicked` → `CometChatSearch`, no uid/guid — or `showSearchBar={false}`); IN-CHAT scoped search in the SIDE PANEL (`CometChatMessageHeader showSearchOption` default `true` → `onSearchOptionClicked` → `CometChatSearch` with the current `uid`/`guid`, mutually exclusive with the thread). Each renders a back button (`onBack`) you MUST wire to close + return, PLUS `onConversationClicked`/`onMessageClicked` to select the hit — a companion you open, you must also close. (Real server-side search may also need a Dashboard toggle — VERIFY.)
|
|
66
66
|
- **SIZE per the ONE standard — `references/layout.md`.** The kit fills its parent and ships its own `loadingView`/`emptyView`, so a broken-looking surface is a HOST container-sizing defect (a content-driven box), not a kit bug — two modes: static collapse (~0px sliver) and load-transition reflow (grows into place as content loads). Satisfy the 5 invariants: prepare/RESET the ancestor chain (`html,body,#root{height:100%;margin:0}` + undo the Vite/CRA/Next scaffold center+cap+pad, AUDIT-019/035) · pin the surface to a content-INDEPENDENT `100dvh` (never `min-height`/`auto`) · size COLUMNS with `min-height:0`/`overflow:hidden` (scroll, don't grow the parent) · let the kit loading state fill the pinned box · no `transform`/`filter` ancestors. The 2-column CSS is in `layout.md`; the 3-column/embedded/popup/sidebar recipes in `cometchat-react-v7-placement`. Keep `CometChatProvider` WRAPPING `.cc-app`, not inside it (the `.cometchat` wrapper breaks the row — AUDIT-036).
|
|
67
|
-
- **Match data scope to the REQUEST (AUDIT-038).** A 1:1/DM-only ask must NOT show the app's seeded groups — scope with the built-in `conversationsRequestBuilder` prop (pass the `CometChat.ConversationsRequestBuilder` INSTANCE, `.setConversationType("user")
|
|
67
|
+
- **Match data scope to the REQUEST (AUDIT-038).** A 1:1/DM-only ask must NOT show the app's seeded groups — scope with the built-in `conversationsRequestBuilder` prop (pass the `CometChat.ConversationsRequestBuilder` INSTANCE, `.setLimit(30).setConversationType("user")` — `setLimit` required; `"group"` for groups-only; **reuse the prop, don't hand-roll a client-side filter**), and scope the selector to match (no Groups tab on a 1:1-only app). A generic unscoped "add chat" keeps BOTH. Example in `references/component-props.md`.
|
|
68
68
|
- **Theme:** the kit defaults to `light` and does NOT follow the OS (no `theme="system"`) — sync `CometChatProvider theme=` to `prefers-color-scheme` by default (`references/theming.md`, AUDIT-004).
|
|
69
69
|
- **Reuse built-in triggers — don't hand-roll buttons (AUDIT-006).** Wire the props components already expose; custom UI goes IN the component's view slot (search icon → Conversations `headerView` / MessageHeader `trailingView`), NEVER a sibling on top (slot map: `references/component-props.md`). Unclear prop → fetch its `.md` twin (`references/docs-map.md`), never the `.d.ts`.
|
|
70
70
|
- **`CometChatErrorBoundary` wraps the surface** (children required; optional `onError`/`fallbackView`/`componentName`) — a render error then shows a localized fallback + retry, not a blank white screen. It is NOT the initializer (init/login still happen first). Leave header call buttons + composer attach/emoji/voice as built-in defaults; do NOT turn on gated extensions/AI/plugins; do NOT add selector tabs / a details or scoped-search side panel / call logs / incoming call (those are the GROWTHS) unless asked — **but the thread panel IS part of the default.** **Prod auth: `loginWithAuthToken` with a per-user server-minted token; the Auth Key is dev-only** (`references/lifecycle.md`).
|
|
@@ -77,12 +77,12 @@ Wire every default-on affordance so nothing dead-ends, and keep these INVARIANTS
|
|
|
77
77
|
- `references/layout.md` — **the ONE reflow-free-surface sizing standard** (the 5 invariants: prepared ancestor chain · pinned content-independent height · `min-height:0` columns · kit loading state inside the pinned box = NO load-transition reflow · no `transform`/`filter` ancestors). `placement` + `calls` reference it too — change sizing rules HERE.
|
|
78
78
|
- `references/ssr.md` — Next.js / Astro / React Router SSR safety (`"use client"`, `ssr:false`, `client:only`).
|
|
79
79
|
- `references/theming.md` — CSS import-once + `--cometchat-*` variables (depth: `cometchat-react-v7-customization`).
|
|
80
|
-
-
|
|
80
|
+
- Localization / RTL / accessibility → the cross-family **`cometchat-i18n`** + **`cometchat-a11y`** skills. Don't render a raw key (`group_info`) — the provider auto-wires localization. React theme tokens: `references/theming.md`.
|
|
81
81
|
- `references/anti-patterns.md` — the 15 real-bug anti-patterns (incl. `transform`/Tailwind overlay bug, container dimensions, **scaffold-boilerplate** = centered/capped/gutter-boxed chat (#15), **global-CSS-leak** = centered names / expanding header, **raw-i18n-key** rendering).
|
|
82
82
|
- `references/dependencies.md` — packages, major pins, `CometChat.*` SDK types, bundle-size cost transparency.
|
|
83
83
|
- `references/component-props.md` — **BAKED stable props + view slots** for the 4 drop-ins (where custom UI goes IN each component — search → Conversations `headerView`, MessageHeader `trailingView`, etc.).
|
|
84
84
|
- `references/docs-map.md` — intent → the exact docs `.md` twin to fetch (replaces reading `.d.ts`); **for a whole feature/task, its "Task guides (recipes)" section says to BUILD FROM the official guide + COMPARE your implementation against it (docs-maximal), then apply the hardening deltas.**
|
|
85
|
-
-
|
|
85
|
+
- Symptom → cause → fix (blank screen, SSR `window is not defined`, ~0px collapse, kit error state, empty lists, events not firing, `version_conflict`) → the **`cometchat-react-v7-troubleshooting`** skill.
|
|
86
86
|
|
|
87
87
|
> **Visual Builder (VCB) is out of scope.** If asked to integrate a VCB export, point to the CometChat Visual Builder docs (via `references/docs-map.md`); don't hand-roll a builder-export flow.
|
|
88
88
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
10. **Don't invent component names** — check `cometchat-react-v7-components` (and `web-v7.json`). A wrong name (e.g. `<CometChatMessenger>`) is a build error.
|
|
13
13
|
11. **No `transform` on a container wrapping chat** — a non-`none` `transform` creates a containing block for `position: fixed` descendants; the UI Kit renders overlays (options menu, emoji picker, file preview, reactions, thread panel) as `position: fixed` and expects them anchored to the viewport. **This includes Tailwind `translate-x-*`/`-translate-y-*`/`scale-*`/`rotate-*`/`transition-transform`** — all compile to `transform` and clip/offset the overlays. Also `filter`, `perspective`, `backdrop-filter`, `will-change: transform`. **Fix:** animate `right`/`left` offset (or `margin-right`) instead of transform — in Tailwind toggle `right-0` ↔ `right-[-420px]` with `transition-[right]`. See `cometchat-react-v7-placement` drawer/widget patterns.
|
|
14
14
|
12. **Don't let host global CSS leak into the `.cometchat` subtree.** The kit's layout is self-contained and correct by default (verified vs 7.1.0): `.cometchat-conversations__header` is `flex-shrink:0` / `min-height:64px` (fixed — **NOT `flex:1`**), `.cometchat-conversations__list` is `flex:1`, and list-item titles are **left-aligned**. So if the **conversations header expands to fill height**, or **list-item names render centered**, the cause is a global style bleeding onto kit elements — a `text-align:center` / `align-items:center` / `flex:1` / CSS reset / Tailwind base on an ancestor — or an override of an internal class, NOT the kit. **Fix:** scope global CSS away from the `.cometchat` subtree (no `text-align`/flex-centering/`flex` on the kit's ancestors), never override the internal BEM classes (`.cometchat-*__header`/`__item-*`/`__list` — customize via `--cometchat-*` vars + view slots, #7), and give the mount container an explicit height so `.cometchat-conversations__root { height:100% }` resolves (#8).
|
|
15
|
-
13. **Never render a raw localization key as a label** — the kit localizes via `CometChatProvider`; a snake_case token in the UI (`group_info`, `add_members`) is a missing/wrong key or a literal-key render. Use the kit component or `useLocale().getLocalizedString(key)`. See `i18n
|
|
15
|
+
13. **Never render a raw localization key as a label** — the kit localizes via `CometChatProvider`; a snake_case token in the UI (`group_info`, `add_members`) is a missing/wrong key or a literal-key render. Use the kit component or `useLocale().getLocalizedString(key)`. See the `cometchat-i18n` skill.
|
|
16
16
|
14. **Don't `import { CometChat }` just for types** — the SDK namespace is an **ambient global**, so `CometChat.User`/`CometChat.Group`/`CometChat.BaseMessage` resolve as types with NO import. A value import used only in type positions fails the Vite React-TS template's strict config (`noUnusedLocals` + `verbatimModuleSyntax`) with `TS6133: 'CometChat' is declared but its value is never read` — and `import type { CometChat }` does **not** fix it (the type comes from the global, not the import). **Rule:** import `CometChat` **only** when you use it as a value (`msg instanceof CometChat.User`, `CometChat.CometChatHelper.getConversationFromMessage(...)`, `new CometChat.GroupMembersRequestBuilder(...)`); for type-only usage, drop the import and use the ambient global. (AUDIT-007.)
|
|
17
17
|
15. **Full-page chat: clear the scaffold boilerplate CSS (the #2 "UI looks broken" defect).** A fresh Vite/CRA/Next app ships template CSS that **centers, width-caps, and pads the root** — Vite's `#root { max-width:1280px; margin:0 auto; padding:2rem; text-align:center }` + `body { display:flex; place-items:center }` (CRA `App.css`, Next `globals.css` have analogues). Drop a `100dvh` chat surface into that and it renders as a **centered ~1280px padded box with big side gutters, message bubbles/overlays clipping off the edge** ("exceeding the viewport / broken"). **Fix:** before the chat CSS, reset it — `html, body, #root { height:100%; margin:0; padding:0 }` + `#root { max-width:none; text-align:left; display:block }` + remove `body{place-items:center}`; give `.cc-app` `overflow:hidden` and the message column `min-width:0; min-height:0; overflow:hidden`. (Verified reproduction: a capped/centered `#root` shoves chat into a ~729px gutter-boxed island; the reset makes it full-bleed. AUDIT-019.) This is invariant (a) of the reflow-free-surface standard — full rule + the load-transition-reflow mode: `layout.md`.
|
|
18
18
|
16. **Don't expect an OPAQUE kit sub-surface to inherit a wrapper's background — override the sub-surface's OWN CSS variable.** `.cometchat-message-list` paints an opaque `background: var(--cometchat-message-list-bg)` (default `--cometchat-background-color-03`), so a background set on a wrapping `div` is COVERED by the list and never shows — the list stays the same shade regardless of the wrapper. Canonical case: the **thread panel** — its header/composer paint their own opaque `--cometchat-background-color-01`, so the thread message list looks like the MAIN list (both `-03`) and different from its own header/composer, even after you give the thread wrapper a background. **Fix:** scope the surface's OWN token on the wrapper — `.cc-thread-panel { --cometchat-message-list-bg: var(--cometchat-background-color-01); }` (cascades into the list; matches the thread header/composer, differs from the main list's `-03`; verified vs 7.1.0). Generalizes to any opaque sub-surface: differentiate it by overriding ITS background variable, not the wrapper's, and never the internal `.cometchat-*` class (#7/#12). (AUDIT-020/024; depth: `cometchat-react-v7-customization`.)
|
|
@@ -38,7 +38,7 @@ message header instead of in its `trailingView`, is a defect — fix it by using
|
|
|
38
38
|
- `options(conversation) => CometChatConversationOption[]` — per-row context-menu actions.
|
|
39
39
|
- `loadingView` · `emptyView` · `errorView` — list states.
|
|
40
40
|
> **Search icon in the conversation list header → put it in `headerView`** (or wire `onSearchBarClicked` → `CometChatSearch` rendered in the list column). NOT a sibling on top of the list.
|
|
41
|
-
> **Scope the list to the request via `conversationsRequestBuilder` (a `CometChat.ConversationsRequestBuilder`).** A **1:1 / DM-only** app → `.setConversationType("user")` (hides the app's seeded groups); **groups-only** → `.setConversationType("group")`. **Pass the builder INSTANCE, not `.build()`** — the kit builds it internally; passing the built object breaks the list (verified vs live v7 `conversations.md`: "Pass the builder instance — not the result of `.build()`"; AUDIT-038). `searchRequestBuilder` scopes server-side search the same way. A generic unscoped "add chat" → OMIT it (show both users and groups). Don't add a Groups tab to a 1:1-only app.
|
|
41
|
+
> **Scope the list to the request via `conversationsRequestBuilder` (a `CometChat.ConversationsRequestBuilder`).** A **1:1 / DM-only** app → `.setLimit(30).setConversationType("user")` (hides the app's seeded groups); **groups-only** → `.setLimit(30).setConversationType("group")`. **Always include `.setLimit(n)`** — a builder without it renders the kit's error state instead of the list (verified 7.2.0, 2026-09-12, AUDIT-245; STOPGAP until the docs' filter-recipe table adds it). **Pass the builder INSTANCE, not `.build()`** — the kit builds it internally; passing the built object breaks the list (verified vs live v7 `conversations.md`: "Pass the builder instance — not the result of `.build()`"; AUDIT-038). `searchRequestBuilder` scopes server-side search the same way. A generic unscoped "add chat" → OMIT it (show both users and groups). Don't add a Groups tab to a 1:1-only app.
|
|
42
42
|
> ```tsx
|
|
43
43
|
> import { CometChat } from "@cometchat/chat-sdk-javascript";
|
|
44
44
|
> <CometChatConversations conversationsRequestBuilder={new CometChat.ConversationsRequestBuilder().setLimit(30).setConversationType("user")} />
|
|
@@ -107,18 +107,10 @@ internals; scope it away and customize via `--cometchat-*` vars + view slots (an
|
|
|
107
107
|
|
|
108
108
|
## The minimal full-page recipe (put it BEFORE the chat CSS)
|
|
109
109
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
body { display: block; place-items: normal; }
|
|
115
|
-
*, *::before, *::after { box-sizing: border-box; }
|
|
116
|
-
/* (b) pin the surface + (c) size the columns (min-height:0 = scroll, don't grow) */
|
|
117
|
-
.cc-app { display: flex; height: 100dvh; width: 100%; overflow: hidden; }
|
|
118
|
-
.cc-app .list-column { width: 320px; flex-shrink: 0; height: 100%; }
|
|
119
|
-
.cc-app .message-pane { flex: 1 1 0; min-width: 0; min-height: 0; height: 100%;
|
|
120
|
-
display: flex; flex-direction: column; overflow: hidden; }
|
|
121
|
-
```
|
|
110
|
+
Assemble the three CSS blocks above in order — (a) prepare/RESET the ancestor chain FIRST,
|
|
111
|
+
then (b) pin `.cc-app` to `100dvh`, then (c) size the columns with `min-height:0` (= scroll,
|
|
112
|
+
don't grow). That exact stack (nothing more) is the full-page recipe.
|
|
113
|
+
|
|
122
114
|
For the grown three-column app the same invariants hold with an extra `.side-column`
|
|
123
115
|
(fixed-ish width, `height:100%`, `min-height:0`) — the full 3-column CSS is in
|
|
124
116
|
`cometchat-react-v7-placement` (the Combined-app recipe), which references THIS standard for
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cometchat-react-v7-production
|
|
3
|
+
description: "Ship a CometChat React v7 integration safely — server-minted auth tokens instead of the Auth Key, correct env prefixes per bundler, bundle hygiene, and a pre-launch checklist. Triggers: 'is this production ready', 'auth token instead of auth key react', 'secure my cometchat react setup', 'production build config react', 'going live checklist react', 'harden cometchat before launch'."
|
|
4
|
+
license: "MIT"
|
|
5
|
+
compatibility: "@cometchat/chat-uikit-react ^7 (7.1.x–7.2.x verified); React 18–19; Vite / Next.js / CRA / React Router / Astro"
|
|
6
|
+
metadata:
|
|
7
|
+
author: "CometChat"
|
|
8
|
+
version: "1.0.0"
|
|
9
|
+
tags: "cometchat react v7 production security auth-token hardening deployment"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
> **Ground truth:** `@cometchat/chat-uikit-react@7`. The auth-token / login API is FETCHED from the docs via `cometchat-react-v7-core/references/docs-map.md` (`/ui-kit/react/integration-react` + the JS SDK auth pages); the REST auth-token endpoint is `{DOCS_BASE}/rest-api/auth-tokens`. **The React UI Kit docs have no single production-hardening page** — this checklist is the pack's own guidance from `RULES.md` §4 (Credentials) + what the kit ships, labelled as such, not presented as documented. Tracked DOCS GAP.
|
|
13
|
+
|
|
14
|
+
## Companion skills (read first)
|
|
15
|
+
- `cometchat-react-v7-core` — `references/setup-credentials.md` + `references/lifecycle.md` cover the dev credential flow this replaces and the init→login→render order.
|
|
16
|
+
- `cometchat-react-v7-patterns` — the per-bundler env prefix + build specifics referenced below.
|
|
17
|
+
- `cometchat-security` — the enterprise auth model this client-side hardening plugs into: wiring your IdP / SSO into the token flow (your IdP → your server → mint the CometChat auth token; CometChat is **not** an IdP), token expiry/refresh + re-login, RBAC roles + group (SBAC) scopes, and Auth Key vs auth token vs REST API Key. Load it for a security review or any SSO question.
|
|
18
|
+
|
|
19
|
+
## Use this skill when
|
|
20
|
+
Moving off the development setup: going live, a security review, or "is this safe to ship."
|
|
21
|
+
|
|
22
|
+
## The one thing that matters
|
|
23
|
+
**Never ship the Auth Key in the browser bundle.**
|
|
24
|
+
|
|
25
|
+
The Auth Key can mint a session for **any user in your app**. Every `VITE_`/`NEXT_PUBLIC_`/`REACT_APP_`/`PUBLIC_`-prefixed value is compiled into JavaScript your users download — so an Auth Key there is public. Anyone can read it, log in as any UID, and read every conversation.
|
|
26
|
+
|
|
27
|
+
| | Development | Production |
|
|
28
|
+
| --- | --- | --- |
|
|
29
|
+
| Login | `CometChatUIKit.login(uid)` | `CometChatUIKit.loginWithAuthToken(token)` |
|
|
30
|
+
| Auth Key | in the client env | **absent from the bundle** |
|
|
31
|
+
| Token source | n/a | your backend, per authenticated user |
|
|
32
|
+
| REST API Key | never client-side | server only |
|
|
33
|
+
|
|
34
|
+
## The production login flow
|
|
35
|
+
1. Your app authenticates the user (your own auth — CometChat is not an identity provider).
|
|
36
|
+
2. Your **server** calls CometChat's REST API with the **REST API Key** to mint an auth token for that user's UID (`{DOCS_BASE}/rest-api/auth-tokens`).
|
|
37
|
+
3. The server returns the token to the browser over an authenticated request.
|
|
38
|
+
4. The app calls `loginWithAuthToken(token)`.
|
|
39
|
+
|
|
40
|
+
```tsx
|
|
41
|
+
// the endpoint derives the UID from the SERVER session — never from a query param
|
|
42
|
+
const res = await fetch("/api/cometchat-token", { credentials: "include" });
|
|
43
|
+
const { authToken } = await res.json();
|
|
44
|
+
await CometChatUIKit.loginWithAuthToken(authToken);
|
|
45
|
+
```
|
|
46
|
+
Accepting `?uid=` (or any client-supplied UID) lets a caller impersonate anyone. The UID must come from the server-side session.
|
|
47
|
+
|
|
48
|
+
## Env prefix — do NOT ship the key
|
|
49
|
+
Init reads the Auth Key from the client env in development. Production must set it empty and log in with a token instead. The prefix is bundler-specific (`cometchat-react-v7-patterns`): Vite `VITE_`, Next `NEXT_PUBLIC_` (`.env.local`), CRA `REACT_APP_`, Astro `PUBLIC_`. App ID and Region are not secrets — they identify the app; the Auth Key is the secret. **Grep the built bundle to be certain:**
|
|
50
|
+
```bash
|
|
51
|
+
npm run build && grep -rll "<your-auth-key>" dist/ build/ .next/ 2>/dev/null && echo "LEAK" || echo "clean"
|
|
52
|
+
```
|
|
53
|
+
Run that in CI — a stray `.env` or a wrong prefix ships the key silently.
|
|
54
|
+
|
|
55
|
+
## Also before launch
|
|
56
|
+
- **Users are created server-side**, as part of your signup — not from the browser (no `createUser` with the Auth Key in client code).
|
|
57
|
+
- **Log out properly**: `await CometChatUIKit.logout()`, then clear derived React state and unregister push tokens (`cometchat-react-v7-push`).
|
|
58
|
+
- **HTTPS everywhere** — required for calls (`getUserMedia`) and push.
|
|
59
|
+
- **Pin the kit** to an exact or `~` range so a minor cannot change component behaviour under you.
|
|
60
|
+
- **Keep `CometChatErrorBoundary`** wrapping the surface so a render error shows a fallback, not a white screen (it is not the initializer — init/login still run first).
|
|
61
|
+
- **SSR/StrictMode:** guard init+login so React 18/19 StrictMode's double-invoke does not race two logins (`cometchat-react-v7-patterns`); never init during SSR — gate on the client.
|
|
62
|
+
- **Region must match** the dashboard app in every build.
|
|
63
|
+
- **Enable dashboard extensions/AI on the PRODUCTION app**, not just dev.
|
|
64
|
+
|
|
65
|
+
## Pre-launch checklist
|
|
66
|
+
- [ ] Auth Key absent from the production bundle (grep-verified in CI)
|
|
67
|
+
- [ ] `loginWithAuthToken` in production; UID from the server session
|
|
68
|
+
- [ ] REST API Key server-side only
|
|
69
|
+
- [ ] Correct env prefix for the bundler; `.env` gitignored
|
|
70
|
+
- [ ] HTTPS, valid certificate
|
|
71
|
+
- [ ] Logout clears session, React state and push tokens
|
|
72
|
+
- [ ] Kit version pinned; `CometChatErrorBoundary` in place
|
|
73
|
+
- [ ] Dashboard extensions/AI enabled for the production app
|
|
74
|
+
- [ ] Tested against the production app's credentials
|
|
75
|
+
|
|
76
|
+
## Common pitfalls
|
|
77
|
+
1. **Auth Key in the production bundle** — the critical one; wrong env prefix is the usual cause.
|
|
78
|
+
2. **Token endpoint trusting a client-supplied UID** — impersonation.
|
|
79
|
+
3. **Init/login run during SSR or twice under StrictMode** — races and "already logged in" errors.
|
|
80
|
+
4. **Dashboard configured on the dev app only** — features silently missing in production.
|
|
81
|
+
5. **No logout teardown** — the next user inherits the session or the push token.
|
|
82
|
+
|
|
83
|
+
## Verify it works
|
|
84
|
+
Production build contains no Auth Key (grep) · login works via token · a tampered UID is rejected by the server · logout fully clears · calls and push work over HTTPS · features enabled on the production app.
|