zerolaunch-plugin-api
ZeroLaunch 插件 SDK — 第三方插件开发的唯一依赖。
只需依赖此 crate,即可编写一个完整的 ZeroLaunch 插件,全程不需要 Tauri、Windows API 或启动器源码。
快速开始
Cargo.toml
[]
= { = "../ZeroLaunch-rs/crates/plugin-api" }
= "0.1"
= { = "1", = ["derive"] }
= "1"
[]
= { = "../ZeroLaunch-rs/crates/plugin-api", = ["mock"] }
= { = "1", = ["macros", "rt"] }
插件骨架
插件级元数据(id、名称、版本、描述、作者、触发关键词、动态触发说明、支持系统、优先级、形态、热键、图标)由宿主从 manifest.toml 的 [plugin] / [icon] 段读取,插件代码不声明,Plugin trait 上也不提供元数据方法。插件代码只提供组件级身份:一个 ComponentCore(组件 id、名称、描述、类型、优先级)。
use async_trait;
use Arc;
use ;
use IconRequest;
use ;
单元测试(使用 mock feature)
关键类型
| 类型 | 说明 |
|---|---|
Plugin trait |
插件核心契约:init() + query() + match_query() + execute_action();插件级元数据不在本 trait 上,由宿主侧持有 |
PluginHandle |
平台能力句柄,通过 init() 注入(Option<Arc<PluginHandle>>),提供 get_icon()、shell_open() 等服务 |
Configurable trait |
组件契约:core()(组件身份)+ setting_schema(),配置读写与校验有默认实现 |
ComponentCore |
组件级身份信息:组件 id、名称、描述、类型、优先级 |
PluginMetadata |
插件级元数据:宿主从 manifest.toml 读取后构造,插件代码不声明 |
Query / QueryResponse |
查询输入/输出类型 |
PluginError |
插件层统一错误类型 |
查询匹配(match_query)
行内插件(mode = "inline")的查询接管判定只有一条路径:宿主在路由阶段调用插件的
Plugin::match_query(&self, raw_query: &str, declared_trigger_keywords: &[String]) -> bool。
- 默认实现即框架的关键词判定:触发表里任一项等于输入首词、且其后还有内容时返回
true(判定函数与宿主共用同一份实现)。因此不覆盖该方法的插件行为与旧版关键词路由完全一致, 老插件一行代码都不用改。 - 需要自定义判定的插件覆盖该方法即可(如路径/网址检测器):自己决定何时返回
true, 此时框架的关键词规则不再参与。 - 宿主只做三件事:并发询问 → 按优先级裁决 → 推导查询词。查询词的规则是:赢家若同时满足框架
关键词规则,取「触发词之后的剩余」(模型
keywords,前端可本地镜像);否则取原始输入 (模型custom,前端粘性)。
实现契约
match_query 每次按键都会执行,因此:
- 必须快速、不涉及 IO 或网络;存在性/可达性等需要 IO 的判定放到
query()(async 且可自行超时)。 - 远端插件经
plugin/match_queryRPC 调用(请求携带rawQuery与该插件声明的触发词); 旧 SDK 未实现该方法时宿主按METHOD_NOT_FOUND用同一份关键词判定兜底——已发布插件不受影响; 其他错误/超时按不命中处理并告警。
路由裁决
只有处于启用状态的行内插件参与路由(mode = "panel" 的插件仅经热键/候选项唤醒),
且输入含空格时才会发起判定(关键词规则与检测器的提交规则都要求空格)。
宿主并发询问全部候选插件(内置进程内、远端 RPC),整体受截止时间兜底;命中者按
priority 数值小者优先、同优先级按 plugin_id 字典序选出唯一赢家——因此同名触发词
可以并存,不再被拒绝注册。
协议与兼容
plugin/match_query是新增的可选方法:未实现的插件宿主容METHOD_NOT_FOUND并回退到 本地关键词判定,协议 major 不变(仅新增可选方法不提升 major)。
内置的 path-detect / url-detect(src-tauri/src/builtin_plugin/detector/,共享面板类型
smart-target)即自定义匹配的参考实现。
国际化(i18n)
宿主与前端共享一套翻译系统,插件可提供自己的语言包:
语言包目录
插件目录下提供 i18n/<lang>.json(lang ∈ zh-Hans / zh-Hant / en),文件内是不带前缀的嵌套 JSON,值必须为字符串:
// <plugin-dir>/i18n/zh-Hans.json
宿主在插件加载时读取并校验(单文件 ≤ 64 KiB,仅允许对象与字符串),统一以
plugin.<pluginId>.<key> 命名空间合并进翻译目录;前端经 i18n_get_plugin_translations
拉取后自动翻译 key-or-literal 文本(设置项 schema 标签、结果项动作 label 等)。
生成翻译键
Rust SDK 提供 t_key(key) 帮助函数——插件 id 在 plugin/initialize 握手时
自动注入,无需手动传入:
use t_key;
ResultAction
未提供语言包(或缺少某语言)时,前端回退显示 key 原文——插件始终可用,翻译是增量能力。
插件进程获取当前语言
- 查询/动作场景:
PluginContext携带locale字段(宿主注入,如"zh-Hans"), 可直接按语言生成本地化面板/结果文本。 - 任意时刻主动查询:
HostProxy::get_locale().await(host/i18n.get_localeRPC)。
async
设置项 schema 标签
SettingDefinition 的 label / description / group 支持 key-or-literal:
写成 t_key(key) 形式即可随语言切换;写死字面量则原样显示(兼容旧插件)。
注意:
HostApi与HostApiBuilder是宿主(zl 主程序)内部类型,负责管理插件注册、存储重配置等全局操作,插件作者不需要也不会接触到它们。插件只需通过Plugin::init()获取Arc<PluginHandle>,所有平台能力调用都通过句柄完成。
集成到主程序
- 在
src-tauri/Cargo.toml添加依赖 - 在
lib.rs::init_plugin_system()中注册:session_router.plugin_service.register; cargo run启动,输入echo hello测试
License
MIT