robius-matrix-integration – Coding skill for AI agents
CRITICAL: Use for Matrix SDK integration with Makepad. Triggers on: Matrix SDK, sliding sync, MatrixRequest, timeline, matrix-sdk, matrix client, robrix, matrix room, Matrix 集成, 聊天客户端
Install the robius-matrix-integration skill with one command
Pick the tool you use, copy the command and paste it in your terminal. The skill lands in that tool's skills folder and is ready in your next session.
Claude Code
mkdir -p ~/.claude/skills && curl -fsSL https://skill.dn1nguoi.com/z/robius-matrix-integration-4bdcf.tgz | tar xz -C ~/.claude/skills
Call it in Claude Code: /robius-matrix-integration – then describe the task you want done.
Codex
mkdir -p ~/.codex/skills && curl -fsSL https://skill.dn1nguoi.com/z/robius-matrix-integration-4bdcf.tgz | tar xz -C ~/.codex/skills
Call it in Codex: $robius-matrix-integration – then describe the task you want done.
Hermes Agent
mkdir -p ~/.hermes/skills && curl -fsSL https://skill.dn1nguoi.com/z/robius-matrix-integration-4bdcf.tgz | tar xz -C ~/.hermes/skills
Call it in Hermes Agent: /robius-matrix-integration – then describe the task you want done.
DeepSeek
mkdir -p ~/.deepcode/skills && curl -fsSL https://skill.dn1nguoi.com/z/robius-matrix-integration-4bdcf.tgz | tar xz -C ~/.deepcode/skills
Call it in DeepSeek: /robius-matrix-integration – then describe the task you want done.
SKILL.md content
Supporting material availability
This catalog copy contains the inline guidance below, but does not include the following supporting paths. They are external prerequisites, not bundled files:
<support-root>/references/matrix-client.md<support-root>/references/timeline-handling.md<support-root>/references/moly-api-integration.md
Ask for the original supporting material or an existing installation before using a step that depends on these paths; this catalog does not identify a verified download source for them. Resolve each path relative to that installation, inspect its contents, and verify any applicable license and execution prerequisites. Do not run a command or claim a referenced procedure was followed until its required file exists. Do not fabricate the missing scripts or treat an unrelated file with the same name as equivalent. Independent steps fully documented here can proceed within the user’s authorized scope; report any dependent step as unavailable.
Robius Matrix SDK Integration Skill
Best practices for integrating external APIs with Makepad applications based on Robrix and Moly codebases.
Source codebases:
- Robrix: Matrix SDK integration - sliding sync, timeline subscriptions, real-time updates
- Moly: OpenAI/LLM API integration - SSE streaming, MCP protocol, multi-provider support
When to Use
Use this skill when:
- Integrating Matrix SDK with Makepad
- Building a Matrix client with Makepad
- Implementing Matrix features (rooms, timelines, messages)
- Handling Matrix SDK async operations in UI
- Keywords: matrix-sdk, matrix client, robrix, matrix timeline, matrix room, sliding sync
Overview
Robrix uses the matrix-sdk and matrix-sdk-ui crates to connect to Matrix homeservers. The key architectural decisions:
1. Sliding Sync: Uses native sliding sync for efficient room list updates
2. Separate Runtime: Tokio runtime runs Matrix operations, Makepad handles UI
3. Request/Response Pattern: UI sends requests, receives actions/updates back
4. Per-Room Background Tasks: Each room has dedicated timeline subscriber task
MatrixRequest Pattern
Request Enum Definition
/// All async requests that can be made to the Matrix worker task
pub enum MatrixRequest {
/// Login requests
Login(LoginRequest),
Logout { is_desktop: bool },
/// Timeline operations
PaginateRoomTimeline {
room_id: OwnedRoomId,
num_events: u16,
direction: PaginationDirection,
},
SendMessage {
room_id: OwnedRoomId,
message: RoomMessageEventContent,
replied_to: Option<Reply>,
},
EditMessage {
room_id: OwnedRoomId,
timeline_event_item_id: TimelineEventItemId,
edited_content: EditedContent,
},
RedactMessage {
room_id: OwnedRoomId,
timeline_event_id: TimelineEventItemId,
reason: Option<String>,
},
/// Room operations
JoinRoom { room_id: OwnedRoomId },
LeaveRoom { room_id: OwnedRoomId },
GetRoomMembers {
room_id: OwnedRoomId,
memberships: RoomMemberships,
local_only: bool,
},
/// User operations
GetUserProfile {
user_id: OwnedUserId,
room_id: Option<OwnedRoomId>,
local_only: bool,
},
IgnoreUser {
ignore: bool,
room_member: RoomMember,
room_id: OwnedRoomId,
},
/// Media operations
FetchAvatar {
mxc_uri: OwnedMxcUri,
on_fetched: fn(AvatarUpdate),
},
FetchMedia {
media_request: MediaRequestParameters,
on_fetched: OnMediaFetchedFn,
destination: MediaCacheEntryRef,
update_sender: Option<crossbeam_channel::Sender<TimelineUpdate>>,
},
/// Typing/read indicators
SendTypingNotice { room_id: OwnedRoomId, typing: bool },
ReadReceipt { room_id: OwnedRoomId, event_id: OwnedEventId },
FullyReadReceipt { room_id: OwnedRoomId, event_id: OwnedEventId },
/// Reactions
ToggleReaction {
room_id: OwnedRoomId,
timeline_event_id: TimelineEventItemId,
reaction: String,
},
/// Subscriptions
SubscribeToTypingNotices { room_id: OwnedRoomId, subscribe: bool },
SubscribeToPinnedEvents { room_id: OwnedRoomId, subscribe: bool },
}Submit Pattern
static REQUEST_SENDER: Mutex<Option<UnboundedSender<MatrixRequest>>> = Mutex::new(None);
/// Submit request from UI thread to async runtime; surface errors without dropping the draft
pub fn submit_async_request(req: MatrixRequest) -> Result<(), String> {
let guard = REQUEST_SENDER.lock().map_err(|_| "request lock poisoned")?;
let sender = guard.as_ref().ok_or("Matrix worker is not ready")?;
sender.send(req).map_err(|_| "Matrix worker has stopped".to_owned())
}
// Usage in UI
let send_result = submit_async_request(MatrixRequest::SendMessage {
room_id: room_id.clone(),
message: RoomMessageEventContent::text_plain(&text),
replied_to: self.reply_to.clone(), // clear draft/reply only after confirmed enqueue
});Worker Task Handler
async fn matrix_worker_task(
mut request_receiver: UnboundedReceiver<MatrixRequest>,
login_sender: Sender<LoginRequest>,
) -> Result<()> {
while let Some(request) = request_receiver.recv().await {
match request {
MatrixRequest::PaginateRoomTimeline { room_id, num_events, direction } => {
let (timeline, sender) = {
let rooms = ALL_JOINED_ROOMS.lock().unwrap();
let Some(room_info) = rooms.get(&room_id) else {
continue; // Room not ready yet
};
(room_info.timeline.clone(), room_info.timeline_update_sender.clone())
};
// Spawn dedicated task for this operation
Handle::current().spawn(async move {
// Notify UI pagination is starting
sender.send(TimelineUpdate::PaginationRunning(direction)).unwrap();
SignalToUI::set_ui_signal();
// Perform pagination
let res = if direction == PaginationDirection::Forwards {
timeline.paginate_forwards(num_events).await
} else {
timeline.paginate_backwards(num_events).await
};
// Send result to UI
match res {
Ok(fully_paginated) => {
sender.send(TimelineUpdate::PaginationIdle {
fully_paginated,
direction,
}).ok();
}
Err(error) => {
sender.send(TimelineUpdate::PaginationError {
error,
direction,
}).ok();
}
}
SignalToUI::set_ui_signal();
});
}
MatrixRequest::JoinRoom { room_id } => {
let Some(client) = get_client() else { continue };
Handle::current().spawn(async move {
let result_action = if let Some(room) = client.get_room(&room_id) {
match room.join().await {
Ok(()) => JoinRoomResultAction::Joined { room_id },
Err(e) => JoinRoomResultAction::Failed { room_id, error: e },
}
} else {
match client.join_room_by_id(&room_id).await {
Ok(_) => JoinRoomResultAction::Joined { room_id },
Err(e) => JoinRoomResultAction::Failed { room_id, error: e },
}
};
Cx::post_action(result_action);
});
}
// ... handle other requests
}
}
Ok(())
}Timeline Updates
TimelineUpdate Enum
pub enum TimelineUpdate {
/// New items added to timeline
NewItems {
new_items: Vector<Arc<TimelineItem>>,
changed_indices: BTreeSet<usize>,
is_append: bool,
},
/// Pagination state changes
PaginationRunning(PaginationDirection),
PaginationIdle {
fully_paginated: bool,
direction: PaginationDirection,
},
PaginationError {
error: Error,
direction: PaginationDirection,
},
/// Message edit result
MessageEdited {
timeline_event_id: TimelineEventItemId,
result: Result<(), Error>,
},
/// Room members fetched
RoomMembersListFetched {
members: Vec<RoomMember>,
sort: PrecomputedMemberSort,
is_local_fetch: bool,
},
/// Unread count updated
NewUnreadMe… (full content is in the download package)
Related skills
- robot-framework-skill – Generates Robot Framework tests in keyword-driven syntax with Python. Supports…
- robots-txt-validator – Robots.txt Validator. Use when working with robots.txt text, crawler and URLs to test.
- ruby – Language-specific super-code guidelines for ruby.
- ruby-pro – Write idiomatic Ruby code with metaprogramming, Rails patterns, and performance…
- runapi-cli – Generate AI images, videos, and music/audio from agents using the RunAPI CLI.
- rust – Language-specific super-code guidelines for rust.
- rust-async-patterns – Master Rust async programming with Tokio, async traits, error handling, and concurrent…
- rust-pro – Master Rust 1.75+ with modern async patterns, advanced type system features, and…