{"id":"28c00df2-933c-4cae-9c83-a65c9b7197c2","shortId":"hX8MX6","kind":"skill","title":"cometchat-angular-features","tagline":"Feature catalog for Angular — calls (separate SDK), extensions (polls / stickers / translation / link preview / collaborative doc / whiteboard), AI features (smart replies / conversation summary / conversation starter), AI agent. Six-bucket taxonomy: default / extension / ai-feat","description":"## Purpose\n\nTeaches Claude how to add features on top of a working CometChat Angular integration. Classifies each feature into one of four types and gives the correct recipe for each.\n\n**Read `cometchat-angular-core` + `cometchat-angular-components` + `cometchat-angular-patterns` first** — a base integration must already exist before features layer on.\n\nGround truth: `docs/ui-kit/angular/core-features`, `docs/ui-kit/angular/calling-integration`, `docs/ui-kit/angular/extensions`, `docs/ui-kit/angular/guide-ai-agent`, and `@cometchat/chat-uikit-angular@4.x` exports.\n\n---\n\n## 1. Feature taxonomy\n\nEvery CometChat feature falls into exactly one of four categories:\n\n| Category | What it means | Example features | How to enable |\n|---|---|---|---|\n| **Default** | Already on — no action needed. Shipped with the kit's base components. | Instant messaging, typing indicators, read receipts, reactions, replies, @mentions, media upload, edit/delete, message info | Just render `<cometchat-message-header>` + `<cometchat-message-list>` + `<cometchat-message-composer>` |\n| **Extension** | Boolean backend toggle. CLI flips it via the dashboard API. UI Kit auto-wires once enabled. | Polls, stickers, message translation, link preview, collaborative doc/whiteboard, thumbnail generation | `cometchat apply-feature <id> --app-id <X>` → hard-reload |\n| **AI feature** | Backend AI toggle that requires an OpenAI API key. CLI sets the key + flips the toggle. | Smart replies, conversation summary, conversation starter | `cometchat apply-feature smart-replies --app-id <X> --openai-key sk-…` |\n| **Dashboard-only** | Third-party API key / multi-field config the user has to supply. CLI cannot automate. | Giphy, Stipop, Tenor, Chatwoot, Intercom, Disappearing Messages, Message Shortcuts | Open https://app.cometchat.com → Extensions |\n| **Package-install** | Install an additional npm package. The UI Kit auto-detects the package on next init. | Voice + video calls (`@cometchat/calls-sdk-javascript`) | `npm install ...` → rebuild |\n| **Component-swap** | Replace or wrap a UI Kit component with a customized version. | Custom text formatter, custom message templates, AI Agent chat history | Write a new component + pass via Angular input |\n\n---\n\n## 2. Enabling extension and AI features (`apply-feature`)\n\nAngular projects don't go through `cometchat apply` (no `.cometchat/state.json`), so always pass `--app-id <id>` explicitly. The CLI hits the dashboard API using the bearer from `cometchat auth login`.\n\n### Extension features\n\n```bash\ncometchat apply-feature polls --app-id <your-app-id>\ncometchat apply-feature link-preview --app-id <your-app-id>\n```\n\n### AI features (smart replies, conversation summary, conversation starter)\n\nThese need an OpenAI API key on the app. The CLI sets the key + flips the toggle in one call:\n\n```bash\ncometchat apply-feature smart-replies --app-id <your-app-id> --openai-key sk-...\n```\n\nThe key is stored on the app once, so subsequent ai-feature applies don't need `--openai-key` repeated. Get one at https://platform.openai.com/api-keys.\n\n### Response shapes\n\n- `\"status\": \"applied\"` → done. Hard-reload the Angular dev server.\n- `\"status\": \"already-applied\"` → already in the desired state.\n- `\"status\": \"auth-required\"` → `cometchat auth login` first.\n- `\"status\": \"openai-key-required\"` → re-run with `--openai-key sk-…`.\n- `\"status\": \"manual-action-required\"` → dashboard-only feature (Giphy, Stipop, Tenor, Chatwoot, Intercom, message-shortcuts, disappearing-messages). Surface `next_steps` verbatim — these need third-party config.\n- `\"status\": \"error\"` → surface `next_steps`.\n\n### Dashboard fallback\n\nOnly when the CLI returns `error` or isn't available:\n1. https://app.cometchat.com → your app\n2. Chat & Messaging → Features\n3. Find the extension by name → flip Status ON\n4. Hard-reload the Angular app (`ng serve` restart or browser refresh)\n\n### What each toggle does\n\n| Extension | UI surface when enabled |\n|---|---|\n| Polls | Polls option in `<cometchat-message-composer>`'s attachment menu |\n| Stickers | Sticker picker in the composer |\n| Smart replies | Chip suggestions above the composer input after an incoming message |\n| Message translation | \"Translate\" option in the message long-press menu |\n| Link preview | Rich-card bubble for URLs in the message list |\n| Collaborative document | Option in composer's attachment menu; opens a shared doc on click |\n| Collaborative whiteboard | Option in composer's attachment menu; opens a shared canvas |\n| Thumbnail generation | Image / video bubbles show thumbnails instead of full-size downloads |\n\n### Gotcha — `auto_wired_in_uikit: false`\n\nA minority of extensions need extra wiring via the `extensions` field on `UIKitSettingsBuilder`. The CLI flags this in its success response:\n\n```json\n{\n  \"status\": \"enabled\",\n  \"name\": \"stickers\",\n  \"auto_wired_in_uikit\": false,\n  \"next_steps\": [\"Pass the extension via the extensions field on UIKitSettingsBuilder\"]\n}\n```\n\nIf `auto_wired_in_uikit` is `false`, import the matching `ExtensionsDataSource` and pass it via `.setExtensions()` on the builder:\n\n```typescript\nimport { UIKitSettingsBuilder } from \"@cometchat/uikit-shared\";\nimport { StickersExtension, PollsExtension } from \"@cometchat/chat-uikit-angular\";\n\nconst settings = new UIKitSettingsBuilder()\n  .setAppId(APP_ID)\n  .setRegion(REGION)\n  .setAuthKey(AUTH_KEY)\n  .setExtensions([new StickersExtension(), new PollsExtension()])\n  .build();\n```\n\n---\n\n## 3. Calls (package-install)\n\nCalls require the separate `@cometchat/calls-sdk-javascript` package.\n\n### 3a — Install the calls SDK\n\n```bash\nnpm install @cometchat/calls-sdk-javascript\n```\n\nNo native peer deps needed for web (unlike React Native). Rebuild the Angular app after installing.\n\n### 3b — Register the call listener at the app root\n\nThe incoming-call UI only shows up if you've registered a listener. Add this to `AppComponent`:\n\n```typescript\n// app.component.ts\nimport { Component, OnInit, OnDestroy } from \"@angular/core\";\nimport { CometChat } from \"@cometchat/chat-sdk-javascript\";\nimport { CometChatIncomingCall } from \"@cometchat/chat-uikit-angular\";\n\n@Component({\n  selector: \"app-root\",\n  template: `\n    <router-outlet></router-outlet>\n    <cometchat-incoming-call\n      *ngIf=\"incomingCall\"\n      [call]=\"incomingCall\"\n      [onAccept]=\"handleAccept\"\n      [onDecline]=\"handleDecline\"\n    ></cometchat-incoming-call>\n  `,\n})\nexport class AppComponent implements OnInit, OnDestroy {\n  incomingCall: CometChat.Call | null = null;\n  private readonly LISTENER_ID = \"APP_CALL_LISTENER\";\n\n  ngOnInit(): void {\n    CometChat.addCallListener(\n      this.LISTENER_ID,\n      new CometChat.CallListener({\n        onIncomingCallReceived: (call: CometChat.Call) => {\n          this.incomingCall = call;\n        },\n        onOutgoingCallAccepted: () => {\n          // navigate to ongoing-call route\n        },\n        onOutgoingCallRejected: () => {\n          this.incomingCall = null;\n        },\n        onIncomingCallCancelled: () => {\n          this.incomingCall = null;\n        },\n        onCallEndedMessageReceived: () => {\n          this.incomingCall = null;\n        },\n      })\n    );\n  }\n\n  ngOnDestroy(): void {\n    CometChat.removeCallListener(this.LISTENER_ID);\n  }\n\n  handleAccept = (call: CometChat.Call): void => {\n    this.incomingCall = null;\n    // navigate to /ongoing-call\n  };\n\n  handleDecline = (): void => {\n    this.incomingCall = null;\n  };\n}\n```\n\n### 3c — Call buttons in the message header\n\nOnce the calls SDK is installed, add `<cometchat-call-buttons>` to the message header's `[menu]` slot:\n\n```html\n<!-- messages.component.html -->\n<cometchat-message-header\n  [user]=\"selectedUser\"\n  [menu]=\"callButtonsTemplate\"\n></cometchat-message-header>\n\n<ng-template #callButtonsTemplate>\n  <cometchat-call-buttons\n    [user]=\"selectedUser\"\n    [onVoiceCallClick]=\"handleVoiceCall\"\n    [onVideoCallClick]=\"handleVideoCall\"\n  ></cometchat-call-buttons>\n</ng-template>\n```\n\n### 3d — Ongoing call\n\nMount `<cometchat-ongoing-call>` with the session ID. To detect when the call ends, subscribe to `CometChatCallEvents.ccCallEnded` from the event bus — there is no `(onCallEnded)` output on the component:\n\n```typescript\n// ongoing-call.component.ts\nimport { CometChatCallEvents } from \"@cometchat/chat-uikit-angular\";\n\n@Component({\n  selector: \"app-ongoing-call\",\n  standalone: true,\n  imports: [CometChatOngoingCall],\n  schemas: [CUSTOM_ELEMENTS_SCHEMA],\n  template: `\n    <cometchat-ongoing-call\n      [sessionID]=\"sessionId\"\n    ></cometchat-ongoing-call>\n  `,\n})\nexport class OngoingCallComponent implements OnInit, OnDestroy {\n  sessionId = \"\";\n  private callEndedSub: any;\n\n  constructor(private route: ActivatedRoute, private router: Router) {}\n\n  ngOnInit(): void {\n    this.sessionId = this.route.snapshot.queryParamMap.get(\"sessionId\") ?? \"\";\n    // Subscribe to call-ended event via the event bus\n    this.callEndedSub = (CometChatCallEvents.ccCallEnded as any).subscribe(() => {\n      this.router.navigate([\"/conversations\"]);\n    });\n  }\n\n  ngOnDestroy(): void {\n    this.callEndedSub?.unsubscribe();\n  }\n}\n```\n\n### 3e — Call logs\n\n```html\n<cometchat-call-logs\n  [onItemClick]=\"openCallDetails\"\n></cometchat-call-logs>\n```\n\n> **`[onItemClick]` is an `@Input()` callback** — use square brackets, not round brackets.\n\n---\n\n## 4. AI Agent (dashboard setup required)\n\n### 4a — Dashboard setup\n\n1. https://app.cometchat.com → your app → AI → Agents\n2. Create a new agent (name, system prompt, model)\n3. Assign a UID to the agent (e.g. `ai-support-agent`)\n\nOnce the agent exists, users can message it like any other user.\n\n### 4b — Chatting with the AI agent\n\nThe Angular v4 UIKit does **not** ship a dedicated AI assistant component (`<cometchat-ai-assistant-chat-history>` is React v6 only). To chat with an AI agent, use the standard message components targeted at the agent's UID:\n\n```typescript\n// Fetch the AI agent as a CometChat.User\nCometChat.getUser(\"ai-support-agent\").then((agentUser) => {\n  this.aiAgent = agentUser;\n});\n```\n\n```html\n<!-- Standard message view pointed at the AI agent UID -->\n<cometchat-message-header [user]=\"aiAgent\"></cometchat-message-header>\n<cometchat-message-list [user]=\"aiAgent\"></cometchat-message-list>\n<cometchat-message-composer [user]=\"aiAgent\"></cometchat-message-composer>\n```\n\nSmart Replies, Conversation Starter, and Conversation Summary AI features surface automatically in the composer and message list once enabled in the dashboard — no extra component needed.\n\n---\n\n## 5b. Deep patterns for three most-requested features\n\n### Calls — custom call listener\n\nAfter installing `@cometchat/calls-sdk-javascript`, call buttons auto-appear. For custom call state handling:\n\n```typescript\n// In AppComponent — register once at the root\nCometChat.addCallListener(\n  \"APP_CALL_LISTENER\",\n  new CometChat.CallListener({\n    onIncomingCallReceived: (call: CometChat.Call) => { this.incomingCall = call; },\n    onOutgoingCallAccepted: (call: CometChat.Call) => {\n      this.outgoingCall = null;\n      this.ongoingSessionId = call.getSessionId();\n    },\n    onOutgoingCallRejected: () => { this.outgoingCall = null; },\n    onIncomingCallCancelled: () => { this.incomingCall = null; },\n    onCallEndedMessageReceived: () => {\n      this.incomingCall = null;\n      this.outgoingCall = null;\n      this.ongoingSessionId = null;\n    },\n  })\n);\n```\n\n### Smart replies — reading extension metadata\n\nAfter enabling Smart Replies in the dashboard, the UI Kit auto-renders chips above the composer. For a custom UI, read the metadata from the incoming message:\n\n```typescript\n// In a message event subscription or custom message template:\nconst metadata = message.getMetadata() as Record<string, any>;\nconst smartReply = metadata?.['@injected']?.['extensions']?.['smart-reply'];\n\nif (smartReply) {\n  const replies = [\n    smartReply.reply_positive,\n    smartReply.reply_neutral,\n    smartReply.reply_negative,\n  ].filter(Boolean);\n  // Render reply chips\n}\n```\n\n### Presence — live online/offline status in custom UI\n\nPresence indicators are built into `<cometchat-conversations>`, `<cometchat-users>`, and `<cometchat-group-members>` automatically. For custom UI that needs live status:\n\n```typescript\nimport { Component, OnInit, OnDestroy, Input } from \"@angular/core\";\nimport { CometChat } from \"@cometchat/chat-sdk-javascript\";\n\n@Component({\n  selector: \"app-user-status\",\n  template: `<span [style.color]=\"isOnline ? '#09C26F' : '#a1a1a1'\">\n    {{ isOnline ? 'Online' : 'Offline' }}\n  </span>`,\n})\nexport class UserStatusComponent implements OnInit, OnDestroy {\n  @Input() uid!: string;\n  isOnline = false;\n  private readonly LISTENER_ID = `presence-${Date.now()}`;\n\n  ngOnInit(): void {\n    // Fetch initial state\n    CometChat.getUser(this.uid).then((u) => {\n      this.isOnline = u.getStatus() === \"online\";\n    });\n\n    // Subscribe to live changes\n    CometChat.addUserListener(\n      this.LISTENER_ID,\n      new CometChat.UserListener({\n        onUserOnline: (user: CometChat.User) => {\n          if (user.getUid() === this.uid) this.isOnline = true;\n        },\n        onUserOffline: (user: CometChat.User) => {\n          if (user.getUid() === this.uid) this.isOnline = false;\n        },\n      })\n    );\n  }\n\n  ngOnDestroy(): void {\n    CometChat.removeUserListener(this.LISTENER_ID);\n  }\n}\n```\n\n---\n\nThe following work from day 1 without any feature-enabling step:\n\n- **Instant messaging** (text, with real-time delivery)\n- **Media sharing** (images, video, audio, files)\n- **Read receipts** (single tick = sent, double tick = delivered, blue = read)\n- **Typing indicators**\n- **@mentions** (requires `CometChatMentionsFormatter` in `[textFormatters]`)\n- **Reactions** (click any message to add emoji reaction)\n- **Replies** (click → Reply)\n- **Edit / delete** own messages\n- **Message info** — sender sees delivery + read timestamps per-recipient\n- **Voice messages** (record + send from composer)\n- **Search** (`[hideSearch]=\"false\"` on `<cometchat-conversations>`, `<cometchat-users>`, `<cometchat-groups>`)\n- **Group management** (create via `<cometchat-create-group>`, add members, leave, transfer ownership)\n\n---\n\n## 6. Finding a feature's category quickly\n\nWhen a user asks for a feature, use this flow:\n\n1. **Is it in the core-features list (§ 5)?** → Already works. Confirm no `[hide*]` input is turning it off.\n2. **Is it voice / video / call history?** → Calls (§ 3). Package install.\n3. **Is it polls, stickers, message translation, link preview, collaborative doc / whiteboard, thumbnails?** → Extension (§ 2). Run `cometchat apply-feature <id> --app-id <X>`.\n3a. **Is it smart replies, conversation summary, or conversation starter?** → AI feature (§ 2). Run `cometchat apply-feature <id> --app-id <X> --openai-key sk-...`.\n3b. **Is it Giphy / Stipop / Tenor / Chatwoot / Intercom / Disappearing Messages / Message Shortcuts?** → Dashboard-only (§ 2). User must enter third-party config in https://app.cometchat.com → Extensions.\n4. **Is it AI agent?** → § 4.\n5. **Is it custom text formatting, custom message templates, custom slot views, custom theme?** → This is **customization**, not a feature. Route to `cometchat-angular-customization` or `cometchat-angular-theming`.\n6. **Not on this list?** → Check `docs/ui-kit/angular/guide-overview` + the kit's exports. If still nothing, tell the user the feature isn't in the UI Kit; they may need to build it with the SDK directly.\n\n---\n\n## 7. Anti-patterns\n\n1. **Do NOT speculatively install the calls SDK.** Install only after the user says they want calls.\n\n2. **Do NOT enable extensions your app doesn't use.** Each enabled extension adds data-fetching overhead.\n\n3. **Do NOT wire the call listener per-component.** It should be once, at the app root (`AppComponent`). Per-component registration causes missed incoming calls when the user navigates away.\n\n4. **Do NOT forget to unsubscribe / remove listeners in `ngOnDestroy`.** Angular components are destroyed on navigation — leaked listeners cause duplicate event handling.\n\n5. **Do NOT reference AI tools or streaming APIs from memory.** These APIs change across UIKit minor versions. Query the docs MCP before generating code.\n\n---\n\n## Skill routing reference\n\n| Skill | When to route |\n|---|---|\n| `cometchat-angular-core` | Init / login / module setup |\n| `cometchat-angular-components` | Component prop reference (for `<cometchat-call-buttons>`, `<cometchat-ongoing-call>`, etc.) |\n| `cometchat-angular-placement` | Where the ongoing-call route, call-logs tab, AI chat route go |\n| `cometchat-angular-features` | This skill — which features exist + how to enable each |\n| `cometchat-angular-theming` | Theming call buttons, reaction colors, extension UI colors |\n| `cometchat-angular-customization` | Custom text formatters, custom message templates, event bus |\n| `cometchat-angular-production` | Production auth tokens (prerequisite for AI agent in prod) |\n| `cometchat-angular-troubleshooting` | Extension not showing after enabling, call permissions denied |","tags":["cometchat","angular","features","skills","agent-skills","ai-agent","chat","claude-code","cursor","messaging","nextjs","react"],"capabilities":["skill","source-cometchat","skill-cometchat-angular-features","topic-agent-skills","topic-ai-agent","topic-chat","topic-claude-code","topic-cometchat","topic-cursor","topic-messaging","topic-nextjs","topic-react","topic-react-native","topic-ui-kit"],"categories":["cometchat-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/cometchat/cometchat-skills/cometchat-angular-features","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add cometchat/cometchat-skills","source_repo":"https://github.com/cometchat/cometchat-skills","install_from":"skills.sh"}},"qualityScore":"0.463","qualityRationale":"deterministic score 0.46 from registry signals: · indexed on github topic:agent-skills · 27 github stars · SKILL.md body (17,020 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T19:04:48.125Z","embedding":null,"createdAt":"2026-05-07T13:05:07.455Z","updatedAt":"2026-05-18T19:04:48.125Z","lastSeenAt":"2026-05-18T19:04:48.125Z","tsv":"'/api-keys.':451 '/conversations':1056 '/ongoing-call':917 '09c26f':1412 '1':105,541,1091,1481,1580,1761 '2':322,545,1097,1600,1625,1646,1674,1778 '3':549,762,1106,1608,1611,1796 '3a':773,1634 '3b':798,1659 '3c':922 '3d':962 '3e':1061 '4':102,558,1082,1685,1690,1828 '4a':1088 '4b':1130 '5':1589,1691,1850 '5b':1231 '6':1563,1722 '7':1757 'a1a1a1':1413 'across':1864 'action':131,497 'activatedrout':1031 'add':45,821,935,1524,1558,1791 'addit':269 'agent':30,311,1084,1096,1101,1112,1117,1120,1135,1157,1166,1173,1181,1689,1964 'agentus':1183,1185 'ai':21,29,38,194,197,310,326,382,436,1083,1095,1115,1134,1145,1156,1172,1179,1212,1644,1688,1854,1913,1963 'ai-feat':37 'ai-featur':435 'ai-support-ag':1114,1178 'aiagent':1192,1198,1204 'alreadi':88,128,466,468,1590 'already-appli':465 'alway':342 'angular':3,8,53,73,77,81,320,331,461,563,794,1137,1715,1720,1838,1884,1892,1901,1919,1932,1944,1956,1969 'angular/core':832,1397 'anti':1759 'anti-pattern':1758 'api':166,203,238,353,394,1858,1862 'app':189,226,345,370,380,398,419,431,544,564,749,795,805,844,873,1000,1094,1266,1405,1632,1653,1784,1812 'app-id':188,225,344,369,379,418,1631,1652 'app-ongoing-cal':999 'app-root':843 'app-user-status':1404 'app.cometchat.com':262,542,1092,1683 'app.component.ts':826 'appcompon':824,861,1259,1814 'appear':1251 'appli':186,220,329,338,366,374,413,438,455,467,1629,1650 'apply-featur':185,219,328,365,373,412,1628,1649 'ask':1573 'assign':1107 'assist':1146 'attach':585,634,648 'audio':1500 'auth':359,475,478,754,1959 'auth-requir':474 'auto':170,276,668,699,716,1250,1312 'auto-appear':1249 'auto-detect':275 'auto-rend':1311 'auto-wir':169 'autom':251 'automat':1215,1382 'avail':540 'away':1827 'backend':158,196 'base':85,138 'bash':363,410,778 'bearer':356 'blue':1510 'boolean':157,1365 'bracket':1078,1081 'browser':569 'bubbl':621,658 'bucket':33 'build':761,1751 'builder':733 'built':1379 'bus':982,1049,1953 'button':924,955,1248,1936 'call':9,285,409,763,767,776,801,810,850,853,874,884,887,893,910,923,931,954,964,974,1002,1015,1043,1062,1067,1240,1242,1247,1254,1267,1272,1275,1277,1605,1607,1767,1777,1801,1822,1907,1910,1935,1976 'call-end':1042 'call-log':1909 'call.getsessionid':1282 'callback':1075 'callbuttonstempl':951 'callendedsub':1026 'cannot':250 'canva':653 'card':620 'catalog':6 'categori':117,118,1568 'caus':1819,1846 'chang':1449,1863 'chat':312,546,1131,1153,1914 'chatwoot':255,506,1665 'check':1727 'chip':595,1314,1368 'class':860,1019,1418 'classifi':55 'claud':42 'cli':160,205,249,349,400,534,687 'click':641,1520,1528 'code':1874 'collabor':18,180,628,642,1620 'color':1938,1941 'cometchat':2,52,72,76,80,109,184,218,337,358,364,372,411,477,834,848,945,953,1013,1066,1188,1194,1200,1399,1627,1648,1714,1719,1883,1891,1900,1918,1931,1943,1955,1968 'cometchat-angular-compon':75,1890 'cometchat-angular-cor':71,1882 'cometchat-angular-custom':1713,1942 'cometchat-angular-featur':1,1917 'cometchat-angular-pattern':79 'cometchat-angular-plac':1899 'cometchat-angular-product':1954 'cometchat-angular-them':1718,1930 'cometchat-angular-troubleshoot':1967 'cometchat-call-button':952 'cometchat-call-log':1065 'cometchat-incoming-cal':847 'cometchat-message-compos':1199 'cometchat-message-head':944,1187 'cometchat-message-list':1193 'cometchat-ongoing-cal':1012 'cometchat.addcalllistener':878,1265 'cometchat.adduserlistener':1450 'cometchat.call':866,885,911,1273,1278 'cometchat.calllistener':882,1270 'cometchat.getuser':1177,1439 'cometchat.removecalllistener':906 'cometchat.removeuserlistener':1473 'cometchat.user':1176,1457,1465 'cometchat.userlistener':1454 'cometchat/calls-sdk-javascript':286,771,781,1246 'cometchat/chat-sdk-javascript':836,1401 'cometchat/chat-uikit-angular':101,743,840,996 'cometchat/state.json':340 'cometchat/uikit-shared':738 'cometchatcallev':994 'cometchatcallevents.cccallended':978,1051 'cometchatincomingcal':838 'cometchatmentionsformatt':1516 'cometchatongoingcal':1006 'compon':78,139,291,299,317,828,841,990,997,1147,1162,1229,1392,1402,1805,1817,1839,1893,1894 'component-swap':290 'compos':592,599,632,646,1202,1218,1317,1549 'config':243,523,1681 'confirm':1592 'const':744,1339,1346,1356 'constructor':1028 'convers':25,27,214,216,386,388,1207,1210,1639,1642 'core':74,1586,1885 'core-featur':1585 'correct':66 'creat':1098,1556 'custom':302,304,307,1008,1241,1253,1320,1336,1374,1384,1694,1697,1700,1703,1707,1716,1945,1946,1949 'dashboard':165,233,352,500,529,1085,1089,1226,1307,1672 'dashboard-on':232,499,1671 'data':1793 'data-fetch':1792 'date.now':1433 'day':1480 'dedic':1144 'deep':1232 'default':35,127 'delet':1531 'deliv':1509 'deliveri':1495,1538 'deni':1978 'dep':785 'desir':471 'destroy':1841 'detect':277,971 'dev':462 'direct':1756 'disappear':257,512,1667 'disappearing-messag':511 'doc':19,639,1621,1870 'doc/whiteboard':181 'docs/ui-kit/angular/calling-integration':97 'docs/ui-kit/angular/core-features':96 'docs/ui-kit/angular/extensions':98 'docs/ui-kit/angular/guide-ai-agent':99 'docs/ui-kit/angular/guide-overview':1728 'document':629 'doesn':1785 'done':456 'doubl':1507 'download':666 'duplic':1847 'e.g':1113 'edit':1530 'edit/delete':151 'element':1009 'emoji':1525 'enabl':126,173,323,579,696,1223,1302,1486,1781,1789,1928,1975 'end':975,1044 'enter':1677 'error':525,536 'etc':1898 'event':981,1045,1048,1333,1848,1952 'everi':108 'exact':113 'exampl':122 'exist':89,1121,1925 'explicit':347 'export':104,859,1018,1417,1732 'extens':12,36,156,263,324,361,552,575,676,682,708,711,1299,1350,1624,1684,1782,1790,1939,1971 'extensionsdatasourc':725 'extra':678,1228 'fall':111 'fallback':530 'fals':672,703,721,1427,1470,1552 'feat':39 'featur':4,5,22,46,57,91,106,110,123,187,195,221,327,330,362,367,375,383,414,437,502,548,1213,1239,1485,1566,1576,1587,1630,1645,1651,1710,1740,1920,1924 'feature-en':1484 'fetch':1170,1436,1794 'field':242,683,712 'file':1501 'filter':1364 'find':550,1564 'first':83,480 'flag':688 'flip':161,209,404,555 'flow':1579 'follow':1477 'forget':1831 'format':1696 'formatt':306,1948 'four':61,116 'full':664 'full-siz':663 'generat':183,655,1873 'get':446 'giphi':252,503,1662 'give':64 'go':335,1916 'gotcha':667 'ground':94 'group':1554 'handl':1256,1849 'handleaccept':856,909 'handledeclin':858,918 'handlevideocal':961 'handlevoicecal':959 'hard':192,458,560 'hard-reload':191,457,559 'header':928,939,947,1190 'hide':1594 'hidesearch':1551 'histori':313,1606 'hit':350 'html':943,1064,1186 'id':190,227,346,371,381,420,750,872,880,908,969,1431,1452,1475,1633,1654 'imag':656,1498 'implement':862,1021,1420 'import':722,735,739,827,833,837,993,1005,1391,1398 'incom':603,809,849,1327,1821 'incoming-cal':808 'incomingcal':852,854,865 'indic':143,1377,1513 'info':153,1535 'init':282,1886 'initi':1437 'inject':1349 'input':321,600,1074,1395,1423,1595 'instal':266,267,288,766,774,780,797,934,1245,1610,1765,1769 'instant':140,1488 'instead':661 'integr':54,86 'intercom':256,507,1666 'isn':538,1741 'isonlin':1411,1414,1426 'json':694 'key':204,208,230,239,395,403,423,426,444,484,492,755,1657 'kit':136,168,274,298,1310,1730,1746 'layer':92 'leak':1844 'leav':1560 'like':1126 'link':16,178,377,616,1618 'link-preview':376 'list':627,1196,1221,1588,1726 'listen':802,820,871,875,1243,1268,1430,1802,1835,1845 'live':1370,1388,1448 'log':1063,1068,1911 'login':360,479,1887 'long':613 'long-press':612 'manag':1555 'manual':496 'manual-action-requir':495 'match':724 'may':1748 'mcp':1871 'mean':121 'media':149,1496 'member':1559 'memori':1860 'mention':148,1514 'menu':586,615,635,649,941,950 'messag':141,152,176,258,259,308,509,513,547,604,605,611,626,927,938,946,1124,1161,1189,1195,1201,1220,1328,1332,1337,1489,1522,1533,1534,1545,1616,1668,1669,1698,1950 'message-shortcut':508 'message.getmetadata':1341 'metadata':1300,1324,1340,1348 'minor':674,1866 'miss':1820 'model':1105 'modul':1888 'most-request':1236 'mount':965 'multi':241 'multi-field':240 'must':87,1676 'name':554,697,1102 'nativ':783,791 'navig':889,915,1826,1843 'need':132,391,441,519,677,786,1230,1387,1749 'negat':1363 'neutral':1361 'new':316,746,757,759,881,1100,1269,1453 'next':281,515,527,704 'ng':565 'ngif':851 'ngondestroy':904,1057,1471,1837 'ngoninit':876,1035,1434 'noth':1735 'npm':270,287,779 'null':867,868,897,900,903,914,921,1280,1285,1288,1291,1293,1295 'offlin':1416 'onaccept':855 'oncallend':986 'oncallendedmessagereceiv':901,1289 'ondeclin':857 'ondestroy':830,864,1023,1394,1422 'one':59,114,408,447 'ongo':892,963,1001,1014,1906 'ongoing-cal':891,1905 'ongoing-call.component.ts':992 'ongoingcallcompon':1020 'onincomingcallcancel':898,1286 'onincomingcallreceiv':883,1271 'oninit':829,863,1022,1393,1421 'onitemclick':1069,1071 'onlin':1415,1445 'online/offline':1371 'onoutgoingcallaccept':888,1276 'onoutgoingcallreject':895,1283 'onuserofflin':1463 'onuseronlin':1455 'onvideocallclick':960 'onvoicecallclick':958 'open':261,636,650 'openai':202,229,393,422,443,483,491,1656 'openai-key':228,421,442,490,1655 'openai-key-requir':482 'opencalldetail':1070 'option':582,608,630,644 'output':987 'overhead':1795 'ownership':1562 'packag':265,271,279,765,772,1609 'package-instal':264,764 'parti':237,522,1680 'pass':318,343,706,727 'pattern':82,1233,1760 'peer':784 'per':1542,1804,1816 'per-compon':1803,1815 'per-recipi':1541 'permiss':1977 'picker':589 'placement':1902 'platform.openai.com':450 'platform.openai.com/api-keys.':449 'poll':13,174,368,580,581,1614 'pollsextens':741,760 'posit':1359 'prerequisit':1961 'presenc':1369,1376,1432 'press':614 'preview':17,179,378,617,1619 'privat':869,1025,1029,1032,1428 'prod':1966 'product':1957,1958 'project':332 'prompt':1104 'prop':1895 'purpos':40 'queri':1868 'quick':1569 're':487 're-run':486 'react':790,1149 'reaction':146,1519,1526,1937 'read':70,144,1298,1322,1502,1511,1539 'readon':870,1429 'real':1493 'real-tim':1492 'rebuild':289,792 'receipt':145,1503 'recip':67 'recipi':1543 'record':1343,1546 'refer':1853,1877,1896 'refresh':570 'region':752 'regist':799,818,1260 'registr':1818 'reload':193,459,561 'remov':1834 'render':155,1313,1366 'repeat':445 'replac':293 'repli':24,147,213,224,385,417,594,1206,1297,1304,1353,1357,1367,1527,1529,1638 'request':1238 'requir':200,476,485,498,768,1087,1515 'respons':452,693 'restart':567 'return':535 'rich':619 'rich-card':618 'root':806,845,1264,1813 'round':1080 'rout':894,1030,1711,1876,1881,1908,1915 'router':1033,1034 'run':488,1626,1647 'say':1774 'schema':1007,1010 'sdk':11,777,932,1755,1768 'search':1550 'see':1537 'selectedus':949,957 'selector':842,998,1403 'send':1547 'sender':1536 'sent':1506 'separ':10,770 'serv':566 'server':463 'session':968 'sessionid':1016,1017,1024,1039 'set':206,401,745 'setappid':748 'setauthkey':753 'setextens':730,756 'setregion':751 'setup':1086,1090,1889 'shape':453 'share':638,652,1497 'ship':133,1142 'shortcut':260,510,1670 'show':659,813,1973 'singl':1504 'six':32 'six-bucket':31 'size':665 'sk':231,424,493,1658 'skill':1875,1878,1922 'skill-cometchat-angular-features' 'slot':942,1701 'smart':23,212,223,384,416,593,1205,1296,1303,1352,1637 'smart-repli':222,415,1351 'smartrepli':1347,1355 'smartreply.reply':1358,1360,1362 'source-cometchat' 'span':1409 'specul':1764 'squar':1077 'standalon':1003 'standard':1160 'starter':28,217,389,1208,1643 'state':472,1255,1438 'status':454,464,473,481,494,524,556,695,1372,1389,1407 'step':516,528,705,1487 'sticker':14,175,587,588,698,1615 'stickersextens':740,758 'still':1734 'stipop':253,504,1663 'store':428 'stream':1857 'string':1344,1425 'style.color':1410 'subscrib':976,1040,1054,1446 'subscript':1334 'subsequ':434 'success':692 'suggest':596 'summari':26,215,387,1211,1640 'suppli':248 'support':1116,1180 'surfac':514,526,577,1214 'swap':292 'system':1103 'tab':1912 'target':1163 'taxonomi':34,107 'teach':41 'tell':1736 'templat':309,846,1011,1338,1408,1699,1951 'tenor':254,505,1664 'text':305,1490,1695,1947 'textformatt':1518 'theme':1704,1721,1933,1934 'third':236,521,1679 'third-parti':235,520,1678 'this.aiagent':1184 'this.callendedsub':1050,1059 'this.incomingcall':886,896,899,902,913,920,1274,1287,1290 'this.isonline':1443,1461,1469 'this.listener':879,907,1451,1474 'this.ongoingsessionid':1281,1294 'this.outgoingcall':1279,1284,1292 'this.route.snapshot.queryparammap.get':1038 'this.router.navigate':1055 'this.sessionid':1037 'this.uid':1440,1460,1468 'three':1235 'thumbnail':182,654,660,1623 'tick':1505,1508 'time':1494 'timestamp':1540 'toggl':159,198,211,406,573 'token':1960 'tool':1855 'top':48 'topic-agent-skills' 'topic-ai-agent' 'topic-chat' 'topic-claude-code' 'topic-cometchat' 'topic-cursor' 'topic-messaging' 'topic-nextjs' 'topic-react' 'topic-react-native' 'topic-ui-kit' 'transfer':1561 'translat':15,177,606,607,1617 'troubleshoot':1970 'true':1004,1462 'truth':95 'turn':1597 'type':62,142,1512 'typescript':734,825,991,1169,1257,1329,1390 'u':1442 'u.getstatus':1444 'ui':167,273,297,576,811,1309,1321,1375,1385,1745,1940 'uid':1109,1168,1424 'uikit':671,702,719,1139,1865 'uikitsettingsbuild':685,714,736,747 'unlik':789 'unsubscrib':1060,1833 'upload':150 'url':623 'use':354,1076,1158,1577,1787 'user':245,948,956,1122,1129,1191,1197,1203,1406,1456,1464,1572,1675,1738,1773,1825 'user.getuid':1459,1467 'userstatuscompon':1419 'v4':1138 'v6':1150 've':817 'verbatim':517 'version':303,1867 'via':163,319,680,709,729,1046,1557 'video':284,657,1499,1604 'view':1702 'voic':283,1544,1603 'void':877,905,912,919,1036,1058,1435,1472 'want':1776 'web':788 'whiteboard':20,643,1622 'wire':171,669,679,700,717,1799 'without':1482 'work':51,1478,1591 'wrap':295 'write':314 'x':103","prices":[{"id":"45dbc4e5-d424-4fd9-be26-a201f83ed939","listingId":"28c00df2-933c-4cae-9c83-a65c9b7197c2","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"cometchat","category":"cometchat-skills","install_from":"skills.sh"},"createdAt":"2026-05-07T13:05:07.455Z"}],"sources":[{"listingId":"28c00df2-933c-4cae-9c83-a65c9b7197c2","source":"github","sourceId":"cometchat/cometchat-skills/cometchat-angular-features","sourceUrl":"https://github.com/cometchat/cometchat-skills/tree/main/skills/cometchat-angular-features","isPrimary":false,"firstSeenAt":"2026-05-07T13:05:07.455Z","lastSeenAt":"2026-05-18T19:04:48.125Z"}],"details":{"listingId":"28c00df2-933c-4cae-9c83-a65c9b7197c2","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"cometchat","slug":"cometchat-angular-features","github":{"repo":"cometchat/cometchat-skills","stars":27,"topics":["agent-skills","ai-agent","chat","claude-code","cometchat","cursor","messaging","nextjs","react","react-native","ui-kit"],"license":null,"html_url":"https://github.com/cometchat/cometchat-skills","pushed_at":"2026-05-18T05:04:24Z","description":"Add CometChat chat to any React, Next.js, React Native, Angular, Android, iOS, or Flutter project through your AI coding agent. Works with Claude Code, Cursor, Codex, VS Code Copilot, Windsurf, Cline, Kiro, and 50+ more agents.","skill_md_sha":"903d4cb76b114e611a556f7c355fe246b3682a8e","skill_md_path":"skills/cometchat-angular-features/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/cometchat/cometchat-skills/tree/main/skills/cometchat-angular-features"},"layout":"multi","source":"github","category":"cometchat-skills","frontmatter":{"name":"cometchat-angular-features","license":"MIT","description":"Feature catalog for Angular — calls (separate SDK), extensions (polls / stickers / translation / link preview / collaborative doc / whiteboard), AI features (smart replies / conversation summary / conversation starter), AI agent. Six-bucket taxonomy: default / extension / ai-feature / dashboard-only / package-install / component-swap.","compatibility":"Angular >=12 <=15; @cometchat/chat-uikit-angular ^4; @cometchat/chat-sdk-javascript ^4"},"skills_sh_url":"https://skills.sh/cometchat/cometchat-skills/cometchat-angular-features"},"updatedAt":"2026-05-18T19:04:48.125Z"}}