[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6MFDPT5JBFS2MV4K8R7MZ5P":3,"skill-same:01M6MFDPT5JBFS2MV4K8R7MZ5P":85},{"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":45,"linkOnly":46,"markdownContent":47,"markdownBody":48,"frontMatter":49,"refName":55,"commitSha":56,"skillDirectory":57,"forksCount":58,"repositoryHtmlUrl":59,"repositoryHomepageUrl":60,"ownerHtmlUrl":61,"ownerBlogUrl":62,"ownerDescription":63,"updatedAt":64,"install":65,"resources":78},"01M6MFDPT5JBFS2MV4K8R7MZ5P","cometchat-ios-v5-sdk",null,"Add voice & video calling to any iOS app FROM SCRATCH with the headless CometChat Calls SDK v5 (`CometChatCallsSDK`, via Swift Package Manager) — no UI Kit. init→login→generateToken→joinSession into a UIView, CallSession listeners, in-call actions (mute\u002Fvideo\u002Flayout\u002Frecord\u002Ftranscribe\u002FPiP), meet-style session rooms AND 1:1 ringing (Chat SDK signaling + Calls SDK media). Triggers: 'add calling from scratch ios', 'standalone video call swift', 'headless calls sdk ios', 'build my own call screen ios', 'meeting room join by session id ios', 'one-on-one ringing call without uikit ios'.","hashgraph-online\u002Fawesome-codex-plugins","hashgraph-online","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F160371962?v=4","01M6CNB6NRJVNNGN14TR01Q6D3","HOL (Hashgraph Online)","01M6JT1HSKKG9V68KQAQGBA7XP",1554,"MIT","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Fcometchat\u002Fcometchat-skills\u002Fskills\u002Fcometchat-ios-v5-sdk\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],"sdk","cometchat","cometchat ios v5 sdk","ios","getting-started","swift","transcribe","for","verified","login","manager","kit","re","actions","screen","join","app","live","Media","Video","ui","2026-11-10 10:12:30",false,"---\nname: cometchat-ios-v5-sdk\ndescription: \"Add voice & video calling to any iOS app FROM SCRATCH with the headless CometChat Calls SDK v5 (`CometChatCallsSDK`, via Swift Package Manager) — no UI Kit. init→login→generateToken→joinSession into a UIView, CallSession listeners, in-call actions (mute\u002Fvideo\u002Flayout\u002Frecord\u002Ftranscribe\u002FPiP), meet-style session rooms AND 1:1 ringing (Chat SDK signaling + Calls SDK media). Triggers: 'add calling from scratch ios', 'standalone video call swift', 'headless calls sdk ios', 'build my own call screen ios', 'meeting room join by session id ios', 'one-on-one ringing call without uikit ios'.\"\nlicense: \"MIT\"\ncompatibility: \"iOS 15.1+ (the Calls SDK package floor; the docs' Podfile sample says 16.0 — that is the SAMPLE APP's target, not the package minimum). CometChatCallsSDK ~> 5.0 (verified against 5.0.4). 1:1 ringing also needs CometChatSDK v4 (verified against 4.1.7 — the version this pack compiles against; the live getting-started page pins a newer 4.1.9, so re-check the docs before overriding) for signaling. Swift\u002FUIKit; the call surface is a UIView, so SwiftUI hosts it via UIViewRepresentable.\"\nmetadata:\n  author: \"CometChat\"\n  version: \"1.0.0\"\n  tags: \"cometchat calls sdk v5 headless voice video webrtc swift ios calling standalone\"\n---\n\n> **Ground truth:** `CometChatCallsSDK` v5 + catalog `ios-calls-v5.json` (the closed symbol list — every type below is in it). Official docs: `\u002Fcalls\u002Fios\u002F**` = **v5** · Docs MCP. Fetch exact `SessionSettings` fields, event names and signatures from the docs (`references\u002Fdocs-map.md`) — never memory. **⚠️ Twelve doc pages contain symbols that DO NOT COMPILE — see \"Doc corrections\" below; prefer THIS skill's names over the page's.** **APPEND to the user's app — additive wiring only.**\n\n## Companion skills (read first)\n- **Standalone\u002Fheadless entry** — owns its own package (the Calls SDK), no `-core` sibling, never depends on the iOS UI Kit. **1:1 ringing** additionally drives the **Chat SDK** (`CometChatSDK` v4) for signaling.\n- **App wants chat too, or the prebuilt call UI?** `cometchat-ios-core` + `cometchat-ios-calls` — not this skill.\n\n## Use this skill when\n\"add calling from scratch \u002F without the UI Kit\", \"standalone voice\u002Fvideo on iOS\", \"build my own call screen\", \"headless calls SDK\", \"meeting-room join by session id\", \"one-on-one ringing\".\n\n## ASK FIRST (BAKED) — two choices, and NOTHING upstream asks them\nAsk whichever the request has not already settled, then **WAIT**. Never infer from silence — each answer means a different SDK set and a different screen.\n1. **Prebuilt call UI, or build your own?** Prebuilt (drop-in, themeable) → **STOP, route to `cometchat-ios-calls`.** Build your own → continue here.\n2. **Meet-style room, or 1:1 ringing?** *Room* — everyone joining the same session id lands in one call; Calls SDK only. *Ringing* — you call a specific user and their device rings; adds `CometChatSDK` v4 for signaling (signatures: `references\u002Fdocs-map.md` § \"1:1 RINGING\"), plus `CometChatPushNotifications` to ring while the app is backgrounded\u002Fclosed.\n\nOnly EXPLICIT wording settles a question — \"from scratch\"\u002F\"my own call screen\" → 1, \"ringing\"\u002F\"call a user\" → 2. **\"Add calling to my iOS app\" settles NEITHER — ask both.**\n\n## Prerequisites & install\n**Swift Package Manager only — never CocoaPods**, even if a `Podfile` exists (same rule as `cometchat-ios-core`: CocoaPods distribution is winding down; a Podfile is a detection signal, not an instruction). In Xcode: *File → Add Package Dependencies*, URL:\n```\nhttps:\u002F\u002Fgithub.com\u002Fcometchat\u002Fcalls-sdk-ios\n```\n⚠️ **The docs print `github.com\u002Fcometchat\u002Fcometchat-calls-sdk-ios` — that repo 404s.** Use the URL above. The package vends ONE product, `CometChatCallsSDK`, which bundles **WebRTC** as a second binary target — do not add WebRTC separately.\n\n**1:1 ringing additionally needs the Chat SDK** (`CometChatSDK` v4) for signaling — add it as a second SPM package: URL `https:\u002F\u002Fgithub.com\u002Fcometchat\u002Fchat-sdk-ios` (product `CometChatSDK`, verified against 4.1.7). Without it the `import CometChatSDK` on the ringing path does not resolve. (Meet-style \u002F room-only does NOT need it.)\n\n**Info.plist — REQUIRED or the call dies on first permission prompt:** `NSCameraUsageDescription` + `NSMicrophoneUsageDescription`. For calls that survive backgrounding, add **Background Modes** → *Audio, AirPlay and Picture in Picture* (+ *Voice over IP* if you use VoIP push).\n\n**Credentials:** App ID · Region · Auth Key (dev only). Load the CLI on demand — `npx @cometchat\u002Fskills-cli@3 auth login` → `provision use --app-id \u003Cid> --json` (`@3` pins the CLI major that matches the v5 skills). Already have App ID \u002F Region \u002F Auth Key? Just paste them. Mint **auth tokens server-side** for production; never ship the Auth Key.\n\n## Init & login ordering (BAKED — invariant)\nInit (once, must succeed) → `CometChatCalls.login(...)` → then `generateToken` \u002F `joinSession` \u002F listeners. Nothing joins before init+login resolve.\n- **DEFAULT to `CometChatCalls.initFromSettings(onSuccess:onError:)`** — the ai-agent \u002F telemetry-attributed path (persists `integrationSource=\"ai-agent\"`). It takes **no settings argument**: it reads a **physical `cometchat-settings.json` from `Bundle.main`** (root `appId` + `region`; optional `callsSDK` → `host`\u002F`adminHost`\u002F`clientHost`\u002F`callsHost`). The file **MUST be in the target's Copy Bundle Resources** or init fails `SETTINGS_FILE_NOT_FOUND`. It is intentionally undocumented (ai-agent-only) — the settings shape is baked in `references\u002Fdocs-map.md`.\n- **Fallback (public-doc path):** `CallAppSettingsBuilder().set(appID:).set(region:).build()` → `CometChatCalls(callsAppSettings:onSuccess:onError:)`. ⚠️ Use `set(appID:)`\u002F`set(region:)` — the `setAppId`\u002F`setRegion`\u002F`setHost` spellings the docs use are **deprecated** in 5.0.4.\n- ⚠️ **Never do both.** A direct builder init AFTER `initFromSettings` re-attributes the app to `\"manual\"` and the ai-agent telemetry is lost.\n\n## SDK method map (BAKED closed list — from the catalog; signatures → FETCH from docs)\n- **Lifecycle:** `CometChatCalls.initFromSettings` · `CometChatCalls(callsAppSettings:)` · `CallAppSettingsBuilder` · `CometChatCalls.login` (UID+authKey \u002F UID+apiKey \u002F authToken) · `logout` · `getLoggedInUser` → `CallsUser`\n- **Session:** `CometChatCalls.generateToken` · `CometChatCalls.joinSession` · `CometChatCalls.sessionSettingsBuilder` · `SessionSettingsBuilder` → `SessionSettingsBuilder.SessionSettings` (NESTED — that is the type `joinSession(callSetting:)` takes)\n- **⚠️ TWO join paths, both real in 5.0.4** — pick one: `generateToken(sessionID:)` → `joinSession(callToken:callSetting:container:)`, **or** `joinSession(sessionID:callSetting:container:)` directly.\n- **In-call actions — on `CallSession.shared`, for CUSTOM controls ONLY** (the default surface already renders them; see pitfall #1): `leaveSession` · `muteAudio`\u002F`unmuteAudio` · `pauseVideo`\u002F`resumeVideo` · `setLayout` · `setAudioMode` · `switchCamera` · `raiseHand`\u002F`lowerHand` · `startRecording`\u002F`stopRecording` · `startTranscription`\u002F`stopTranscription` · `startStreaming`\u002F`stopStreaming` · `pinParticipant`\u002F`unpinParticipant` · `muteParticipant` · `pauseParticipantVideo` · `enablePictureInPictureLayout`\u002F`disablePictureInPictureLayout` · `isCallSessionActive`\n- **Listeners (add on `CallSession.shared`, remove on teardown):** `SessionStatusListener` · `MediaEventsListener` · `ParticipantEventListener` · `LayoutListener` · `ButtonClickListener` · `clearAllListeners`\n- **Call logs:** `CallLogsBuilder` → `CallLogsRequest` → `CallLog` (+ `CallUser`\u002F`CallGroup`\u002F`CallEntity`\u002F`CallStatus`\u002F`CallCategory`\u002F`CallDirection`)\n- **Enums:** `AudioMode` (`.speaker`\u002F`.earpiece`\u002F`.bluetooth`\u002F`.headphones`) · `SessionType` (`.video`\u002F`.voice`) · `LayoutType` (`.tile`\u002F`.spotlight`\u002F`.sidebar`) · **`CameraFacing` (`.FRONT`\u002F`.REAR` — UPPERCASE, the ONE Calls-SDK enum that breaks the lowercase convention; `.front`\u002F`.rear` fail to compile, and the docs' `.BACK` does NOT exist — see Doc corrections)**\n> This map is a **curated highlight, NOT the full surface** — the AUTHORITATIVE closed list is the **`ios-calls-v5.json` catalog** (60 symbols). A symbol is real **iff it's in the catalog** — confirm THERE, then fetch its exact signature from the docs page in `references\u002Fdocs-map.md`.\n\n## Listener lifecycle (BAKED)\nRegister listeners on `CallSession.shared` **BEFORE** joining; remove each one (or `clearAllListeners()`) on teardown, and call `CallSession.shared.leaveSession()` when the screen goes away. For ringing also `CometChat.removeCallListener(\u003Cid>)`. Never leak.\n\n**The listener contract (all five, verified in the 5.0.4 interface):**\n- Every listener protocol is `@objc` and **EVERY member is `optional`.** Implement ONLY the callbacks you need — do NOT stub the rest. **A name that is NOT in the protocol also compiles, then silently never fires** — copy callback names from the events page \u002F `references\u002Fdocs-map.md`, never by analogy.\n- Because they are `@objc`, the conforming type MUST be a class inheriting **`NSObject`**.\n- Exact add\u002Fremove pairs on `CallSession.shared` — the names are NOT in the catalog (it is types-only), so use these:\n\n| Protocol | Register \u002F remove |\n|---|---|\n| `SessionStatusListener` | `addSessionStatusListener(_:)` \u002F `removeSessionStatusListener(_:)` |\n| `MediaEventsListener` | `addMediaEventsListener(_:)` \u002F `removeMediaEventsListener(_:)` |\n| `ParticipantEventListener` | `addParticipantEventListener(_:)` \u002F `removeParticipantEventListener(_:)` |\n| `LayoutListener` | `addLayoutListener(_:)` \u002F `removeLayoutListener(_:)` |\n| `ButtonClickListener` | `addButtonClickListener(_:)` \u002F `removeButtonClickListener(_:)` |\n\n- **`ButtonClickListener` callbacks fire BEFORE the SDK's own action, and do NOT suppress it.** Reacting to `onLeaveSessionButtonClicked` must NOT also call `leaveSession()` — the SDK is already leaving; doing both double-leaves.\n- **`Participant` has EXACTLY 12 fields, all Optional:** `uid` · `name` · `avatar` · `mid` · `state` · `isJoined` · `joinedAt` · `leftAt` · `deviceID` · `totalAudioMinutes` · `totalVideoMinutes` · `totalDurationInMinutes`. Identity is **`uid`** (`String?` — unwrap before passing to `muteParticipant(participantId:)`), never `name`.\n- **⚠️ The docs use SIX `Participant` fields that DO NOT EXIST** — `pid`, `isPinned`, `isAudioMuted`, `isVideoPaused`, `isPresenting`, `raisedHandTimestamp`. Copying any of them fails to compile. `pid` → use `uid`; the five state flags have **no field at all** — track that state yourself from the `ParticipantEventListener` callbacks (`onParticipantAudioMuted`\u002F`Unmuted`, `onParticipantHandRaised`\u002F`Lowered`, `onParticipantStarted`\u002F`StoppedScreenShare`).\n\n## Least-code recipe (meet-style — ORDER, not signatures)\n```swift\n\u002F\u002F Fetch every signature\u002Ffield from references\u002Fdocs-map.md. This is the ORDER, which is the part that bites.\nimport UIKit\nimport CometChatCallsSDK\n\n1. CometChatCalls.initFromSettings(onSuccess:onError:)   \u002F\u002F ai-agent default; reads bundled cometchat-settings.json\n2. CometChatCalls.login(UID:authKey:onSuccess:onError:)   \u002F\u002F or login(authToken:) in production\n3. let settings = CometChatCalls.sessionSettingsBuilder.setSessionType(.video).build()   \u002F\u002F NOT .setType — see Doc corrections\n4. CallSession.shared.addSessionStatusListener(self)      \u002F\u002F register BEFORE joining\n5. CometChatCalls.joinSession(sessionID:callSetting:container:onSuccess:onError:)  \u002F\u002F container = a UIView with REAL bounds\n   \u002F\u002F   or: generateToken(sessionID:) -> joinSession(callToken:callSetting:container:)\n6. \u002F\u002F NO control buttons needed — the joined surface ALREADY renders mute\u002Fvideo\u002Fleave.\n7. \u002F\u002F teardown -> CallSession.shared.clearAllListeners(); CallSession.shared.leaveSession()\n```\nThe `container` MUST have real bounds — a zero-frame view renders invisibly. In SwiftUI wrap it with `UIViewRepresentable`.\n\n## VoIP call notifications (SEPARATE package — `CometChatPushNotifications`)\nRinging a user whose app is **backgrounded or terminated** is NOT the Calls SDK's job. It is\n`CometChatPushNotifications` **1.0.0** — a different package. Do not hand-roll it.\n\n- **Install:** SPM `https:\u002F\u002Fgithub.com\u002Fcometchat\u002Fpush-notifications-sdk-ios` @ `1.0.0` (product\n  `CometChatPushNotificationsSwift`). **Its `Package.swift` declares NO dependencies, yet the binary\n  imports `CometChatSDK` + `CometChatCallsSDK`** — the app must ALSO have both packages above\n  (`chat-sdk-ios` + `calls-sdk-ios`) or the build fails. **`import CometChatPushNotificationsSwift`** — the\n  module name differs from the class name; importing `CometChatPushNotifications` does not compile.\n- **Three steps, nothing more:**\n  1. after `CometChat.init`: `CometChatPushNotifications.shared.initialize(config: .init(providerId:))` then set `.delegate`\n  2. in `AppDelegate`: forward `registerDeviceToken(_:)` (+ `handleRegistrationFailure(_:)`)\n  3. implement `CometChatPushNotificationsDelegate` — **every method is optional**; the ones that matter are `presentCallScreen(for:sessionId:)` and `onCallCleanupComplete()`\n- **NEVER emit a `PKPushRegistryDelegate` or a `CXProviderDelegate`.** The SDK owns both. Writing\n  either is the #1 mistake here — it fights the SDK for the same callbacks.\n- **Cold start:** call `CometChatPushNotifications.shared.notifyCallsSDKReady()` from the **login**\n  success — NOT init success. It only lifts the buffer; it does not check that anyone is logged in,\n  so releasing at init hands `presentCallScreen` an unauthenticated session and the `joinSession`\n  after it fails on auth. (A 3s safety timeout fires the buffered call anyway, so a slow login can\n  still present early — do not assume a live session in the call screen.)\n- **The call is ALREADY accepted** when `presentCallScreen` fires — present UI and join; do not accept again.\n- **Prerequisites (state them, they are not code):** an **APNs VoIP provider** in the dashboard,\n  the Push Notifications + Background Modes (Voice over IP, Remote notifications) capabilities, and\n  a **PHYSICAL DEVICE** — VoIP pushes are never delivered to the Simulator.\n- `ForegroundCallPresentation` = `.callKit` (default) · `.inApp` (`CometChatIncomingCallView`, styled\n  via `CometChatIncomingCallStyle`) · `.none` (present your own).\n\n> **Callback shapes differ PER API and `?.` on a non-optional does not compile** — `login`\u002F`logout`\n> hand you a NON-optional `CometChatCallException`; `initFromSettings`\u002F`generateToken`\u002F`joinSession`\n> hand you an Optional. Exact table + `isCallSessionActive()` arity: `references\u002Fdocs-map.md`.\n\n## Doc corrections (VERIFIED against CometChatCallsSDK 5.0.4 — prefer these over the page)\n| The docs write | It does not compile — use |\n|---|---|\n| `AudioModeType` (events, session-settings, recording) | **`AudioMode`** — `AudioModeType` exists in neither the interface nor the binary |\n| `CometChat.CallStatus` (ringing) | **`CometChat.callStatus`** — lowercase `c`; Swift is case-sensitive |\n| `.setType(.video)` (ringing, session-settings, join-session, idle-timeout, migration-guide) | **`.setSessionType(.video)`** — `SessionSettingsBuilder` has no `setType` in any spelling |\n| SPM URL `…\u002Fcometchat-calls-sdk-ios` (setup) | **`https:\u002F\u002Fgithub.com\u002Fcometchat\u002Fcalls-sdk-ios`** — documented URL 404s |\n| `region` is \"`us` or `eu`\" (setup) | **also `in`** — the SDK only checks the string is non-empty; `in` is a live region |\n| `.setAppId()` \u002F `.setRegion()` (setup) | **`.set(appID:)` \u002F `.set(region:)`** — the `setX` spellings are deprecated in 5.0.4 |\n| `call.callInitiator?.name` (ringing) | **`(call.callInitiator as? User)?.name`** — `callInitiator`\u002F`callReceiver` are `AppEntity?`; only `User` has `name` |\n| `CallType` \u002F `CallTypeVideo` as the session type (5 pages) | **`SessionType` \u002F `SessionType.video`** — `CallType` has **zero** occurrences in `CometChatCallsSDK`. It is a **Chat SDK** type (`CometChat.CallType`), valid ONLY on the ringing path. Never pass it to `SessionSettingsBuilder` |\n| `SessionType.audio` for audio-only | **`.voice`** — `.audio` and `.audioVideo` are `@available(*, deprecated)` in 5.0.4 |\n| The **Objective-C** tabs (setup, session-settings, ringing, voip-calling) | **Do not copy them** — deprecated setters, too few opening brackets, and enum constants wrongly `CometChat`-prefixed. Exact names: `references\u002Fdocs-map.md` |\n| `participant.pid` \u002F `.isPinned` \u002F `.isAudioMuted` \u002F `.isVideoPaused` \u002F `.isPresenting` \u002F `.raisedHandTimestamp` (actions, participant-management, custom-participant-list — 23×) | **None of these exist on `Participant`.** `pid` → **`uid`**; the five flags have no field — derive them from the participant events. Two review emits failed `swiftc` on exactly this |\n| `CallSession.shared.setAudioMode` \u002F `setLayout` taking an enum | **They take a `String`** — `\"SPEAKER\"`\u002F`\"EARPIECE\"`\u002F`\"BLUETOOTH\"`\u002F`\"HEADPHONES\"`, `\"TILE\"`\u002F`\"SPOTLIGHT\"`\u002F`\"SIDEBAR\"`. Only the **builder** forms take `AudioMode` \u002F `LayoutType`. Same method name, two different parameter types |\n| docs show only `login(UID:apiKey:)` \u002F `login(authToken:)` | **`login(UID:authKey:)` also exists** in 5.0.4 — the docs are incomplete, the skill's recipe is correct |\n| — (unstated anywhere) | **Chat-SDK enum casing is INCONSISTENT** — `CometChat.CallType`\u002F`.ReceiverType` Capitalised, `CometChat.callStatus` lowercase. Analogy fails to compile; check each. |\n\nDocs PR cometchat\u002Fdocs#489 merged 2026-09-08 and the live `\u002Fcalls\u002Fios\u002F**` pages now carry these fixes — re-verified against the live pages. The one exception is **`CameraFacing.BACK`**: it is still live on both `session-settings` and `events` (`.BACK`, not `.REAR`) — #489 did not touch it (separate docs fix owed). Keep every correction above as defensive guidance. Detail + per-symbol live status: `references\u002Fdocs-map.md`.\n\n## Common pitfalls (BAKED)\n- **Don't duplicate the built-in call controls (the #1 mistake).** The joined session renders a COMPLETE call UI — mute, camera, layout, participants, raise-hand, leave. Do NOT add your own buttons. `CallSession.shared` actions are for CUSTOM controls ONLY — reach for them **just when the user EXPLICITLY asks** to replace the defaults, and hide the built-ins first (`hide*Button` list in `references\u002Fdocs-map.md`). To merely REACT to the leave button, implement `ButtonClickListener.onLeaveSessionButtonClicked` — never a second button.\n- **Ringing teardown needs BOTH SDKs.** `CallSession.shared.leaveSession()` ends YOUR media; `CometChat.endCall(sessionID:)` tells the peer and completes the call log. Do only the first and the other side still thinks the call is live.\n- **Zero-bounds container** — `joinSession` mounts into your `UIView`; give it real size.\n- **CRASH — declare `var window: UIWindow?` on your AppDelegate, even in a scene-based app.** The SDK reads `UIApplication.delegate.window`; without it the app aborts (`unrecognized selector`) right after the camera permission is granted. Detail: `references\u002Fdocs-map.md`.\n- **Missing Info.plist usage strings** — no `NSCameraUsageDescription`\u002F`NSMicrophoneUsageDescription` means iOS kills the app at the first permission request.\n- **`cometchat-settings.json` not bundled** — `initFromSettings` fails `SETTINGS_FILE_NOT_FOUND`; the file must be in Copy Bundle Resources.\n- **Double init** — a builder init after `initFromSettings` silently re-attributes telemetry to `\"manual\"`.\n- **No local screen share on iOS.** Only the PEER events `onParticipantStarted`\u002F`StoppedScreenShare` are real — no start\u002Fstop action (web has one), and local capture needs a Broadcast Upload Extension. Do not emit one. (The docs' `onScreenShareStarted`\u002F`Stopped` do not exist — see docs-map.)\n- **No virtual background on iOS** — the web Calls SDK has it; this one does not.\n- **No roster, no participant state — so moderation is UNBUILDABLE.** There is no participant-list accessor, `Participant` carries no mute\u002Fpin\u002Fhand\u002Fshare flag, and (verified live on two clients) the participant events deliver nothing: `onParticipantJoined`\u002F`Left` never fire and `onParticipantListChanged` arrives EMPTY. You can never obtain a peer `uid`, so `muteParticipant`\u002F`pinParticipant`\u002F`pauseParticipantVideo` have no argument. Do NOT emit them or a custom roster — the built-in participant panel is already on screen. Detail: `references\u002Fdocs-map.md`.\n- **Assuming a signature** — event names, `SessionSettings` fields and action params are FETCHED from docs, never guessed.\n\n## Verify it works\n- **Tier-1 catalog:** every `CometChatCallsSDK` symbol emitted appears in `ios-calls-v5.json` (`node test-suite\u002Fscripts\u002Fverify-catalog.mjs --family ios-calls-v5`).\n- **Tier-2 compile:** the emit type-checks against the installed `CometChatCallsSDK` (5.0.4) with `swiftc -typecheck`.\n- **Tier-3 smoke:** the calls round-trip on a simulator (init→login→generateToken→join-wiring→leaveSession). **Ringing runs as TWO concurrent simulators** (one process per role), and only counts if both report success on the SAME session id — live-certified, not just wired.\n","> **Ground truth:** `CometChatCallsSDK` v5 + catalog `ios-calls-v5.json` (the closed symbol list — every type below is in it). Official docs: `\u002Fcalls\u002Fios\u002F**` = **v5** · Docs MCP. Fetch exact `SessionSettings` fields, event names and signatures from the docs (`references\u002Fdocs-map.md`) — never memory. **⚠️ Twelve doc pages contain symbols that DO NOT COMPILE — see \"Doc corrections\" below; prefer THIS skill's names over the page's.** **APPEND to the user's app — additive wiring only.**\n\n## Companion skills (read first)\n- **Standalone\u002Fheadless entry** — owns its own package (the Calls SDK), no `-core` sibling, never depends on the iOS UI Kit. **1:1 ringing** additionally drives the **Chat SDK** (`CometChatSDK` v4) for signaling.\n- **App wants chat too, or the prebuilt call UI?** `cometchat-ios-core` + `cometchat-ios-calls` — not this skill.\n\n## Use this skill when\n\"add calling from scratch \u002F without the UI Kit\", \"standalone voice\u002Fvideo on iOS\", \"build my own call screen\", \"headless calls SDK\", \"meeting-room join by session id\", \"one-on-one ringing\".\n\n## ASK FIRST (BAKED) — two choices, and NOTHING upstream asks them\nAsk whichever the request has not already settled, then **WAIT**. Never infer from silence — each answer means a different SDK set and a different screen.\n1. **Prebuilt call UI, or build your own?** Prebuilt (drop-in, themeable) → **STOP, route to `cometchat-ios-calls`.** Build your own → continue here.\n2. **Meet-style room, or 1:1 ringing?** *Room* — everyone joining the same session id lands in one call; Calls SDK only. *Ringing* — you call a specific user and their device rings; adds `CometChatSDK` v4 for signaling (signatures: `references\u002Fdocs-map.md` § \"1:1 RINGING\"), plus `CometChatPushNotifications` to ring while the app is backgrounded\u002Fclosed.\n\nOnly EXPLICIT wording settles a question — \"from scratch\"\u002F\"my own call screen\" → 1, \"ringing\"\u002F\"call a user\" → 2. **\"Add calling to my iOS app\" settles NEITHER — ask both.**\n\n## Prerequisites & install\n**Swift Package Manager only — never CocoaPods**, even if a `Podfile` exists (same rule as `cometchat-ios-core`: CocoaPods distribution is winding down; a Podfile is a detection signal, not an instruction). In Xcode: *File → Add Package Dependencies*, URL:\n```\nhttps:\u002F\u002Fgithub.com\u002Fcometchat\u002Fcalls-sdk-ios\n```\n⚠️ **The docs print `github.com\u002Fcometchat\u002Fcometchat-calls-sdk-ios` — that repo 404s.** Use the URL above. The package vends ONE product, `CometChatCallsSDK`, which bundles **WebRTC** as a second binary target — do not add WebRTC separately.\n\n**1:1 ringing additionally needs the Chat SDK** (`CometChatSDK` v4) for signaling — add it as a second SPM package: URL `https:\u002F\u002Fgithub.com\u002Fcometchat\u002Fchat-sdk-ios` (product `CometChatSDK`, verified against 4.1.7). Without it the `import CometChatSDK` on the ringing path does not resolve. (Meet-style \u002F room-only does NOT need it.)\n\n**Info.plist — REQUIRED or the call dies on first permission prompt:** `NSCameraUsageDescription` + `NSMicrophoneUsageDescription`. For calls that survive backgrounding, add **Background Modes** → *Audio, AirPlay and Picture in Picture* (+ *Voice over IP* if you use VoIP push).\n\n**Credentials:** App ID · Region · Auth Key (dev only). Load the CLI on demand — `npx @cometchat\u002Fskills-cli@3 auth login` → `provision use --app-id \u003Cid> --json` (`@3` pins the CLI major that matches the v5 skills). Already have App ID \u002F Region \u002F Auth Key? Just paste them. Mint **auth tokens server-side** for production; never ship the Auth Key.\n\n## Init & login ordering (BAKED — invariant)\nInit (once, must succeed) → `CometChatCalls.login(...)` → then `generateToken` \u002F `joinSession` \u002F listeners. Nothing joins before init+login resolve.\n- **DEFAULT to `CometChatCalls.initFromSettings(onSuccess:onError:)`** — the ai-agent \u002F telemetry-attributed path (persists `integrationSource=\"ai-agent\"`). It takes **no settings argument**: it reads a **physical `cometchat-settings.json` from `Bundle.main`** (root `appId` + `region`; optional `callsSDK` → `host`\u002F`adminHost`\u002F`clientHost`\u002F`callsHost`). The file **MUST be in the target's Copy Bundle Resources** or init fails `SETTINGS_FILE_NOT_FOUND`. It is intentionally undocumented (ai-agent-only) — the settings shape is baked in `references\u002Fdocs-map.md`.\n- **Fallback (public-doc path):** `CallAppSettingsBuilder().set(appID:).set(region:).build()` → `CometChatCalls(callsAppSettings:onSuccess:onError:)`. ⚠️ Use `set(appID:)`\u002F`set(region:)` — the `setAppId`\u002F`setRegion`\u002F`setHost` spellings the docs use are **deprecated** in 5.0.4.\n- ⚠️ **Never do both.** A direct builder init AFTER `initFromSettings` re-attributes the app to `\"manual\"` and the ai-agent telemetry is lost.\n\n## SDK method map (BAKED closed list — from the catalog; signatures → FETCH from docs)\n- **Lifecycle:** `CometChatCalls.initFromSettings` · `CometChatCalls(callsAppSettings:)` · `CallAppSettingsBuilder` · `CometChatCalls.login` (UID+authKey \u002F UID+apiKey \u002F authToken) · `logout` · `getLoggedInUser` → `CallsUser`\n- **Session:** `CometChatCalls.generateToken` · `CometChatCalls.joinSession` · `CometChatCalls.sessionSettingsBuilder` · `SessionSettingsBuilder` → `SessionSettingsBuilder.SessionSettings` (NESTED — that is the type `joinSession(callSetting:)` takes)\n- **⚠️ TWO join paths, both real in 5.0.4** — pick one: `generateToken(sessionID:)` → `joinSession(callToken:callSetting:container:)`, **or** `joinSession(sessionID:callSetting:container:)` directly.\n- **In-call actions — on `CallSession.shared`, for CUSTOM controls ONLY** (the default surface already renders them; see pitfall #1): `leaveSession` · `muteAudio`\u002F`unmuteAudio` · `pauseVideo`\u002F`resumeVideo` · `setLayout` · `setAudioMode` · `switchCamera` · `raiseHand`\u002F`lowerHand` · `startRecording`\u002F`stopRecording` · `startTranscription`\u002F`stopTranscription` · `startStreaming`\u002F`stopStreaming` · `pinParticipant`\u002F`unpinParticipant` · `muteParticipant` · `pauseParticipantVideo` · `enablePictureInPictureLayout`\u002F`disablePictureInPictureLayout` · `isCallSessionActive`\n- **Listeners (add on `CallSession.shared`, remove on teardown):** `SessionStatusListener` · `MediaEventsListener` · `ParticipantEventListener` · `LayoutListener` · `ButtonClickListener` · `clearAllListeners`\n- **Call logs:** `CallLogsBuilder` → `CallLogsRequest` → `CallLog` (+ `CallUser`\u002F`CallGroup`\u002F`CallEntity`\u002F`CallStatus`\u002F`CallCategory`\u002F`CallDirection`)\n- **Enums:** `AudioMode` (`.speaker`\u002F`.earpiece`\u002F`.bluetooth`\u002F`.headphones`) · `SessionType` (`.video`\u002F`.voice`) · `LayoutType` (`.tile`\u002F`.spotlight`\u002F`.sidebar`) · **`CameraFacing` (`.FRONT`\u002F`.REAR` — UPPERCASE, the ONE Calls-SDK enum that breaks the lowercase convention; `.front`\u002F`.rear` fail to compile, and the docs' `.BACK` does NOT exist — see Doc corrections)**\n> This map is a **curated highlight, NOT the full surface** — the AUTHORITATIVE closed list is the **`ios-calls-v5.json` catalog** (60 symbols). A symbol is real **iff it's in the catalog** — confirm THERE, then fetch its exact signature from the docs page in `references\u002Fdocs-map.md`.\n\n## Listener lifecycle (BAKED)\nRegister listeners on `CallSession.shared` **BEFORE** joining; remove each one (or `clearAllListeners()`) on teardown, and call `CallSession.shared.leaveSession()` when the screen goes away. For ringing also `CometChat.removeCallListener(\u003Cid>)`. Never leak.\n\n**The listener contract (all five, verified in the 5.0.4 interface):**\n- Every listener protocol is `@objc` and **EVERY member is `optional`.** Implement ONLY the callbacks you need — do NOT stub the rest. **A name that is NOT in the protocol also compiles, then silently never fires** — copy callback names from the events page \u002F `references\u002Fdocs-map.md`, never by analogy.\n- Because they are `@objc`, the conforming type MUST be a class inheriting **`NSObject`**.\n- Exact add\u002Fremove pairs on `CallSession.shared` — the names are NOT in the catalog (it is types-only), so use these:\n\n| Protocol | Register \u002F remove |\n|---|---|\n| `SessionStatusListener` | `addSessionStatusListener(_:)` \u002F `removeSessionStatusListener(_:)` |\n| `MediaEventsListener` | `addMediaEventsListener(_:)` \u002F `removeMediaEventsListener(_:)` |\n| `ParticipantEventListener` | `addParticipantEventListener(_:)` \u002F `removeParticipantEventListener(_:)` |\n| `LayoutListener` | `addLayoutListener(_:)` \u002F `removeLayoutListener(_:)` |\n| `ButtonClickListener` | `addButtonClickListener(_:)` \u002F `removeButtonClickListener(_:)` |\n\n- **`ButtonClickListener` callbacks fire BEFORE the SDK's own action, and do NOT suppress it.** Reacting to `onLeaveSessionButtonClicked` must NOT also call `leaveSession()` — the SDK is already leaving; doing both double-leaves.\n- **`Participant` has EXACTLY 12 fields, all Optional:** `uid` · `name` · `avatar` · `mid` · `state` · `isJoined` · `joinedAt` · `leftAt` · `deviceID` · `totalAudioMinutes` · `totalVideoMinutes` · `totalDurationInMinutes`. Identity is **`uid`** (`String?` — unwrap before passing to `muteParticipant(participantId:)`), never `name`.\n- **⚠️ The docs use SIX `Participant` fields that DO NOT EXIST** — `pid`, `isPinned`, `isAudioMuted`, `isVideoPaused`, `isPresenting`, `raisedHandTimestamp`. Copying any of them fails to compile. `pid` → use `uid`; the five state flags have **no field at all** — track that state yourself from the `ParticipantEventListener` callbacks (`onParticipantAudioMuted`\u002F`Unmuted`, `onParticipantHandRaised`\u002F`Lowered`, `onParticipantStarted`\u002F`StoppedScreenShare`).\n\n## Least-code recipe (meet-style — ORDER, not signatures)\n```swift\n\u002F\u002F Fetch every signature\u002Ffield from references\u002Fdocs-map.md. This is the ORDER, which is the part that bites.\nimport UIKit\nimport CometChatCallsSDK\n\n1. CometChatCalls.initFromSettings(onSuccess:onError:)   \u002F\u002F ai-agent default; reads bundled cometchat-settings.json\n2. CometChatCalls.login(UID:authKey:onSuccess:onError:)   \u002F\u002F or login(authToken:) in production\n3. let settings = CometChatCalls.sessionSettingsBuilder.setSessionType(.video).build()   \u002F\u002F NOT .setType — see Doc corrections\n4. CallSession.shared.addSessionStatusListener(self)      \u002F\u002F register BEFORE joining\n5. CometChatCalls.joinSession(sessionID:callSetting:container:onSuccess:onError:)  \u002F\u002F container = a UIView with REAL bounds\n   \u002F\u002F   or: generateToken(sessionID:) -> joinSession(callToken:callSetting:container:)\n6. \u002F\u002F NO control buttons needed — the joined surface ALREADY renders mute\u002Fvideo\u002Fleave.\n7. \u002F\u002F teardown -> CallSession.shared.clearAllListeners(); CallSession.shared.leaveSession()\n```\nThe `container` MUST have real bounds — a zero-frame view renders invisibly. In SwiftUI wrap it with `UIViewRepresentable`.\n\n## VoIP call notifications (SEPARATE package — `CometChatPushNotifications`)\nRinging a user whose app is **backgrounded or terminated** is NOT the Calls SDK's job. It is\n`CometChatPushNotifications` **1.0.0** — a different package. Do not hand-roll it.\n\n- **Install:** SPM `https:\u002F\u002Fgithub.com\u002Fcometchat\u002Fpush-notifications-sdk-ios` @ `1.0.0` (product\n  `CometChatPushNotificationsSwift`). **Its `Package.swift` declares NO dependencies, yet the binary\n  imports `CometChatSDK` + `CometChatCallsSDK`** — the app must ALSO have both packages above\n  (`chat-sdk-ios` + `calls-sdk-ios`) or the build fails. **`import CometChatPushNotificationsSwift`** — the\n  module name differs from the class name; importing `CometChatPushNotifications` does not compile.\n- **Three steps, nothing more:**\n  1. after `CometChat.init`: `CometChatPushNotifications.shared.initialize(config: .init(providerId:))` then set `.delegate`\n  2. in `AppDelegate`: forward `registerDeviceToken(_:)` (+ `handleRegistrationFailure(_:)`)\n  3. implement `CometChatPushNotificationsDelegate` — **every method is optional**; the ones that matter are `presentCallScreen(for:sessionId:)` and `onCallCleanupComplete()`\n- **NEVER emit a `PKPushRegistryDelegate` or a `CXProviderDelegate`.** The SDK owns both. Writing\n  either is the #1 mistake here — it fights the SDK for the same callbacks.\n- **Cold start:** call `CometChatPushNotifications.shared.notifyCallsSDKReady()` from the **login**\n  success — NOT init success. It only lifts the buffer; it does not check that anyone is logged in,\n  so releasing at init hands `presentCallScreen` an unauthenticated session and the `joinSession`\n  after it fails on auth. (A 3s safety timeout fires the buffered call anyway, so a slow login can\n  still present early — do not assume a live session in the call screen.)\n- **The call is ALREADY accepted** when `presentCallScreen` fires — present UI and join; do not accept again.\n- **Prerequisites (state them, they are not code):** an **APNs VoIP provider** in the dashboard,\n  the Push Notifications + Background Modes (Voice over IP, Remote notifications) capabilities, and\n  a **PHYSICAL DEVICE** — VoIP pushes are never delivered to the Simulator.\n- `ForegroundCallPresentation` = `.callKit` (default) · `.inApp` (`CometChatIncomingCallView`, styled\n  via `CometChatIncomingCallStyle`) · `.none` (present your own).\n\n> **Callback shapes differ PER API and `?.` on a non-optional does not compile** — `login`\u002F`logout`\n> hand you a NON-optional `CometChatCallException`; `initFromSettings`\u002F`generateToken`\u002F`joinSession`\n> hand you an Optional. Exact table + `isCallSessionActive()` arity: `references\u002Fdocs-map.md`.\n\n## Doc corrections (VERIFIED against CometChatCallsSDK 5.0.4 — prefer these over the page)\n| The docs write | It does not compile — use |\n|---|---|\n| `AudioModeType` (events, session-settings, recording) | **`AudioMode`** — `AudioModeType` exists in neither the interface nor the binary |\n| `CometChat.CallStatus` (ringing) | **`CometChat.callStatus`** — lowercase `c`; Swift is case-sensitive |\n| `.setType(.video)` (ringing, session-settings, join-session, idle-timeout, migration-guide) | **`.setSessionType(.video)`** — `SessionSettingsBuilder` has no `setType` in any spelling |\n| SPM URL `…\u002Fcometchat-calls-sdk-ios` (setup) | **`https:\u002F\u002Fgithub.com\u002Fcometchat\u002Fcalls-sdk-ios`** — documented URL 404s |\n| `region` is \"`us` or `eu`\" (setup) | **also `in`** — the SDK only checks the string is non-empty; `in` is a live region |\n| `.setAppId()` \u002F `.setRegion()` (setup) | **`.set(appID:)` \u002F `.set(region:)`** — the `setX` spellings are deprecated in 5.0.4 |\n| `call.callInitiator?.name` (ringing) | **`(call.callInitiator as? User)?.name`** — `callInitiator`\u002F`callReceiver` are `AppEntity?`; only `User` has `name` |\n| `CallType` \u002F `CallTypeVideo` as the session type (5 pages) | **`SessionType` \u002F `SessionType.video`** — `CallType` has **zero** occurrences in `CometChatCallsSDK`. It is a **Chat SDK** type (`CometChat.CallType`), valid ONLY on the ringing path. Never pass it to `SessionSettingsBuilder` |\n| `SessionType.audio` for audio-only | **`.voice`** — `.audio` and `.audioVideo` are `@available(*, deprecated)` in 5.0.4 |\n| The **Objective-C** tabs (setup, session-settings, ringing, voip-calling) | **Do not copy them** — deprecated setters, too few opening brackets, and enum constants wrongly `CometChat`-prefixed. Exact names: `references\u002Fdocs-map.md` |\n| `participant.pid` \u002F `.isPinned` \u002F `.isAudioMuted` \u002F `.isVideoPaused` \u002F `.isPresenting` \u002F `.raisedHandTimestamp` (actions, participant-management, custom-participant-list — 23×) | **None of these exist on `Participant`.** `pid` → **`uid`**; the five flags have no field — derive them from the participant events. Two review emits failed `swiftc` on exactly this |\n| `CallSession.shared.setAudioMode` \u002F `setLayout` taking an enum | **They take a `String`** — `\"SPEAKER\"`\u002F`\"EARPIECE\"`\u002F`\"BLUETOOTH\"`\u002F`\"HEADPHONES\"`, `\"TILE\"`\u002F`\"SPOTLIGHT\"`\u002F`\"SIDEBAR\"`. Only the **builder** forms take `AudioMode` \u002F `LayoutType`. Same method name, two different parameter types |\n| docs show only `login(UID:apiKey:)` \u002F `login(authToken:)` | **`login(UID:authKey:)` also exists** in 5.0.4 — the docs are incomplete, the skill's recipe is correct |\n| — (unstated anywhere) | **Chat-SDK enum casing is INCONSISTENT** — `CometChat.CallType`\u002F`.ReceiverType` Capitalised, `CometChat.callStatus` lowercase. Analogy fails to compile; check each. |\n\nDocs PR cometchat\u002Fdocs#489 merged 2026-09-08 and the live `\u002Fcalls\u002Fios\u002F**` pages now carry these fixes — re-verified against the live pages. The one exception is **`CameraFacing.BACK`**: it is still live on both `session-settings` and `events` (`.BACK`, not `.REAR`) — #489 did not touch it (separate docs fix owed). Keep every correction above as defensive guidance. Detail + per-symbol live status: `references\u002Fdocs-map.md`.\n\n## Common pitfalls (BAKED)\n- **Don't duplicate the built-in call controls (the #1 mistake).** The joined session renders a COMPLETE call UI — mute, camera, layout, participants, raise-hand, leave. Do NOT add your own buttons. `CallSession.shared` actions are for CUSTOM controls ONLY — reach for them **just when the user EXPLICITLY asks** to replace the defaults, and hide the built-ins first (`hide*Button` list in `references\u002Fdocs-map.md`). To merely REACT to the leave button, implement `ButtonClickListener.onLeaveSessionButtonClicked` — never a second button.\n- **Ringing teardown needs BOTH SDKs.** `CallSession.shared.leaveSession()` ends YOUR media; `CometChat.endCall(sessionID:)` tells the peer and completes the call log. Do only the first and the other side still thinks the call is live.\n- **Zero-bounds container** — `joinSession` mounts into your `UIView`; give it real size.\n- **CRASH — declare `var window: UIWindow?` on your AppDelegate, even in a scene-based app.** The SDK reads `UIApplication.delegate.window`; without it the app aborts (`unrecognized selector`) right after the camera permission is granted. Detail: `references\u002Fdocs-map.md`.\n- **Missing Info.plist usage strings** — no `NSCameraUsageDescription`\u002F`NSMicrophoneUsageDescription` means iOS kills the app at the first permission request.\n- **`cometchat-settings.json` not bundled** — `initFromSettings` fails `SETTINGS_FILE_NOT_FOUND`; the file must be in Copy Bundle Resources.\n- **Double init** — a builder init after `initFromSettings` silently re-attributes telemetry to `\"manual\"`.\n- **No local screen share on iOS.** Only the PEER events `onParticipantStarted`\u002F`StoppedScreenShare` are real — no start\u002Fstop action (web has one), and local capture needs a Broadcast Upload Extension. Do not emit one. (The docs' `onScreenShareStarted`\u002F`Stopped` do not exist — see docs-map.)\n- **No virtual background on iOS** — the web Calls SDK has it; this one does not.\n- **No roster, no participant state — so moderation is UNBUILDABLE.** There is no participant-list accessor, `Participant` carries no mute\u002Fpin\u002Fhand\u002Fshare flag, and (verified live on two clients) the participant events deliver nothing: `onParticipantJoined`\u002F`Left` never fire and `onParticipantListChanged` arrives EMPTY. You can never obtain a peer `uid`, so `muteParticipant`\u002F`pinParticipant`\u002F`pauseParticipantVideo` have no argument. Do NOT emit them or a custom roster — the built-in participant panel is already on screen. Detail: `references\u002Fdocs-map.md`.\n- **Assuming a signature** — event names, `SessionSettings` fields and action params are FETCHED from docs, never guessed.\n\n## Verify it works\n- **Tier-1 catalog:** every `CometChatCallsSDK` symbol emitted appears in `ios-calls-v5.json` (`node test-suite\u002Fscripts\u002Fverify-catalog.mjs --family ios-calls-v5`).\n- **Tier-2 compile:** the emit type-checks against the installed `CometChatCallsSDK` (5.0.4) with `swiftc -typecheck`.\n- **Tier-3 smoke:** the calls round-trip on a simulator (init→login→generateToken→join-wiring→leaveSession). **Ringing runs as TWO concurrent simulators** (one process per role), and only counts if both report success on the SAME session id — live-certified, not just wired.\n",{"name":5,"license":15,"metadata":50,"description":7,"compatibility":54},{"tags":51,"author":52,"version":53},"cometchat calls sdk v5 headless voice video webrtc swift ios calling standalone","CometChat","1.0.0","iOS 15.1+ (the Calls SDK package floor; the docs' Podfile sample says 16.0 — that is the SAMPLE APP's target, not the package minimum). CometChatCallsSDK ~> 5.0 (verified against 5.0.4). 1:1 ringing also needs CometChatSDK v4 (verified against 4.1.7 — the version this pack compiles against; the live getting-started page pins a newer 4.1.9, so re-check the docs before overriding) for signaling. Swift\u002FUIKit; the call surface is a UIView, so SwiftUI hosts it via UIViewRepresentable.","main","2b63f856ce19c2a797929cacabd9e0fc936812fa","plugins\u002Fcometchat\u002Fcometchat-skills\u002Fskills\u002Fcometchat-ios-v5-sdk",468,"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-11 02:22:54",{"source":8,"skillName":5,"commands":66,"prompt":76,"zipAvailable":77},[67,70,73],{"tool":68,"command":69},"npx","npx skills add hashgraph-online\u002Fawesome-codex-plugins --skill cometchat-ios-v5-sdk",{"tool":71,"command":72},"bunx","bunx skills add hashgraph-online\u002Fawesome-codex-plugins --skill cometchat-ios-v5-sdk",{"tool":74,"command":75},"pnpm","pnpm dlx skills add hashgraph-online\u002Fawesome-codex-plugins --skill cometchat-ios-v5-sdk","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Fcometchat\u002Fcometchat-skills\u002Fskills\u002Fcometchat-ios-v5-sdk\u002FSKILL.md",true,[79],{"path":80,"resourceType":81,"resourceTypeDesc":82,"sizeBytes":83,"sourceHtmlUrl":84},"references\u002Fdocs-map.md","REFERENCE","参考文档",28497,"https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Fcometchat\u002Fcometchat-skills\u002Fskills\u002Fcometchat-ios-v5-sdk\u002Freferences\u002Fdocs-map.md",[86,113,138,167,187,201],{"skillNo":87,"name":88,"nameZh":6,"description":89,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":90,"licenseFileUrl":6,"sourceHtmlUrl":91,"categories":92,"keywords":93,"publishedAt":45},"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.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Fvshulcz\u002Fdeja-vu\u002Fskills\u002Fdeja-search\u002FSKILL.md",[],[94,95,96,97,98,99,36,100,101,102,103,104,105,106,107,108,109,110,111,112],"search","deja search","error","ready","never","memory","decide","fix","design","debugging","when","you","done","reviewer","io","change","cli","merge","past",{"skillNo":114,"name":115,"nameZh":6,"description":116,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":90,"licenseFileUrl":6,"sourceHtmlUrl":117,"categories":118,"keywords":119,"publishedAt":45},"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",[],[120,121,122,123,99,124,125,126,127,128,129,130,131,108,132,133,134,135,136,137],"reflect","deja reflect","brew","remember","project rules","project","session","end","reflection","Rules","decisions","review","with","record","github","next","https","node",{"skillNo":139,"name":140,"nameZh":6,"description":141,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":90,"licenseFileUrl":6,"sourceHtmlUrl":142,"categories":143,"keywords":151,"publishedAt":45},"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",[144,147,148],{"categoryNo":145,"categoryName":146,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":149,"categoryName":150,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[140,43,152,153,154,155,125,156,36,157,158,159,160,104,161,162,163,164,165,166],"short-form","standalone","PDF","viral","tiktok","short","social","MCP","song","URL","image","mcp server","schedule","api","publish",{"skillNo":168,"name":169,"nameZh":6,"description":170,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":90,"licenseFileUrl":6,"sourceHtmlUrl":171,"categories":172,"keywords":173,"publishedAt":45},"01M71569ZM2X3H5RBFK8PVKMK2","review-study","Review a QuestionPunk survey before launch for wording, answer choices, branching, and missing settings. Use for check my survey or review this draft before publishing.","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Fquestionpunk\u002Fcodex-plugin\u002Fskills\u002Freview-study\u002FSKILL.md",[],[174,175,131,31,176,177,178,179,180,181,182,183,184,185,186],"study","review study","answer","missing","survey","publishing","use","check","draft","settings","launch","my","branching",{"skillNo":188,"name":189,"nameZh":6,"description":190,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":90,"licenseFileUrl":6,"sourceHtmlUrl":191,"categories":192,"keywords":193,"publishedAt":45},"01M71567GV0C35YQBY0DPGR86B","manage-study","Find QuestionPunk studies, check status, publish an explicitly requested draft, or retrieve its participant link. Use for find my survey, publish this study, or how many people responded.","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Fquestionpunk\u002Fcodex-plugin\u002Fskills\u002Fmanage-study\u002FSKILL.md",[],[194,174,195,31,178,180,196,181,182,166,197,198,199,200,185],"manage study","manage","people","how","find","link","status",{"skillNo":202,"name":203,"nameZh":6,"description":204,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":90,"licenseFileUrl":6,"sourceHtmlUrl":205,"categories":206,"keywords":207,"publishedAt":45},"01M71565A8TCA01AZQZRGRYMFZ","create-study","Create a saved QuestionPunk survey draft from a research brief or edit specified questions. Use for requests such as make a customer feedback survey or shorten my onboarding study.","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Fquestionpunk\u002Fcodex-plugin\u002Fskills\u002Fcreate-study\u002FSKILL.md",[],[208,174,209,210,211,212,31,213,178,214,180,215,216,182,217,218,219,220,221,185],"create study","create","brief","as","feedback","customer feedback","research brief","shorten","saved","research","requests","customer","questions","edit"]