{"id":"8110c83a-b23a-453a-8768-a746ebbfe2d3","shortId":"LfdD8p","kind":"skill","title":"robius-matrix-integration","tagline":"CRITICAL: Use for Matrix SDK integration with Makepad. Triggers on:\nMatrix SDK, sliding sync, MatrixRequest, timeline,\nmatrix-sdk, matrix client, robrix, matrix room,\nMatrix 集成, 聊天客户端","description":"# Robius Matrix SDK Integration Skill\n\nBest practices for integrating external APIs with Makepad applications based on Robrix and Moly codebases.\n\n**Source codebases:**\n- **Robrix**: Matrix SDK integration - sliding sync, timeline subscriptions, real-time updates\n- **Moly**: OpenAI/LLM API integration - SSE streaming, MCP protocol, multi-provider support\n\n## When to Use\nUse this skill when:\n- Integrating Matrix SDK with Makepad\n- Building a Matrix client with Makepad\n- Implementing Matrix features (rooms, timelines, messages)\n- Handling Matrix SDK async operations in UI\n- Keywords: matrix-sdk, matrix client, robrix, matrix timeline, matrix room, sliding sync\n\n## Overview\n\nRobrix uses the `matrix-sdk` and `matrix-sdk-ui` crates to connect to Matrix homeservers. The key architectural decisions:\n\n1. **Sliding Sync**: Uses native sliding sync for efficient room list updates\n2. **Separate Runtime**: Tokio runtime runs Matrix operations, Makepad handles UI\n3. **Request/Response Pattern**: UI sends requests, receives actions/updates back\n4. **Per-Room Background Tasks**: Each room has dedicated timeline subscriber task\n\n## MatrixRequest Pattern\n\n### Request Enum Definition\n\n```rust\n/// All async requests that can be made to the Matrix worker task\npub enum MatrixRequest {\n    /// Login requests\n    Login(LoginRequest),\n    Logout { is_desktop: bool },\n\n    /// Timeline operations\n    PaginateRoomTimeline {\n        room_id: OwnedRoomId,\n        num_events: u16,\n        direction: PaginationDirection,\n    },\n    SendMessage {\n        room_id: OwnedRoomId,\n        message: RoomMessageEventContent,\n        replied_to: Option<Reply>,\n    },\n    EditMessage {\n        room_id: OwnedRoomId,\n        timeline_event_item_id: TimelineEventItemId,\n        edited_content: EditedContent,\n    },\n    RedactMessage {\n        room_id: OwnedRoomId,\n        timeline_event_id: TimelineEventItemId,\n        reason: Option<String>,\n    },\n\n    /// Room operations\n    JoinRoom { room_id: OwnedRoomId },\n    LeaveRoom { room_id: OwnedRoomId },\n    GetRoomMembers {\n        room_id: OwnedRoomId,\n        memberships: RoomMemberships,\n        local_only: bool,\n    },\n\n    /// User operations\n    GetUserProfile {\n        user_id: OwnedUserId,\n        room_id: Option<OwnedRoomId>,\n        local_only: bool,\n    },\n    IgnoreUser {\n        ignore: bool,\n        room_member: RoomMember,\n        room_id: OwnedRoomId,\n    },\n\n    /// Media operations\n    FetchAvatar {\n        mxc_uri: OwnedMxcUri,\n        on_fetched: fn(AvatarUpdate),\n    },\n    FetchMedia {\n        media_request: MediaRequestParameters,\n        on_fetched: OnMediaFetchedFn,\n        destination: MediaCacheEntryRef,\n        update_sender: Option<crossbeam_channel::Sender<TimelineUpdate>>,\n    },\n\n    /// Typing/read indicators\n    SendTypingNotice { room_id: OwnedRoomId, typing: bool },\n    ReadReceipt { room_id: OwnedRoomId, event_id: OwnedEventId },\n    FullyReadReceipt { room_id: OwnedRoomId, event_id: OwnedEventId },\n\n    /// Reactions\n    ToggleReaction {\n        room_id: OwnedRoomId,\n        timeline_event_id: TimelineEventItemId,\n        reaction: String,\n    },\n\n    /// Subscriptions\n    SubscribeToTypingNotices { room_id: OwnedRoomId, subscribe: bool },\n    SubscribeToPinnedEvents { room_id: OwnedRoomId, subscribe: bool },\n}\n```\n\n### Submit Pattern\n\n```rust\nstatic REQUEST_SENDER: Mutex<Option<UnboundedSender<MatrixRequest>>> = Mutex::new(None);\n\n/// Submit request from UI thread to async runtime\npub fn submit_async_request(req: MatrixRequest) {\n    if let Some(sender) = REQUEST_SENDER.lock().unwrap().as_ref() {\n        sender.send(req).expect(\"BUG: matrix worker task receiver died!\");\n    }\n}\n\n// Usage in UI\nsubmit_async_request(MatrixRequest::SendMessage {\n    room_id: room_id.clone(),\n    message: RoomMessageEventContent::text_plain(&text),\n    replied_to: self.reply_to.take(),\n});\n```\n\n## Worker Task Handler\n\n```rust\nasync fn matrix_worker_task(\n    mut request_receiver: UnboundedReceiver<MatrixRequest>,\n    login_sender: Sender<LoginRequest>,\n) -> Result<()> {\n    while let Some(request) = request_receiver.recv().await {\n        match request {\n            MatrixRequest::PaginateRoomTimeline { room_id, num_events, direction } => {\n                let (timeline, sender) = {\n                    let rooms = ALL_JOINED_ROOMS.lock().unwrap();\n                    let Some(room_info) = rooms.get(&room_id) else {\n                        continue;  // Room not ready yet\n                    };\n                    (room_info.timeline.clone(), room_info.update_sender.clone())\n                };\n\n                // Spawn dedicated task for this operation\n                Handle::current().spawn(async move {\n                    // Notify UI pagination is starting\n                    sender.send(TimelineUpdate::PaginationRunning(direction)).unwrap();\n                    SignalToUI::set_ui_signal();\n\n                    // Perform pagination\n                    let res = if direction == PaginationDirection::Forwards {\n                        timeline.paginate_forwards(num_events).await\n                    } else {\n                        timeline.paginate_backwards(num_events).await\n                    };\n\n                    // Send result to UI\n                    match res {\n                        Ok(fully_paginated) => {\n                            sender.send(TimelineUpdate::PaginationIdle {\n                                fully_paginated,\n                                direction,\n                            }).unwrap();\n                        }\n                        Err(error) => {\n                            sender.send(TimelineUpdate::PaginationError {\n                                error,\n                                direction,\n                            }).unwrap();\n                        }\n                    }\n                    SignalToUI::set_ui_signal();\n                });\n            }\n\n            MatrixRequest::JoinRoom { room_id } => {\n                let Some(client) = get_client() else { continue };\n\n                Handle::current().spawn(async move {\n                    let result_action = if let Some(room) = client.get_room(&room_id) {\n                        match room.join().await {\n                            Ok(()) => JoinRoomResultAction::Joined { room_id },\n                            Err(e) => JoinRoomResultAction::Failed { room_id, error: e },\n                        }\n                    } else {\n                        match client.join_room_by_id(&room_id).await {\n                            Ok(_) => JoinRoomResultAction::Joined { room_id },\n                            Err(e) => JoinRoomResultAction::Failed { room_id, error: e },\n                        }\n                    };\n                    Cx::post_action(result_action);\n                });\n            }\n            // ... handle other requests\n        }\n    }\n    Ok(())\n}\n```\n\n## Timeline Updates\n\n### TimelineUpdate Enum\n\n```rust\npub enum TimelineUpdate {\n    /// New items added to timeline\n    NewItems {\n        new_items: Vector<Arc<TimelineItem>>,\n        changed_indices: BTreeSet<usize>,\n        is_append: bool,\n    },\n    /// Pagination state changes\n    PaginationRunning(PaginationDirection),\n    PaginationIdle {\n        fully_paginated: bool,\n        direction: PaginationDirection,\n    },\n    PaginationError {\n        error: Error,\n        direction: PaginationDirection,\n    },\n    /// Message edit result\n    MessageEdited {\n        timeline_event_id: TimelineEventItemId,\n        result: Result<(), Error>,\n    },\n    /// Room members fetched\n    RoomMembersListFetched {\n        members: Vec<RoomMember>,\n        sort: PrecomputedMemberSort,\n        is_local_fetch: bool,\n    },\n    /// Unread count updated\n    NewUnreadMessagesCount(UnreadMessageCount),\n    /// User power levels fetched\n    UserPowerLevels(UserPowerLevels),\n}\n```\n\n### Per-Room Update Flow\n\n```rust\nstruct JoinedRoomDetails {\n    room_id: OwnedRoomId,\n    timeline: Arc<Timeline>,\n    timeline_update_sender: crossbeam_channel::Sender<TimelineUpdate>,\n    timeline_subscriber_handler_task: JoinHandle<()>,\n    typing_notice_subscriber: Option<EventHandlerDropGuard>,\n}\n\nimpl Drop for JoinedRoomDetails {\n    fn drop(&mut self) {\n        // Cleanup background tasks when room closes\n        self.timeline_subscriber_handler_task.abort();\n        drop(self.typing_notice_subscriber.take());\n    }\n}\n\n// Spawn subscriber for a room\nasync fn spawn_timeline_subscriber(\n    room_id: OwnedRoomId,\n    timeline: Arc<Timeline>,\n    sender: crossbeam_channel::Sender<TimelineUpdate>,\n) -> JoinHandle<()> {\n    tokio::spawn(async move {\n        let (items, mut stream) = timeline.subscribe().await;\n\n        // Send initial items\n        sender.send(TimelineUpdate::NewItems {\n            new_items: items,\n            changed_indices: BTreeSet::new(),\n            is_append: false,\n        }).unwrap();\n        SignalToUI::set_ui_signal();\n\n        // Listen for updates\n        while let Some(diff) = stream.next().await {\n            let update = process_timeline_diff(diff);\n            sender.send(update).unwrap();\n            SignalToUI::set_ui_signal();\n        }\n    })\n}\n```\n\n### Handling Updates in UI\n\n```rust\nimpl Widget for RoomScreen {\n    fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {\n        // Poll timeline updates on Signal events\n        if let Event::Signal = event {\n            while let Ok(update) = self.timeline_state.update_receiver.try_recv() {\n                match update {\n                    TimelineUpdate::NewItems { new_items, changed_indices, is_append } => {\n                        self.apply_new_items(cx, new_items, changed_indices, is_append);\n                    }\n                    TimelineUpdate::PaginationIdle { fully_paginated, direction } => {\n                        self.set_pagination_idle(cx, direction, fully_paginated);\n                    }\n                    TimelineUpdate::PaginationError { error, direction } => {\n                        self.show_pagination_error(cx, direction, &error);\n                    }\n                    // ... handle other updates\n                }\n            }\n        }\n\n        self.view.handle_event(cx, event, scope);\n    }\n}\n```\n\n## Room List Updates\n\n### RoomsListUpdate Enum\n\n```rust\npub enum RoomsListUpdate {\n    NotLoaded,\n    LoadedRooms { max_rooms: Option<u32> },\n    AddInvitedRoom(InvitedRoomInfo),\n    AddJoinedRoom(JoinedRoomInfo),\n    ClearRooms,\n    UpdateLatestEvent {\n        room_id: OwnedRoomId,\n        timestamp: MilliSecondsSinceUnixEpoch,\n        latest_message_text: String,\n    },\n    UpdateNumUnreadMessages {\n        room_id: OwnedRoomId,\n        unread_messages: UnreadMessageCount,\n        unread_mentions: u64,\n    },\n    UpdateRoomName { new_room_name: RoomNameId },\n    UpdateRoomAvatar { room_id: OwnedRoomId, avatar: FetchedRoomAvatar },\n    RemoveRoom { room_id: OwnedRoomId, new_state: RoomState },\n    Status { status: String },\n    ScrollToRoom(OwnedRoomId),\n}\n\nstatic PENDING_ROOM_UPDATES: SegQueue<RoomsListUpdate> = SegQueue::new();\n\npub fn enqueue_rooms_list_update(update: RoomsListUpdate) {\n    PENDING_ROOM_UPDATES.push(update);\n    SignalToUI::set_ui_signal();\n}\n```\n\n## Client Build Pattern\n\n```rust\nasync fn build_client(\n    homeserver_url: &str,\n    data_dir: &Path,\n) -> Result<(Client, ClientSessionPersisted)> {\n    // Generate unique subfolder for this session\n    let db_subfolder = format!(\"db_{}\", chrono::Local::now().format(\"%F_%H_%M_%S_%f\"));\n    let db_path = data_dir.join(db_subfolder);\n\n    // Generate random passphrase for encryption\n    let passphrase: String = {\n        use rand::{Rng, thread_rng};\n        thread_rng()\n            .sample_iter(rand::distributions::Alphanumeric)\n            .take(32)\n            .map(char::from)\n            .collect()\n    };\n\n    let client = Client::builder()\n        .server_name_or_homeserver_url(homeserver_url)\n        .sqlite_store(&db_path, Some(&passphrase))\n        .sliding_sync_version_builder(VersionBuilder::DiscoverNative)\n        .with_decryption_settings(DecryptionSettings {\n            sender_device_trust_requirement: TrustRequirement::Untrusted,\n        })\n        .with_encryption_settings(EncryptionSettings {\n            auto_enable_cross_signing: true,\n            backup_download_strategy: BackupDownloadStrategy::OneShot,\n            auto_enable_backups: true,\n        })\n        .request_config(\n            RequestConfig::new().timeout(Duration::from_secs(60))\n        )\n        .build()\n        .await?;\n\n    Ok((client, ClientSessionPersisted { homeserver: homeserver_url.to_string(), db_path, passphrase }))\n}\n```\n\n## Best Practices\n\n1. **Always spawn tasks**: Don't block the worker task receiver loop\n2. **Use crossbeam channels for per-room updates**: More efficient than global queue\n3. **Always call SignalToUI::set_ui_signal()**: After enqueueing any update\n4. **Handle room not ready**: Skip requests for rooms not yet in `ALL_JOINED_ROOMS`\n5. **Cleanup on drop**: Abort background tasks when rooms are closed\n6. **Use Cx::post_action for results**: Posted actions are handled in App::handle_actions\n7. **Use SegQueue for high-frequency updates**: Lock-free for room list updates\n\n## Reference Files\n\n- `references/matrix-client.md` - Matrix client setup and login patterns (Robrix)\n- `references/timeline-handling.md` - Matrix timeline subscription patterns (Robrix)\n- `references/moly-api-integration.md` - Moly API integration patterns\n  - OpenAI client with SSE streaming\n  - Platform-agnostic async streams\n  - MCP (Model Context Protocol) integration\n  - Tool approval flow\n  - MolyClient for local server\n  - BotContext for multi-provider support\n\n## Limitations\n- Use this skill only when the task clearly matches the scope described above.\n- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.\n- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.","tags":["robius","matrix","integration","antigravity","awesome","skills","sickn33","agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding"],"capabilities":["skill","source-sickn33","skill-robius-matrix-integration","topic-agent-skills","topic-agentic-skills","topic-ai-agent-skills","topic-ai-agents","topic-ai-coding","topic-ai-workflows","topic-antigravity","topic-antigravity-skills","topic-claude-code","topic-claude-code-skills","topic-codex-cli","topic-codex-skills"],"categories":["antigravity-awesome-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/sickn33/antigravity-awesome-skills/robius-matrix-integration","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add sickn33/antigravity-awesome-skills","source_repo":"https://github.com/sickn33/antigravity-awesome-skills","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 34583 github stars · SKILL.md body (14,075 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-22T18:52:09.050Z","embedding":null,"createdAt":"2026-04-18T21:43:39.989Z","updatedAt":"2026-04-22T18:52:09.050Z","lastSeenAt":"2026-04-22T18:52:09.050Z","tsv":"'1':144,1140 '2':156,1152 '3':167,1166 '32':1062 '4':176,1177 '5':1192 '6':1203 '60':1126 '7':1218 'abort':1196 'action':578,627,629,1207,1211,1217 'actions/updates':174 'ad':644 'addinvitedroom':929 'addjoinedroom':931 'agnost':1261 'all_joined_rooms.lock':471 'alphanumer':1060 'alway':1141,1167 'api':42,68,1251 'app':1215 'append':656,797,874,884 'applic':45 'approv':1270 'arc':651,720,767 'architectur':142 'ask':1315 'async':105,196,389,394,419,438,497,574,758,775,1002,1262 'auto':1104,1114 'avatar':963 'avatarupd':309 'await':456,525,531,589,611,782,812,1128 'back':175 'background':180,745,1197 'backup':1109,1116 'backupdownloadstrategi':1112 'backward':528 'base':46 'best':37,1138 'block':1146 'bool':217,278,290,293,332,364,370,657,666,696 'botcontext':1276 'boundari':1323 'btreeset':654,794 'bug':409 'build':90,999,1004,1127 'builder':1070,1087 'call':1168 'chang':652,660,792,871,881 'channel':323,725,770,1155 'char':1064 'chrono':1026 'clarif':1317 'cleanup':744,1193 'clear':1290 'clearroom':933 'client':25,93,114,566,568,998,1005,1013,1068,1069,1130,1237,1255 'client.get':583 'client.join':605 'clientsessionpersist':1014,1131 'close':749,1202 'codebas':51,53 'collect':1066 'config':1119 'connect':136 'content':248 'context':1266 'continu':481,570 'count':698 'crate':134 'criteria':1326 'critic':5 'cross':1106 'crossbeam':322,724,769,1154 'current':495,572 'cx':625,840,842,878,893,904,912,1205 'data':1009 'data_dir.join':1038 'db':1022,1025,1036,1039,1080,1135 'decis':143 'decrypt':1091 'decryptionset':1093 'dedic':185,489 'definit':193 'describ':1294 'desktop':216 'destin':317 'devic':1095 'die':414 'diff':810,817,818 'dir':1010 'direct':227,465,507,518,546,554,667,672,889,894,900,905 'discovern':1089 'distribut':1059 'download':1110 'drop':737,741,751,1195 'durat':1123 'e':596,602,618,624 'edit':247,675 'editedcont':249 'editmessag':238 'effici':152,1162 'els':480,526,569,603 'enabl':1105,1115 'encrypt':1045,1101 'encryptionset':1103 'enqueu':986,1174 'enum':192,208,637,640,919,922 'environ':1306 'environment-specif':1305 'err':548,595,617 'error':549,553,601,623,670,671,684,899,903,906 'event':225,243,255,337,344,353,464,524,530,679,837,843,844,853,856,858,911,913 'expect':408 'expert':1311 'extern':41 'f':1030,1034 'fail':598,620 'fals':798 'featur':98 'fetch':307,315,687,695,705 'fetchavatar':302 'fetchedroomavatar':964 'fetchmedia':310 'file':1234 'flow':712,1271 'fn':308,392,439,740,759,835,985,1003 'format':1024,1029 'forward':520,522 'free':1228 'frequenc':1224 'fulli':539,544,664,887,895 'fullyreadreceipt':340 'generat':1015,1041 'get':567 'getroommemb':270 'getuserprofil':281 'global':1164 'h':1031 'handl':102,165,494,571,630,826,836,907,1178,1213,1216 'handler':436,729 'high':1223 'high-frequ':1222 'homeserv':139,1006,1074,1076,1132 'homeserver_url.to':1133 'id':222,231,240,245,252,256,264,268,272,283,286,298,329,335,338,342,345,350,354,361,367,424,462,479,563,586,594,600,608,610,616,622,680,717,764,936,946,961,967 'idl':892 'ignor':292 'ignoreus':291 'impl':736,831 'implement':96 'indic':326,653,793,872,882 'info':476 'initi':784 'input':1320 'integr':4,10,35,40,57,69,85,1252,1268 'invitedroominfo':930 'item':244,643,649,778,785,790,791,870,877,880 'iter':1057 'join':592,614,1190 'joinedroomdetail':715,739 'joinedroominfo':932 'joinhandl':731,772 'joinroom':262,561 'joinroomresultact':591,597,613,619 'key':141 'keyword':109 'latest':940 'leaveroom':266 'let':399,452,466,469,473,515,564,576,580,777,808,813,855,860,1021,1035,1046,1067 'level':704 'limit':1282 'list':154,916,988,1231 'listen':804 'loadedroom':925 'local':276,288,694,1027,1274 'lock':1227 'lock-fre':1226 'login':210,212,447,1240 'loginrequest':213 'logout':214 'loop':1151 'm':1032 'made':201 'makepad':12,44,89,95,164 'map':1063 'match':457,536,587,604,865,1291 'matrix':3,8,15,22,24,27,29,33,55,86,92,97,103,111,113,116,118,127,131,138,162,204,410,440,1236,1244 'matrix-sdk':21,110,126 'matrix-sdk-ui':130 'matrixrequest':19,189,209,397,421,459,560 'max':926 'mcp':72,1264 'media':300,311 'mediacacheentryref':318 'mediarequestparamet':313 'member':295,686,689 'membership':274 'mention':952 'messag':101,233,426,674,941,949 'messageedit':677 'millisecondssinceunixepoch':939 'miss':1328 'model':1265 'moli':50,66,1250 'molycli':1272 'move':498,575,776 'multi':75,1279 'multi-provid':74,1278 'mut':443,742,779,838,841,846 'mutex':377,380 'mxc':303 'name':957,1072 'nativ':148 'new':381,642,648,789,795,869,876,879,955,969,983,1121 'newitem':647,788,868 'newunreadmessagescount':700 'none':382 'notic':733 'notifi':499 'notload':924 'num':224,463,523,529 'ok':538,590,612,633,861,1129 'oneshot':1113 'onmediafetchedfn':316 'openai':1254 'openai/llm':67 'oper':106,163,219,261,280,301,493 'option':237,259,287,321,378,735,928 'output':1300 'overview':122 'ownedeventid':339,346 'ownedmxcuri':305 'ownedroomid':223,232,241,253,265,269,273,299,330,336,343,351,362,368,718,765,937,947,962,968,976 'owneduserid':284 'pagin':501,514,540,545,658,665,888,891,896,902 'paginateroomtimelin':220,460 'paginationdirect':228,519,662,668,673 'paginationerror':552,669,898 'paginationidl':543,663,886 'paginationrun':506,661 'passphras':1043,1047,1083,1137 'path':1011,1037,1081,1136 'pattern':169,190,372,1000,1241,1247,1253 'pend':978 'pending_room_updates.push':992 'per':178,709,1158 'per-room':177,708,1157 'perform':513 'permiss':1321 'plain':429 'platform':1260 'platform-agnost':1259 'poll':848 'post':626,1206,1210 'power':703 'practic':38,1139 'precomputedmembersort':692 'process':815 'protocol':73,1267 'provid':76,1280 'pub':207,391,639,921,984 'queue':1165 'rand':1050,1058 'random':1042 'reaction':347,356 'readi':484,1181 'readreceipt':333 'real':63 'real-tim':62 'reason':258 'receiv':173,413,445,1150 'recv':864 'redactmessag':250 'ref':405 'refer':1233 'references/matrix-client.md':1235 'references/moly-api-integration.md':1249 'references/timeline-handling.md':1243 'removeroom':965 'repli':235,431 'req':396,407 'request':172,191,197,211,312,375,384,395,420,444,454,458,632,1118,1183 'request/response':168 'request_receiver.recv':455 'request_sender.lock':402 'requestconfig':1120 'requir':1097,1319 'res':516,537 'result':450,533,577,628,676,682,683,1012,1209 'review':1312 'rng':1051,1053,1055 'robius':2,32 'robius-matrix-integr':1 'robrix':26,48,54,115,123,1242,1248 'room':28,99,119,153,179,183,221,230,239,251,260,263,267,271,285,294,297,328,334,341,349,360,366,423,461,470,475,478,482,562,582,584,585,593,599,606,609,615,621,685,710,716,748,757,763,915,927,935,945,956,960,966,979,987,1159,1179,1185,1191,1200,1230 'room.join':588 'room_id.clone':425 'room_info.timeline.clone':486 'room_info.update_sender.clone':487 'roommemb':296 'roommembership':275 'roommemberslistfetch':688 'roommessageeventcont':234,427 'roomnameid':958 'rooms.get':477 'roomscreen':834 'roomslistupd':918,923,991 'roomstat':971 'run':161 'runtim':158,160,390 'rust':194,373,437,638,713,830,920,1001 'safeti':1322 'sampl':1056 'scope':845,847,914,1293 'scrolltoroom':975 'sdk':9,16,23,34,56,87,104,112,128,132 'sec':1125 'segqueu':981,982,1220 'self':743,839 'self.apply':875 'self.reply_to.take':433 'self.set':890 'self.show':901 'self.timeline_state.update_receiver.try':863 'self.timeline_subscriber_handler_task.abort':750 'self.typing_notice_subscriber.take':752 'self.view.handle':910 'send':171,532,783 'sender':320,324,376,401,448,449,468,723,726,768,771,1094 'sender.send':406,504,541,550,786,819 'sendmessag':229,422 'sendtypingnotic':327 'separ':157 'server':1071,1275 'session':1020 'set':510,557,801,823,995,1092,1102,1170 'setup':1238 'sign':1107 'signal':512,559,803,825,852,857,997,1172 'signaltoui':509,556,800,822,994,1169 'skill':36,83,1285 'skill-robius-matrix-integration' 'skip':1182 'slide':17,58,120,145,149,1084 'sort':691 'sourc':52 'source-sickn33' 'spawn':488,496,573,753,760,774,1142 'specif':1307 'sqlite':1078 'sse':70,1257 'start':503 'state':659,970 'static':374,977 'status':972,973 'stop':1313 'store':1079 'str':1008 'strategi':1111 'stream':71,780,1258,1263 'stream.next':811 'string':357,943,974,1048,1134 'struct':714 'subfold':1017,1023,1040 'submit':371,383,393,418 'subscrib':187,363,369,728,734,754,762 'subscribetopinnedev':365 'subscribetotypingnotic':359 'subscript':61,358,1246 'substitut':1303 'success':1325 'support':77,1281 'sync':18,59,121,146,150,1085 'take':1061 'task':181,188,206,412,435,442,490,730,746,1143,1149,1198,1289 'test':1309 'text':428,430,942 'thread':387,1052,1054 'time':64 'timelin':20,60,100,117,186,218,242,254,352,467,634,646,678,719,721,727,761,766,816,849,1245 'timeline.paginate':521,527 'timeline.subscribe':781 'timelineeventitemid':246,257,355,681 'timelineupd':505,542,551,636,641,787,867,885,897 'timeout':1122 'timestamp':938 'togglereact':348 'tokio':159,773 'tool':1269 'topic-agent-skills' 'topic-agentic-skills' 'topic-ai-agent-skills' 'topic-ai-agents' 'topic-ai-coding' 'topic-ai-workflows' 'topic-antigravity' 'topic-antigravity-skills' 'topic-claude-code' 'topic-claude-code-skills' 'topic-codex-cli' 'topic-codex-skills' 'treat':1298 'trigger':13 'true':1108,1117 'trust':1096 'trustrequir':1098 'type':331,732 'typing/read':325 'u16':226 'u64':953 'ui':108,133,166,170,386,417,500,511,535,558,802,824,829,996,1171 'unboundedreceiv':446 'unboundedsend':379 'uniqu':1016 'unread':697,948,951 'unreadmessagecount':701,950 'untrust':1099 'unwrap':403,472,508,547,555,799,821 'updat':65,155,319,635,699,711,722,806,814,820,827,850,862,866,909,917,980,989,990,993,1160,1176,1225,1232 'updatelatestev':934 'updatenumunreadmessag':944 'updateroomavatar':959 'updateroomnam':954 'uri':304 'url':1007,1075,1077 'usag':415 'use':6,80,81,124,147,1049,1153,1204,1219,1283 'user':279,282,702 'userpowerlevel':706,707 'valid':1308 'vec':690 'vector':650 'version':1086 'versionbuild':1088 'widget':832 'worker':205,411,434,441,1148 'yet':485,1187 '聊天客户端':31 '集成':30","prices":[{"id":"88313989-104a-4287-b388-38b3f6983ba3","listingId":"8110c83a-b23a-453a-8768-a746ebbfe2d3","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"sickn33","category":"antigravity-awesome-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T21:43:39.989Z"}],"sources":[{"listingId":"8110c83a-b23a-453a-8768-a746ebbfe2d3","source":"github","sourceId":"sickn33/antigravity-awesome-skills/robius-matrix-integration","sourceUrl":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/robius-matrix-integration","isPrimary":false,"firstSeenAt":"2026-04-18T21:43:39.989Z","lastSeenAt":"2026-04-22T18:52:09.050Z"}],"details":{"listingId":"8110c83a-b23a-453a-8768-a746ebbfe2d3","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"sickn33","slug":"robius-matrix-integration","github":{"repo":"sickn33/antigravity-awesome-skills","stars":34583,"topics":["agent-skills","agentic-skills","ai-agent-skills","ai-agents","ai-coding","ai-workflows","antigravity","antigravity-skills","claude-code","claude-code-skills","codex-cli","codex-skills","cursor","cursor-skills","developer-tools","gemini-cli","gemini-skills","kiro","mcp","skill-library"],"license":"mit","html_url":"https://github.com/sickn33/antigravity-awesome-skills","pushed_at":"2026-04-22T06:40:00Z","description":"Installable GitHub library of 1,400+ agentic skills for Claude Code, Cursor, Codex CLI, Gemini CLI, Antigravity, and more. Includes installer CLI, bundles, workflows, and official/community skill collections.","skill_md_sha":"31692639a5afb680b0ff1ae77b399185344538be","skill_md_path":"skills/robius-matrix-integration/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/sickn33/antigravity-awesome-skills/tree/main/skills/robius-matrix-integration"},"layout":"multi","source":"github","category":"antigravity-awesome-skills","frontmatter":{"name":"robius-matrix-integration","description":"CRITICAL: Use for Matrix SDK integration with Makepad. Triggers on:\nMatrix SDK, sliding sync, MatrixRequest, timeline,\nmatrix-sdk, matrix client, robrix, matrix room,\nMatrix 集成, 聊天客户端"},"skills_sh_url":"https://skills.sh/sickn33/antigravity-awesome-skills/robius-matrix-integration"},"updatedAt":"2026-04-22T18:52:09.050Z"}}