[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6MF36M7ASQMQ0GMR1QPDKHS":3,"skill-same:01M6MF36M7ASQMQ0GMR1QPDKHS":86},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":46,"linkOnly":47,"markdownContent":48,"markdownBody":49,"frontMatter":50,"refName":56,"commitSha":57,"skillDirectory":58,"forksCount":59,"repositoryHtmlUrl":60,"repositoryHomepageUrl":61,"ownerHtmlUrl":62,"ownerBlogUrl":63,"ownerDescription":64,"updatedAt":65,"install":66,"resources":79},"01M6MF36M7ASQMQ0GMR1QPDKHS","cometchat-android-v6-calls",null,"Add voice and video calling to an Android v6 CometChat app — the Calls SDK dependency, the settings-file calling toggle, call buttons in the message header, a global incoming-call listener, outgoing\u002Fongoing call UI, call logs, and the runtime permissions. Triggers: 'add calling to my android app', 'voice video call android cometchat', 'incoming call screen android', 'call logs android', 'why are the call buttons not showing'.","hashgraph-online\u002Fawesome-codex-plugins","hashgraph-online","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F160371962?v=4","01M6CNB6NRJVNNGN14TR01Q6D3","HOL (Hashgraph Online)","01M6JT1HSKKG9V68KQAQGBA7XP",1575,"MIT","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Fcometchat\u002Fcometchat-skills\u002Fskills\u002Fcometchat-android-v6-calls\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000016","图像与多媒体","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45],"cometchat android v6 calls","android","calls","cometchat","buttons","call","triggers","runtime","compose","add","ui","my","verified","why","screen","dependency","message","jvm","permissions","logs","app","Video","2026-11-10 10:12:30",false,"---\nname: cometchat-android-v6-calls\ndescription: \"Add voice and video calling to an Android v6 CometChat app — the Calls SDK dependency, the settings-file calling toggle, call buttons in the message header, a global incoming-call listener, outgoing\u002Fongoing call UI, call logs, and the runtime permissions. Triggers: 'add calling to my android app', 'voice video call android cometchat', 'incoming call screen android', 'call logs android', 'why are the call buttons not showing'.\"\nlicense: \"MIT\"\ncompatibility: \"Android minSdk >=28; compileSdk >=36; Kotlin >=2.1; AGP >=8.9.1; JVM target 11; com.cometchat:chatuikit-kotlin-android ^6 OR com.cometchat:chatuikit-compose-android ^6 (6.1.x, verified 6.1.1); com.cometchat:calls-sdk-android ^5 (5.0.x); com.cometchat:chat-sdk-android ^5\"\nmetadata:\n  author: \"CometChat\"\n  version: \"1.0.0\"\n  tags: \"cometchat android calls voice video v6 calling compose views\"\n---\n\n> **Ground truth:** catalog `android-v6.json` + `features.android-v6.json` (`voice-video-calls`) + `contracts.android-v6.json` (`voice-video-calls`) + the live pages `calling-integration`, `call-features`, `components\u002F{call-buttons,incoming-call,outgoing-call,call-logs}`, `guide-call-log-details`. Deep Calls-SDK behavior: the `\u002Fcalls\u002Fandroid` docs tree. Verify symbols against the catalog; fetch params from docs; never trust memory.\n\n## Companion skills (read first)\n- `cometchat-android-v6-core` — install, credentials (`assets\u002Fcometchat-settings.json`), `initFromSettings → login → render`, sizing (`references\u002Flayout.md`), the fetch map. Assumed here, never repeated.\n- `cometchat-android-v6-{kotlin,compose}-placement` — where the incoming-call surface sits in the app shell.\n\n## Use this skill when\n\"add voice\u002Fvideo calling\", \"show call buttons in the chat\", \"handle incoming calls\", \"add a call history screen\", \"the call buttons aren't appearing\", \"call log details\".\n\n## Calls package + version\nAdd the Calls SDK **alongside** your cohort's UI Kit artifact (never instead of it):\n```kotlin\ndependencies {\n    implementation(\"com.cometchat:chatuikit-compose-android:6.1.1\")   \u002F\u002F or chatuikit-kotlin-android for XML Views\n    implementation(\"com.cometchat:calls-sdk-android:5.0.4\")\n}\n```\n> ⚠️ **On 6.1.1 the simplest fix is no Jetifier at all** — chat-sdk 5.0.7 dropped the pre-AndroidX\n> transitive, and a clean app with kit 6.1.1 + calls-sdk 5.0.4 builds with `android.enableJetifier=false`\n> (verified 2026-10-15). **If the app keeps Jetifier on (6.0.x, or another legacy dependency), add a\n> Jetifier ignore-list, or the build can break the moment you add calling.**\n> `calls-sdk-android` 5.0.x bundles a React-Native stack (`react-android` \u002F `hermes` \u002F `react-native-webrtc`),\n> and Jetifier **cannot transform** `react-android-*.aar` — so with Jetifier on, the build dies at\n> `checkDebugAarMetadata` with `Execution failed for JetifyTransform: react-android-0.77.2-debug.aar`\n> (the app compiled fine BEFORE calling; adding the artifact breaks it — verified 2026-09-10). These\n> AARs are already AndroidX, so exclude them from Jetifier in `gradle.properties`:\n> ```properties\n> android.jetifier.ignorelist=react-android,hermes-android,react-native-webrtc\n> ```\n⚠️ **The artifact and the flag are a PAIR — setting either alone leaves calling broken.**\n> · flag `true`, artifact missing → 6.0.x: **app crashes at launch** (`initFromSettings` → `initCometChatCalls` → `NoClassDefFoundError: CometChatCalls$SessionSettingsBuilder`). 6.1.1: no crash; init logs `enableCalling=true but the CometChat Calls SDK is not on the classpath` and calling stays off (ENG-39311, source-checked)\n> · artifact present, flag `false` → calling components crash when used (`RuntimeException: Please call the CometChatCalls.init() method ...`)\n>\n> ⚠️ **BOTH are required — the artifact alone is not enough.** `uiKit.enableCalling: true` in\n`assets\u002Fcometchat-settings.json` is what makes `initFromSettings` initialize `CometChatCalls`.\nWithout it, `CometChatCallLogs` throws `RuntimeException: Please call the CometChatCalls.init()\nmethod ...`; without the artifact 6.0.x throws `NoClassDefFoundError` (6.1.1 skips Calls init and\ncalling components do nothing). Both compile fine — device-only failures (verified 2026-08-21 on 6.0.x).\n\n**The kit auto-detects the Calls SDK** and activates calling. Also set `\"uiKit\": { \"enableCalling\": true }` in `app\u002Fsrc\u002Fmain\u002Fassets\u002Fcometchat-settings.json` so `CometChatUIKit.initFromSettings(...)` initializes the Calls SDK through the telemetry-aware path (it auto-inits Calls when that flag is on). Dashboard: calling must be enabled for the app.\n\n**Header call buttons differ BY COHORT** (verified vs 6.0.5 source; unchanged in 6.1.1):\n- **Views**: automatic — `CometChatMessageHeader`'s voice\u002Fvideo button visibility defaults follow `CallsUtils.isCallingEnabled()`, so the buttons render with no extra code once calling is enabled.\n- **Compose**: NOT automatic — the `CometChatMessageHeader` composable defaults `hideVoiceCallButton = true` and `hideVideoCallButton = true`. Pass both explicitly:\n  ```kotlin\n  CometChatMessageHeader(user = user, hideVoiceCallButton = false, hideVideoCallButton = false)\n  ```\n  And do NOT use the header's `auxiliaryView` slot for other icons — it REPLACES the default auxiliary area that hosts the call buttons (they vanish). Extra header icons go in `trailingView` (see `cometchat-android-v6-compose-components`).\n\n## Call-flow ordering (BAKED — invariant)\n1. **Dependency + `enableCalling`** → call buttons appear in the message header (Views: nothing to wire; Compose: pass `hideVoiceCallButton = false, hideVideoCallButton = false` — see above).\n2. **`initFromSettings` resolves → `login` resolves** (as always) — calling is unavailable before that.\n\n> ⚠️ **Enabling calling in an app with EXISTING sessions — force a fresh login.** `CometChatUIKit.login()`\n> short-circuits when the same uid is already logged in (persisted session): it returns `onSuccess`\n> WITHOUT calling `loginCometChatCalls`, so the Calls SDK never gets an auth token (verified vs 6.0.5\n> `CometChatUIKit.kt` login + on device 2026-08-25; same short-circuit in 6.1.1 source). Symptom: `CometChatCallLogs` shows a silent\n> error state; logcat says `User auth token cannot be null`. When calling is FIRST enabled on an app\n> whose users already have a session, users must re-login — `CometChatUIKit.logout(...)` then\n> `CometChatUIKit.login(...)` (or force a fresh login path once, e.g. on a calling-feature version\n> bump). During development, wire `onError` on `CometChatCallLogs` so this failure is not silent.\n3. **Register a GLOBAL call listener** so an incoming call rings from anywhere in the app — the docs recommend an `Application` subclass, registering **before** the UI Kit is used:\n```kotlin\nimport com.cometchat.chat.core.Call            \u002F\u002F NOTE: chat.core, NOT chat.models\nimport com.cometchat.chat.core.CometChat\n\nclass BaseApplication : Application() {\n    companion object {\n        private val LISTENER_ID = \"${BaseApplication::class.java.simpleName}${System.currentTimeMillis()}\"\n    }\n    override fun onCreate() {\n        super.onCreate()\n        CometChat.addCallListener(LISTENER_ID, object : CometChat.CallListener() {\n            override fun onIncomingCallReceived(call: Call) { \u002F* show CometChatIncomingCall over the current screen *\u002F }\n            override fun onOutgoingCallAccepted(call: Call) { \u002F* proceed to the ongoing-call surface *\u002F }\n            override fun onOutgoingCallRejected(call: Call) { \u002F* dismiss the outgoing UI *\u002F }\n            override fun onIncomingCallCancelled(call: Call) { \u002F* dismiss the incoming UI *\u002F }\n        })\n    }\n}\n```\nRegister the Application class in the manifest (`android:name=\".BaseApplication\"`). **Views**: instantiate `CometChatIncomingCall(context)`, set its `call`, set `fitsSystemWindows = true`, wire its error handler, and present it (dialog \u002F full-screen overlay). **Compose**: hold the incoming `Call` in app-level state and render the incoming-call composable above your nav host — fetch the composable's params from `components\u002Fincoming-call.md`.\n4. **Permissions** — request `CAMERA` and `RECORD_AUDIO` at runtime before a call starts (video needs both; audio-only needs `RECORD_AUDIO`); declare them in the manifest. The kit ships `CometChatPermissionHandler` \u002F `CometChatPermissionActivity` — prefer them over a hand-rolled flow.\n\n> Note: **SoLoader \u002F bundled React-Native native libs (know this before an ACTIVE call).** `calls-sdk-android`\n> 5.0.x bundles a React-Native stack (`react-android` \u002F `hermes` \u002F `react-native-webrtc`), declared at\n> **`runtime` scope** in its POM — so they land on the runtime classpath and `initFromSettings` calls-init +\n> `CometChatCallLogs` work with **no extra deps** (verified on device: init succeeds, call logs render).\n> An **active** call surface loads those native `.so`s, which on RN ≥ 0.76 depend on `SoLoader`. If an\n> active call fails to open with a `SoLoader`\u002F`UnsatisfiedLinkError`\u002F`NoClassDefFoundError` (React\u002FJSI\u002F\n> Hermes symbols), add the RN + SoLoader artifacts on the **compile** classpath and init SoLoader once in\n> `Application.onCreate` **before** the first call surface:\n> ```kotlin\n> \u002F\u002F build.gradle.kts (only if an active call throws a SoLoader\u002Fnative-link error)\n> implementation(\"com.facebook.react:react-android:0.77.2\")   \u002F\u002F match what calls-sdk-android pulls\n> implementation(\"com.facebook.soloader:soloader:0.12.1\")\n> \u002F\u002F Application.onCreate: SoLoader.init(this, OpenSourceMergedSoMapping)\n> ```\n> Whether 5.0.x needs this for an active call is not yet settled from a single device — it is NOT needed for\n> init or call logs. Verify with a real two-device call; treat this as the fix if (and only if) you hit that\n> native-link error, not as an unconditional step.\n\n## Calls component \u002F API map (BAKED closed list)\n`CometChatCallButtons` (auto-rendered in the message header; can also be placed standalone) · `CometChatIncomingCall` (ringing UI — accept\u002Fdecline) · `CometChatOutgoingCall` (dialing UI) · `CometChatOngoingCall` + `CometChatOngoingCallActivity` \u002F `CometChatCallActivity` (the in-call surface) · `CometChatCallLogs` (call history list) + `CometChatCallLogsListItem` · call bubbles in the message list: `CometChatCallActionBubble`, `CometChatMeetCallBubble` · `CometChatCallEvent` (call events → `cometchat-android-v6-events`). SDK-side (build-your-own flows): `CometChat.initiateCall` \u002F `acceptCall` \u002F `rejectCall` \u002F `getActiveCall` \u002F `clearActiveCall` \u002F `addCallListener` \u002F `removeCallListener` — see `core\u002Freferences\u002Fdocs-map.md` → SDK section.\n\nThe **minimum for \"add calling\"** (contract `voice-video-calls`): initiate (buttons) + incoming-call UI + outgoing-call UI + call logs. A call button with no incoming-call handler is a dead end — the callee never sees the ring.\n\n```kotlin\n\u002F\u002F Minimum calls surface — four components for voice-video-calls contract\n\u002F\u002F CometChatCallButtons: auto-rendered in the message header; place standalone when needed\nval callButtons = CometChatCallButtons(context)\n\n\u002F\u002F CometChatOutgoingCall: shown while the callee hasn't answered yet\nval outgoingCall = CometChatOutgoingCall(context)\noutgoingCall.call = pendingCall\n\n\u002F\u002F CometChatCallActivity \u002F CometChatOngoingCallActivity: the in-call surface, launched\n\u002F\u002F automatically during a session. ⚠️ You do NOT declare these — BOTH are already declared in the\n\u002F\u002F UI-Kit AAR manifest and merge in automatically (verified vs 6.0.x and the 6.1.1 AAR manifests). The cohort-correct classes:\n\u002F\u002F   Compose: com.cometchat.uikit.compose.calls.CometChatCallActivity\n\u002F\u002F            com.cometchat.uikit.compose.presentation.ongoingcall.ui.CometChatOngoingCallActivity\n\u002F\u002F   Views:   com.cometchat.uikit.kotlin.calls.CometChatCallActivity\n\u002F\u002F            com.cometchat.uikit.kotlin.presentation.ongoingcall.ui.CometChatOngoingCallActivity\n\u002F\u002F (There is NO `com.cometchat.chatuikit.calling.*` class in v6 — that's a v5\u002Fv4-era name; do not\n\u002F\u002F add a manual \u003Cactivity> line for it or the merge\u002Flaunch breaks.)\n\n\u002F\u002F CometChatCallLogs: call history tab\nval callLogs = CometChatCallLogs(context)\n```\n\n### Huddle \u002F docked call — Android how-to (BAKED — verified vs 6.1.1 + calls-sdk 5.0.4)\nThe pattern (start -> join -> dock -> indicator -> leave): `cometchat-onboarding\u002Freferences\u002Fclone-mode.md` -> *Huddle \u002F drop-in room pattern*. The Android code for both cohorts is in **`references\u002Fhuddle.md`**: send the kit's own `meeting` message (session id = group GUID), replace the meeting bubble with a `BubbleFactory` so Join opens your dock, and join with `CometChatCalls.joinSession(sessionId, settings, yourRelativeLayout, ...)` instead of the kit's full-screen `CometChatOngoingCallActivity`. Compiled, not yet run on a device.\n\n## Deeper calling features → fetch\n| Intent | Page (append `.md`) |\n|---|---|\n| calling overview \u002F what's supported | `\u002Fui-kit\u002Fandroid\u002Fcall-features` |\n| call buttons props | `\u002Fui-kit\u002Fandroid\u002Fcall-buttons` |\n| incoming \u002F outgoing UI props | `\u002Fui-kit\u002Fandroid\u002Fincoming-call` · `\u002Fui-kit\u002Fandroid\u002Foutgoing-call` |\n| call logs + details recipe | `\u002Fui-kit\u002Fandroid\u002Fcall-logs` · `\u002Fui-kit\u002Fandroid\u002Fguide-call-log-details` |\n| custom in-call UI, layouts, recording, screen share, audio modes | the `\u002Fcalls\u002Fandroid\u002F*` pages (`call-layouts`, `custom-control-panel`, `audio-modes`, `background-handling`, `idle-timeout`, `events`, ...) |\n\n## Common pitfalls\nImporting `com.cometchat.chat.models.Call` (it is **`com.cometchat.chat.core.Call`** — the wrong import compiles to an \"Unresolved reference 'Call'\" cascade) · manually declaring `CometChatCallActivity`\u002F`CometChatOngoingCallActivity` in your manifest (they AUTO-MERGE from the UI-Kit AAR — a hand-written `\u003Cactivity>` with the wrong\u002Flegacy `com.cometchat.chatuikit.calling.*` name breaks the launch) · Calls SDK missing (buttons never appear) · `enableCalling` not set in the settings file · Compose header without `hideVoiceCallButton = false` \u002F `hideVideoCallButton = false` (buttons never appear — Compose defaults hide them) · Compose `auxiliaryView` used for a custom header icon (it replaces the call-button host — use `trailingView`) · calling enabled on an app with a persisted session without a re-login (Calls SDK tokenless — call logs silently error with \"User auth token cannot be null\") · no global call listener (incoming calls never ring) · listener registered per-Activity only (rings only on that screen) · registering in `Application` but forgetting `android:name` in the manifest · missing runtime CAMERA\u002FRECORD_AUDIO permissions (call fails silently) · calling before `login` resolves · call UI not `fitsSystemWindows` \u002F not full-bleed (controls under system bars) · leaking the listener (remove it if you register outside `Application`) · mixing a v4\u002Fv5 calls artifact with the v6 kit · a docked\u002Fmini call target left on the kit default (the group call button and the meeting bubble's Join both open the full-screen `CometChatOngoingCallActivity`; a Views `CometChatOngoingCall` mounted in your panel calls `activity.finish()` when the call ends) — dock it per `references\u002Fhuddle.md`.\n\n## Verify it works\nCompile against the pinned kit (`.\u002Fgradlew :app:assembleDebug   # in YOUR app (npm run verify:fences:android-v6 is a pack-repo gate)`). On device (TWO devices\u002Femulators + two users — calling can't be verified single-ended): call buttons render in the message header; tapping starts an outgoing call; the OTHER device rings with the incoming UI from **any** screen; accept → ongoing call with audio\u002Fvideo; decline\u002Fcancel dismisses cleanly on both sides; the call appears in `CometChatCallLogs` and as a call bubble in the chat. No ring ⇒ listener not registered globally (or app not logged in). Permission denial ⇒ handle it and tell the user, don't fail silently.\n","> **Ground truth:** catalog `android-v6.json` + `features.android-v6.json` (`voice-video-calls`) + `contracts.android-v6.json` (`voice-video-calls`) + the live pages `calling-integration`, `call-features`, `components\u002F{call-buttons,incoming-call,outgoing-call,call-logs}`, `guide-call-log-details`. Deep Calls-SDK behavior: the `\u002Fcalls\u002Fandroid` docs tree. Verify symbols against the catalog; fetch params from docs; never trust memory.\n\n## Companion skills (read first)\n- `cometchat-android-v6-core` — install, credentials (`assets\u002Fcometchat-settings.json`), `initFromSettings → login → render`, sizing (`references\u002Flayout.md`), the fetch map. Assumed here, never repeated.\n- `cometchat-android-v6-{kotlin,compose}-placement` — where the incoming-call surface sits in the app shell.\n\n## Use this skill when\n\"add voice\u002Fvideo calling\", \"show call buttons in the chat\", \"handle incoming calls\", \"add a call history screen\", \"the call buttons aren't appearing\", \"call log details\".\n\n## Calls package + version\nAdd the Calls SDK **alongside** your cohort's UI Kit artifact (never instead of it):\n```kotlin\ndependencies {\n    implementation(\"com.cometchat:chatuikit-compose-android:6.1.1\")   \u002F\u002F or chatuikit-kotlin-android for XML Views\n    implementation(\"com.cometchat:calls-sdk-android:5.0.4\")\n}\n```\n> ⚠️ **On 6.1.1 the simplest fix is no Jetifier at all** — chat-sdk 5.0.7 dropped the pre-AndroidX\n> transitive, and a clean app with kit 6.1.1 + calls-sdk 5.0.4 builds with `android.enableJetifier=false`\n> (verified 2026-10-15). **If the app keeps Jetifier on (6.0.x, or another legacy dependency), add a\n> Jetifier ignore-list, or the build can break the moment you add calling.**\n> `calls-sdk-android` 5.0.x bundles a React-Native stack (`react-android` \u002F `hermes` \u002F `react-native-webrtc`),\n> and Jetifier **cannot transform** `react-android-*.aar` — so with Jetifier on, the build dies at\n> `checkDebugAarMetadata` with `Execution failed for JetifyTransform: react-android-0.77.2-debug.aar`\n> (the app compiled fine BEFORE calling; adding the artifact breaks it — verified 2026-09-10). These\n> AARs are already AndroidX, so exclude them from Jetifier in `gradle.properties`:\n> ```properties\n> android.jetifier.ignorelist=react-android,hermes-android,react-native-webrtc\n> ```\n⚠️ **The artifact and the flag are a PAIR — setting either alone leaves calling broken.**\n> · flag `true`, artifact missing → 6.0.x: **app crashes at launch** (`initFromSettings` → `initCometChatCalls` → `NoClassDefFoundError: CometChatCalls$SessionSettingsBuilder`). 6.1.1: no crash; init logs `enableCalling=true but the CometChat Calls SDK is not on the classpath` and calling stays off (ENG-39311, source-checked)\n> · artifact present, flag `false` → calling components crash when used (`RuntimeException: Please call the CometChatCalls.init() method ...`)\n>\n> ⚠️ **BOTH are required — the artifact alone is not enough.** `uiKit.enableCalling: true` in\n`assets\u002Fcometchat-settings.json` is what makes `initFromSettings` initialize `CometChatCalls`.\nWithout it, `CometChatCallLogs` throws `RuntimeException: Please call the CometChatCalls.init()\nmethod ...`; without the artifact 6.0.x throws `NoClassDefFoundError` (6.1.1 skips Calls init and\ncalling components do nothing). Both compile fine — device-only failures (verified 2026-08-21 on 6.0.x).\n\n**The kit auto-detects the Calls SDK** and activates calling. Also set `\"uiKit\": { \"enableCalling\": true }` in `app\u002Fsrc\u002Fmain\u002Fassets\u002Fcometchat-settings.json` so `CometChatUIKit.initFromSettings(...)` initializes the Calls SDK through the telemetry-aware path (it auto-inits Calls when that flag is on). Dashboard: calling must be enabled for the app.\n\n**Header call buttons differ BY COHORT** (verified vs 6.0.5 source; unchanged in 6.1.1):\n- **Views**: automatic — `CometChatMessageHeader`'s voice\u002Fvideo button visibility defaults follow `CallsUtils.isCallingEnabled()`, so the buttons render with no extra code once calling is enabled.\n- **Compose**: NOT automatic — the `CometChatMessageHeader` composable defaults `hideVoiceCallButton = true` and `hideVideoCallButton = true`. Pass both explicitly:\n  ```kotlin\n  CometChatMessageHeader(user = user, hideVoiceCallButton = false, hideVideoCallButton = false)\n  ```\n  And do NOT use the header's `auxiliaryView` slot for other icons — it REPLACES the default auxiliary area that hosts the call buttons (they vanish). Extra header icons go in `trailingView` (see `cometchat-android-v6-compose-components`).\n\n## Call-flow ordering (BAKED — invariant)\n1. **Dependency + `enableCalling`** → call buttons appear in the message header (Views: nothing to wire; Compose: pass `hideVoiceCallButton = false, hideVideoCallButton = false` — see above).\n2. **`initFromSettings` resolves → `login` resolves** (as always) — calling is unavailable before that.\n\n> ⚠️ **Enabling calling in an app with EXISTING sessions — force a fresh login.** `CometChatUIKit.login()`\n> short-circuits when the same uid is already logged in (persisted session): it returns `onSuccess`\n> WITHOUT calling `loginCometChatCalls`, so the Calls SDK never gets an auth token (verified vs 6.0.5\n> `CometChatUIKit.kt` login + on device 2026-08-25; same short-circuit in 6.1.1 source). Symptom: `CometChatCallLogs` shows a silent\n> error state; logcat says `User auth token cannot be null`. When calling is FIRST enabled on an app\n> whose users already have a session, users must re-login — `CometChatUIKit.logout(...)` then\n> `CometChatUIKit.login(...)` (or force a fresh login path once, e.g. on a calling-feature version\n> bump). During development, wire `onError` on `CometChatCallLogs` so this failure is not silent.\n3. **Register a GLOBAL call listener** so an incoming call rings from anywhere in the app — the docs recommend an `Application` subclass, registering **before** the UI Kit is used:\n```kotlin\nimport com.cometchat.chat.core.Call            \u002F\u002F NOTE: chat.core, NOT chat.models\nimport com.cometchat.chat.core.CometChat\n\nclass BaseApplication : Application() {\n    companion object {\n        private val LISTENER_ID = \"${BaseApplication::class.java.simpleName}${System.currentTimeMillis()}\"\n    }\n    override fun onCreate() {\n        super.onCreate()\n        CometChat.addCallListener(LISTENER_ID, object : CometChat.CallListener() {\n            override fun onIncomingCallReceived(call: Call) { \u002F* show CometChatIncomingCall over the current screen *\u002F }\n            override fun onOutgoingCallAccepted(call: Call) { \u002F* proceed to the ongoing-call surface *\u002F }\n            override fun onOutgoingCallRejected(call: Call) { \u002F* dismiss the outgoing UI *\u002F }\n            override fun onIncomingCallCancelled(call: Call) { \u002F* dismiss the incoming UI *\u002F }\n        })\n    }\n}\n```\nRegister the Application class in the manifest (`android:name=\".BaseApplication\"`). **Views**: instantiate `CometChatIncomingCall(context)`, set its `call`, set `fitsSystemWindows = true`, wire its error handler, and present it (dialog \u002F full-screen overlay). **Compose**: hold the incoming `Call` in app-level state and render the incoming-call composable above your nav host — fetch the composable's params from `components\u002Fincoming-call.md`.\n4. **Permissions** — request `CAMERA` and `RECORD_AUDIO` at runtime before a call starts (video needs both; audio-only needs `RECORD_AUDIO`); declare them in the manifest. The kit ships `CometChatPermissionHandler` \u002F `CometChatPermissionActivity` — prefer them over a hand-rolled flow.\n\n> Note: **SoLoader \u002F bundled React-Native native libs (know this before an ACTIVE call).** `calls-sdk-android`\n> 5.0.x bundles a React-Native stack (`react-android` \u002F `hermes` \u002F `react-native-webrtc`), declared at\n> **`runtime` scope** in its POM — so they land on the runtime classpath and `initFromSettings` calls-init +\n> `CometChatCallLogs` work with **no extra deps** (verified on device: init succeeds, call logs render).\n> An **active** call surface loads those native `.so`s, which on RN ≥ 0.76 depend on `SoLoader`. If an\n> active call fails to open with a `SoLoader`\u002F`UnsatisfiedLinkError`\u002F`NoClassDefFoundError` (React\u002FJSI\u002F\n> Hermes symbols), add the RN + SoLoader artifacts on the **compile** classpath and init SoLoader once in\n> `Application.onCreate` **before** the first call surface:\n> ```kotlin\n> \u002F\u002F build.gradle.kts (only if an active call throws a SoLoader\u002Fnative-link error)\n> implementation(\"com.facebook.react:react-android:0.77.2\")   \u002F\u002F match what calls-sdk-android pulls\n> implementation(\"com.facebook.soloader:soloader:0.12.1\")\n> \u002F\u002F Application.onCreate: SoLoader.init(this, OpenSourceMergedSoMapping)\n> ```\n> Whether 5.0.x needs this for an active call is not yet settled from a single device — it is NOT needed for\n> init or call logs. Verify with a real two-device call; treat this as the fix if (and only if) you hit that\n> native-link error, not as an unconditional step.\n\n## Calls component \u002F API map (BAKED closed list)\n`CometChatCallButtons` (auto-rendered in the message header; can also be placed standalone) · `CometChatIncomingCall` (ringing UI — accept\u002Fdecline) · `CometChatOutgoingCall` (dialing UI) · `CometChatOngoingCall` + `CometChatOngoingCallActivity` \u002F `CometChatCallActivity` (the in-call surface) · `CometChatCallLogs` (call history list) + `CometChatCallLogsListItem` · call bubbles in the message list: `CometChatCallActionBubble`, `CometChatMeetCallBubble` · `CometChatCallEvent` (call events → `cometchat-android-v6-events`). SDK-side (build-your-own flows): `CometChat.initiateCall` \u002F `acceptCall` \u002F `rejectCall` \u002F `getActiveCall` \u002F `clearActiveCall` \u002F `addCallListener` \u002F `removeCallListener` — see `core\u002Freferences\u002Fdocs-map.md` → SDK section.\n\nThe **minimum for \"add calling\"** (contract `voice-video-calls`): initiate (buttons) + incoming-call UI + outgoing-call UI + call logs. A call button with no incoming-call handler is a dead end — the callee never sees the ring.\n\n```kotlin\n\u002F\u002F Minimum calls surface — four components for voice-video-calls contract\n\u002F\u002F CometChatCallButtons: auto-rendered in the message header; place standalone when needed\nval callButtons = CometChatCallButtons(context)\n\n\u002F\u002F CometChatOutgoingCall: shown while the callee hasn't answered yet\nval outgoingCall = CometChatOutgoingCall(context)\noutgoingCall.call = pendingCall\n\n\u002F\u002F CometChatCallActivity \u002F CometChatOngoingCallActivity: the in-call surface, launched\n\u002F\u002F automatically during a session. ⚠️ You do NOT declare these — BOTH are already declared in the\n\u002F\u002F UI-Kit AAR manifest and merge in automatically (verified vs 6.0.x and the 6.1.1 AAR manifests). The cohort-correct classes:\n\u002F\u002F   Compose: com.cometchat.uikit.compose.calls.CometChatCallActivity\n\u002F\u002F            com.cometchat.uikit.compose.presentation.ongoingcall.ui.CometChatOngoingCallActivity\n\u002F\u002F   Views:   com.cometchat.uikit.kotlin.calls.CometChatCallActivity\n\u002F\u002F            com.cometchat.uikit.kotlin.presentation.ongoingcall.ui.CometChatOngoingCallActivity\n\u002F\u002F (There is NO `com.cometchat.chatuikit.calling.*` class in v6 — that's a v5\u002Fv4-era name; do not\n\u002F\u002F add a manual \u003Cactivity> line for it or the merge\u002Flaunch breaks.)\n\n\u002F\u002F CometChatCallLogs: call history tab\nval callLogs = CometChatCallLogs(context)\n```\n\n### Huddle \u002F docked call — Android how-to (BAKED — verified vs 6.1.1 + calls-sdk 5.0.4)\nThe pattern (start -> join -> dock -> indicator -> leave): `cometchat-onboarding\u002Freferences\u002Fclone-mode.md` -> *Huddle \u002F drop-in room pattern*. The Android code for both cohorts is in **`references\u002Fhuddle.md`**: send the kit's own `meeting` message (session id = group GUID), replace the meeting bubble with a `BubbleFactory` so Join opens your dock, and join with `CometChatCalls.joinSession(sessionId, settings, yourRelativeLayout, ...)` instead of the kit's full-screen `CometChatOngoingCallActivity`. Compiled, not yet run on a device.\n\n## Deeper calling features → fetch\n| Intent | Page (append `.md`) |\n|---|---|\n| calling overview \u002F what's supported | `\u002Fui-kit\u002Fandroid\u002Fcall-features` |\n| call buttons props | `\u002Fui-kit\u002Fandroid\u002Fcall-buttons` |\n| incoming \u002F outgoing UI props | `\u002Fui-kit\u002Fandroid\u002Fincoming-call` · `\u002Fui-kit\u002Fandroid\u002Foutgoing-call` |\n| call logs + details recipe | `\u002Fui-kit\u002Fandroid\u002Fcall-logs` · `\u002Fui-kit\u002Fandroid\u002Fguide-call-log-details` |\n| custom in-call UI, layouts, recording, screen share, audio modes | the `\u002Fcalls\u002Fandroid\u002F*` pages (`call-layouts`, `custom-control-panel`, `audio-modes`, `background-handling`, `idle-timeout`, `events`, ...) |\n\n## Common pitfalls\nImporting `com.cometchat.chat.models.Call` (it is **`com.cometchat.chat.core.Call`** — the wrong import compiles to an \"Unresolved reference 'Call'\" cascade) · manually declaring `CometChatCallActivity`\u002F`CometChatOngoingCallActivity` in your manifest (they AUTO-MERGE from the UI-Kit AAR — a hand-written `\u003Cactivity>` with the wrong\u002Flegacy `com.cometchat.chatuikit.calling.*` name breaks the launch) · Calls SDK missing (buttons never appear) · `enableCalling` not set in the settings file · Compose header without `hideVoiceCallButton = false` \u002F `hideVideoCallButton = false` (buttons never appear — Compose defaults hide them) · Compose `auxiliaryView` used for a custom header icon (it replaces the call-button host — use `trailingView`) · calling enabled on an app with a persisted session without a re-login (Calls SDK tokenless — call logs silently error with \"User auth token cannot be null\") · no global call listener (incoming calls never ring) · listener registered per-Activity only (rings only on that screen) · registering in `Application` but forgetting `android:name` in the manifest · missing runtime CAMERA\u002FRECORD_AUDIO permissions (call fails silently) · calling before `login` resolves · call UI not `fitsSystemWindows` \u002F not full-bleed (controls under system bars) · leaking the listener (remove it if you register outside `Application`) · mixing a v4\u002Fv5 calls artifact with the v6 kit · a docked\u002Fmini call target left on the kit default (the group call button and the meeting bubble's Join both open the full-screen `CometChatOngoingCallActivity`; a Views `CometChatOngoingCall` mounted in your panel calls `activity.finish()` when the call ends) — dock it per `references\u002Fhuddle.md`.\n\n## Verify it works\nCompile against the pinned kit (`.\u002Fgradlew :app:assembleDebug   # in YOUR app (npm run verify:fences:android-v6 is a pack-repo gate)`). On device (TWO devices\u002Femulators + two users — calling can't be verified single-ended): call buttons render in the message header; tapping starts an outgoing call; the OTHER device rings with the incoming UI from **any** screen; accept → ongoing call with audio\u002Fvideo; decline\u002Fcancel dismisses cleanly on both sides; the call appears in `CometChatCallLogs` and as a call bubble in the chat. No ring ⇒ listener not registered globally (or app not logged in). Permission denial ⇒ handle it and tell the user, don't fail silently.\n",{"name":5,"license":15,"metadata":51,"description":7,"compatibility":55},{"tags":52,"author":53,"version":54},"cometchat android calls voice video v6 calling compose views","CometChat","1.0.0","Android minSdk >=28; compileSdk >=36; Kotlin >=2.1; AGP >=8.9.1; JVM target 11; com.cometchat:chatuikit-kotlin-android ^6 OR com.cometchat:chatuikit-compose-android ^6 (6.1.x, verified 6.1.1); com.cometchat:calls-sdk-android ^5 (5.0.x); com.cometchat:chat-sdk-android ^5","main","cebc3dce495d7eb80d3b1d5841f877a4a92e162d","plugins\u002Fcometchat\u002Fcometchat-skills\u002Fskills\u002Fcometchat-android-v6-calls",491,"https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins","https:\u002F\u002Fhol.org\u002Fplugins\u002Fbest-codex-plugins","https:\u002F\u002Fgithub.com\u002Fhashgraph-online","https:\u002F\u002Fhol.org","Open-source standards and developer tools for interoperable AI agents: discovery, identity, communication, payments, privacy and security.","2026-11-14 14:06:13",{"source":8,"skillName":5,"commands":67,"prompt":77,"zipAvailable":78},[68,71,74],{"tool":69,"command":70},"npx","npx skills add hashgraph-online\u002Fawesome-codex-plugins --skill cometchat-android-v6-calls",{"tool":72,"command":73},"bunx","bunx skills add hashgraph-online\u002Fawesome-codex-plugins --skill cometchat-android-v6-calls",{"tool":75,"command":76},"pnpm","pnpm dlx skills add hashgraph-online\u002Fawesome-codex-plugins --skill cometchat-android-v6-calls","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Fcometchat\u002Fcometchat-skills\u002Fskills\u002Fcometchat-android-v6-calls\u002FSKILL.md",true,[80],{"path":81,"resourceType":82,"resourceTypeDesc":83,"sizeBytes":84,"sourceHtmlUrl":85},"references\u002Fhuddle.md","REFERENCE","参考文档",13592,"https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Fcometchat\u002Fcometchat-skills\u002Fskills\u002Fcometchat-android-v6-calls\u002Freferences\u002Fhuddle.md",[87,96,103,110,137,162],{"skillNo":88,"name":89,"nameZh":6,"description":90,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":91,"licenseFileUrl":6,"sourceHtmlUrl":92,"categories":93,"keywords":94,"publishedAt":95},"01M746ZWACVKMZ1BJXJZHYJSSX","migrate-to-e2e","Moves an existing Playwright, Cypress, Selenium, Appium, Detox, Maestro, or TesterArmy suite to e2e one slice at a time, with the old suite running beside the new one until each ported test is proven. Keeps a MIGRATION.md progress file so any later session resumes where the last stopped. Optionally plants a defect to show both suites catch it. Use for \u002Fmigrate-to-e2e, \"migrate our tests to e2e\", \"port these Maestro flows\", \"move our TesterArmy tests\", or when a project has an e2e config and an older suite still running.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Ftester-army\u002Fe2e\u002Fskills\u002Fmigrate-to-e2e\u002FSKILL.md",[],[],"2026-11-11 15:11:14",{"skillNo":97,"name":98,"nameZh":6,"description":99,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":91,"licenseFileUrl":6,"sourceHtmlUrl":100,"categories":101,"keywords":102,"publishedAt":95},"01M746ZPTAX1Q0FBKAB1CYND7E","e2e","Writes, runs, and debugs end-to-end tests for web and mobile apps with e2e, the agentic test runner, which mixes agent.act goals with exact locator assertions on a Playwright browser or an iOS or Android device. Also drives a project's running app live over the e2e MCP server to look at a screen, check a UI change, take a screenshot or record a video, and try a locator; and runs bug bashes, parallel e2e explore runs with each bug proven by a repro test. Use when a project depends on e2e or has an e2e.config.ts, when asked for end-to-end, browser, mobile, or agentic UI tests, to check a change in the running app, to QA or bug bash an app or branch, or when an e2e run fails.","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Ftester-army\u002Fe2e\u002Fskills\u002Fe2e\u002FSKILL.md",[],[],{"skillNo":104,"name":105,"nameZh":6,"description":106,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":91,"licenseFileUrl":6,"sourceHtmlUrl":107,"categories":108,"keywords":109,"publishedAt":95},"01M746ZJN784HVHMDP9MQGCSGG","create-verification-skill","Generate a project-local verify-\u003Capp> skill on top of e2e, so any coding agent can launch the app, check it is worth driving, exercise a feature the way a user does, keep evidence, and bug bash it. Writes the skill, a feature map with one explore charter per feature, and proves it once. Use for \u002Fcreate-verification-skill, \"make a verification skill for this repo\", or when a project has no scripted way to prove UI behavior.","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Ftester-army\u002Fe2e\u002Fskills\u002Fcreate-verification-skill\u002FSKILL.md",[],[],{"skillNo":111,"name":112,"nameZh":6,"description":113,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":91,"licenseFileUrl":6,"sourceHtmlUrl":114,"categories":115,"keywords":116,"publishedAt":46},"01M716A6ETNB9B1SQ3GXZC75VR","deja-search","deja-vu memory — search the user's past AI coding sessions with the deja CLI. Holds what they already settled and never wrote into the repo (naming rules, banned or already-tried tools, required checks before merge, preferred values, who owns what). Use before your first edit in a task, before you call a change done or ready to merge, before you recommend a tool, library, design or reviewer, before re-debugging an error that may already be solved, when they say 'didn't we fix this before', 'what did we decide about X' or 'I already have that', and before telling them something on this machine does not exist.","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Fvshulcz\u002Fdeja-vu\u002Fskills\u002Fdeja-search\u002FSKILL.md",[],[117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136],"search","deja search","never","error","ready","memory","re","decide","fix","design","debugging","when","you","done","reviewer","io","change","cli","merge","past",{"skillNo":138,"name":139,"nameZh":6,"description":140,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":91,"licenseFileUrl":6,"sourceHtmlUrl":141,"categories":142,"keywords":143,"publishedAt":46},"01M716A3J2W5SENSE9VGMXB375","deja-reflect","End-of-session reflection and memory curation with deja-vu. Review what was decided, what commands broke and what repaired them, and record durable project rules or decisions with deja remember so the next session starts with them.","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Fvshulcz\u002Fdeja-vu\u002Fskills\u002Fdeja-reflect\u002FSKILL.md",[],[144,145,146,132,147,148,149,150,151,152,153,154,155,156,122,157,158,159,160,161],"deja reflect","reflect","review","with","record","github","next","https","node","Rules","decisions","brew","remember","project rules","project","session","end","reflection",{"skillNo":163,"name":164,"nameZh":6,"description":165,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":91,"licenseFileUrl":6,"sourceHtmlUrl":166,"categories":167,"keywords":175,"publishedAt":46},"01M715T3RR4BAYSR57HPPTJ0PF","revid","Make, edit, export and post AI videos with Revid (revid.ai) through the Revid MCP server. Use whenever the user wants a short-form or long-form video made (from an idea, a script, a URL, an article, a PDF, a tweet, a product page, their own clips, or a song), wants to find what is going viral on TikTok, YouTube, Instagram or X before making something, wants to edit or re-export an existing Revid project, generate a standalone AI image or clip, make a series episode, or publish and schedule a finished video to connected social accounts. Covers setup (hosted MCP with OAuth, or an API key), the 36 tools, credits, polling and the rules for publishing. Routes to the more specific revid-* skills when one fits.","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Ftmakersas\u002Frevid-skills\u002Fskills\u002Frevid\u002FSKILL.md",[168,169,172],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":170,"categoryName":171,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":173,"categoryName":174,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口",[164,176,45,177,178,179,180,158,181,123,182,183,184,185,128,186,187,188,189,190],"URL","short-form","standalone","PDF","viral","tiktok","short","social","MCP","song","image","mcp server","schedule","api","publish"]