Token导航 LogoToken导航

Agent Skill · 开发

robius-event-action(罗宾斯事件动作)

robius-event-action 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

robius-event-action 是开发类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证信息还不明确,第三方扫描已通过,按安装量在开发类的 21,746 个 Skill 里排第 17,811。

总安装 376周安装 16GitHub Stars 35,699下载 132核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:robius-event-action(罗宾斯事件动作)
来源仓库:https://github.com/sickn33/antigravity-awesome-skills
仓库路径:skills/robius-event-action
安装命令:
npx skills add https://github.com/sickn33/antigravity-awesome-skills --skill robius-event-action
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/sickn33/antigravity-awesome-skills --skill robius-event-action

这个 Skill 是做什么的

开发类 Skill 面向写代码、改代码和排查问题,一般会读写仓库文件,部分还会执行构建或测试命令。

用于罗宾斯事件-动作模型的具体实现与流程编排。支持异步消息队列、错误重试与幂等性保证机制。可自动生成事件总线注册与处理器绑定代码。适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。生产环境部署时应配置适当的事件溯源与审计日志。

robius-event-action 属于开发类 Skill,可作为该场景下的辅助能力补充。

来源仓库内路径:skills/robius-event-action

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/sickn33/antigravity-awesome-skills --skill rob…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

robius-event-action 怎么安装?

在终端执行 npx skills add https://github.com/sickn33/antigravity-awesome-skills --skill robius-event-…。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

robius-event-action 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

robius-event-action 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

robius-event-action 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

robius-event-action 用的人多吗?

公开数据是累计安装 376 次,近一周安装 16 次,下载 132 次,GitHub 35,699 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

robius-event-action 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 第三方扫描已通过,常见的高风险行为没有命中。
  • 来源仓库有 35,699 星,维护活跃度相对可查。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理开发类任务、又不想每次都手写提示词的人。

不太适合

  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

开发类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
skill-vetter

技能审查员 · OpenClaw

8,779,018986操作浏览器MIT-0通过
ontology

本体论 · OpenClaw

6,636,960576只读MIT-0通过
entra-app-registration

内部应用程序注册 · Codex、Claude

6,631,872764接触敏感数据未明确通过
entra-app-registration

内部应用程序注册 · Codex、Claude

3,757,680201接触敏感数据未明确通过
nano-banana-pro

纳米香蕉专业版 · OpenClaw

3,526,898364接触敏感数据MIT-0有提醒
robius-event-action

罗宾斯事件动作 · 本页

37635,699需要联网未明确通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Robius Event and Action Patterns Skill

Best practices for event handling and action patterns in Makepad applications based on Robrix and Moly codebases.

Source codebases:

  • Robrix: Matrix chat client - MessageAction, RoomsListAction, AppStateAction
  • Moly: AI chat application - StoreAction, ChatAction, NavigationAction, Timer patterns

Triggers

Use this skill when:

  • Implementing custom actions in Makepad
  • Handling events in widgets
  • Centralizing action handling in App
  • Widget-to-widget communication
  • Keywords: makepad action, makepad event, widget action, handle_actions, cx.widget_action

Custom Action Pattern

Defining Domain-Specific Actions

use makepad_widgets::*;

/// Actions emitted by the Message widget
#[derive(Clone, DefaultNone, Debug)]
pub enum MessageAction {
    /// User wants to react to a message
    React { details: MessageDetails, reaction: String },
    /// User wants to reply to a message
    Reply(MessageDetails),
    /// User wants to edit a message
    Edit(MessageDetails),
    /// User wants to delete a message
    Delete(MessageDetails),
    /// User requested to open context menu
    OpenContextMenu { details: MessageDetails, abs_pos: DVec2 },
    /// Required default variant
    None,
}

/// Data associated with a message action
#[derive(Clone, Debug)]
pub struct MessageDetails {
    pub room_id: OwnedRoomId,
    pub event_id: OwnedEventId,
    pub content: String,
    pub sender_id: OwnedUserId,
}

Emitting Actions from Widgets

impl Widget for Message {
    fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {
        self.view.handle_event(cx, event, scope);

        let area = self.view.area();
        match event.hits(cx, area) {
            Hit::FingerDown(_fe) => {
                cx.set_key_focus(area);
            }
            Hit::FingerUp(fe) => {
                if fe.is_over && fe.is_primary_hit() && fe.was_tap() {
                    // Emit widget action
                    cx.widget_action(
                        self.widget_uid(),
                        &scope.path,
                        MessageAction::Reply(self.get_details()),
                    );
                }
            }
            Hit::FingerLongPress(lpe) => {
                cx.widget_action(
                    self.widget_uid(),
                    &scope.path,
                    MessageAction::OpenContextMenu {
                        details: self.get_details(),
                        abs_pos: lpe.abs,
                    },
                );
            }
            _ => {}
        }
    }
}

Centralized Action Handling in App

Using MatchEvent Trait

impl MatchEvent for App {
    fn handle_startup(&mut self, cx: &mut Cx) {
        // Called once on app startup
        self.initialize(cx);
    }

    fn handle_actions(&mut self, cx: &mut Cx, actions: &Actions) {
        for action in actions {
            // Pattern 1: Direct downcast for non-widget actions
            if let Some(action) = action.downcast_ref::<LoginAction>() {
                match action {
                    LoginAction::LoginSuccess => {
                        self.app_state.logged_in = true;
                        self.update_ui_visibility(cx);
                    }
                    LoginAction::LoginFailure(error) => {
                        self.show_error(cx, error);
                    }
                }
                continue;  // Action handled
            }

            // Pattern 2: Widget action cast
            if let MessageAction::OpenContextMenu { details, abs_pos } =
                action.as_widget_action().cast()
            {
                self.show_context_menu(cx, details, abs_pos);
                continue;
            }

            // Pattern 3: Match on downcast_ref for enum variants
            match action.downcast_ref() {
                Some(AppStateAction::RoomFocused(room)) => {
                    self.app_state.selected_room = Some(room.clone());
                    continue;
                }
                Some(AppStateAction::NavigateToRoom { destination }) => {
                    self.navigate_to_room(cx, destination);
                    continue;
                }
                _ => {}
            }

            // Pattern 4: Modal actions
            match action.downcast_ref() {
                Some(ModalAction::Open { kind }) => {
                    self.ui.modal(ids!(my_modal)).open(cx);
                    continue;
                }
                Some(ModalAction::Close { was_internal }) => {
                    if *was_internal {
                        self.ui.modal(ids!(my_modal)).close(cx);
                    }
                    continue;
                }
                _ => {}
            }
        }
    }
}

impl AppMain for App {
    fn handle_event(&mut self, cx: &mut Cx, event: &Event) {
        // Forward to MatchEvent
        self.match_event(cx, event);

        // Pass events to widget tree
        let scope = &mut Scope::with_data(&mut self.app_state);
        self.ui.handle_event(cx, event, scope);
    }
}

Action Types

Widget Actions (UI Thread)

Emitted by widgets, handled in the same frame:

// Emitting
cx.widget_action(
    self.widget_uid(),
    &scope.path,
    MyAction::Something,
);

// Handling (two patterns)
// Pattern A: Direct cast for widget actions
if let MyAction::Something = action.as_widget_action().cast() {
    // handle...
}

// Pattern B: With widget UID matching
if let Some(uid) = action.as_widget_action().widget_uid() {
    if uid == my_expected_uid {
        if let MyAction::Something = action.as_widget_action().cast() {
            // handle...
        }
    }
}

Posted Actions (From Async)

Posted from async tasks, received in next event cycle:

// In async task
Cx::post_action(DataFetchedAction { data });
SignalToUI::set_ui_signal();  // Wake UI thread

// Handling in App (NOT widget actions)
if let Some(action) = action.downcast_ref::<DataFetchedAction>() {
    self.process_data(&action.data);
}

Global Actions

For app-wide state changes:

// Using cx.action() for global actions
cx.action(NavigationAction::GoBack);

// Handling
if let Some(NavigationAction::GoBack) = action.downcast_ref() {
    self.navigate_back(cx);
}

Event Handling Patterns

Hit Testing

impl Widget for MyWidget {
    fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {
        let area = self.view.area();
        match event.hits(cx, area) {
            Hit::FingerDown(fe) => {
                cx.set_key_focus(area);
                // Start drag, capture, etc.
            }
            Hit::FingerUp(fe) => {
                if fe.is_over && fe.is_primary_hit() {
                    if fe.was_tap() {
                        // Single tap
                    }
                    if fe.was_long_press() {
                        // Long press
                    }
                }
            }
            Hit::FingerMove(fe) => {
                // Drag handling
            }
            Hit::FingerHoverIn(_) => {
                self.animator_play(cx, id!(hover.on));
            }
            Hit::FingerHoverOut(_) => {
                self.animator_play(cx, id!(hover.off));
            }
            Hit::FingerScroll(se) => {
                // Scroll handling
            }
            _ => {}
        }
    }
}

Keyboard Events

fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {
    if let Event::KeyDown(ke) = event {
        match ke.key_code {
            KeyCode::Return if !ke.modifiers.shift => {
                self.submit(cx);
            }
            KeyCode::Escape => {
                self.cancel(cx);
            }
            KeyCode::KeyC if ke.modifiers.control || ke.modifiers.logo => {
                self.copy_to_clipboard(cx);
            }
            _ => {}
        }
    }
}

Signal Events

For handling async updates:

fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {
    if let Event::Signal = event {
        // Poll update queues
        while let Some(update) = PENDING_UPDATES.pop() {
            self.apply_update(cx, update);
        }
    }
}

Action Chaining Pattern

Widget emits action → Parent catches and re-emits with more context:

// In child widget
cx.widget_action(
    self.widget_uid(),
    &scope.path,
    ItemAction::Selected(item_id),
);

// In parent widget's handle_event
if let ItemAction::Selected(item_id) = action.as_widget_action().cast() {
    // Add context and forward to App
    cx.widget_action(
        self.widget_uid(),
        &scope.path,
        ListAction::ItemSelected {
            list_id: self.list_id.clone(),
            item_id,
        },
    );
}

Best Practices

  1. Use DefaultNone derive: All action enums must have a None variant
  2. Use continue after handling: Prevents unnecessary processing
  3. Downcast pattern for async actions: Posted actions are not widget actions
  4. Widget action cast for UI actions: Use as_widget_action().cast()
  5. Always call SignalToUI::set_ui_signal(): After posting actions from async
  6. Centralize in App::handle_actions: Keep action handling in one place
  7. Use descriptive action names: MessageAction::Reply not MessageAction::Action1

Reference Files

  • references/action-patterns.md - Additional action patterns (Robrix)
  • references/event-handling.md - Event handling reference (Robrix)
  • references/moly-action-patterns.md - Moly-specific patterns

- Store-based action forwarding - Timer-based retry pattern - Radio button navigation - External link handling - Platform-conditional actions (#[cfg]) - UiRunner event handling

平台分布

Codex

35.02%
按下载量换算46

Claude

28.92%
按下载量换算38

Cursor

19.3%
按下载量换算25

Gemini CLI

9.26%
按下载量换算12

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills