Skip to main content

zerolaunch_plugin_protocol/
manifest.rs

1use serde::{Deserialize, Serialize};
2use zerolaunch_plugin_api::PluginMode;
3
4/// 顶层插件 manifest,从 `manifest.toml` 反序列化,也可序列化为 JSON 返回给前端。
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct Manifest {
7    /// 插件元信息(ID、名称、版本、作者等)
8    #[serde(rename = "plugin")]
9    pub plugin: PluginSection,
10    /// 运行时配置(启动命令、超时、自动重启策略)
11    #[serde(default, rename = "runtime")]
12    pub runtime: RuntimeSection,
13    /// 组件声明(插件对外提供哪些能力)
14    #[serde(default, rename = "components")]
15    pub components: ComponentsSection,
16    /// 前端 UI 入口(第三方插件可选的 Vue 面板)
17    #[serde(default, rename = "ui")]
18    pub ui: Option<UiSection>,
19    /// 插件图标文件路径
20    #[serde(default, rename = "icon")]
21    pub icon: Option<IconSection>,
22}
23
24/// 插件元信息段。
25#[derive(Debug, Clone, Serialize, Deserialize)]
26pub struct PluginSection {
27    /// 插件唯一标识,反向域名格式,如 `com.example.my-plugin`
28    #[serde(rename = "id")]
29    pub id: String,
30    /// 显示名称
31    #[serde(rename = "name")]
32    pub name: String,
33    /// 语义版本号
34    #[serde(rename = "version")]
35    pub version: String,
36    /// 简短描述
37    #[serde(rename = "description")]
38    pub description: String,
39    /// 作者名
40    #[serde(rename = "author")]
41    pub author: String,
42    /// 插件形态:`inline`(行内,触发词路由)或 `panel`(独立插件,候选项/热键唤醒)
43    #[serde(rename = "mode")]
44    pub mode: PluginMode,
45    /// 全局唤醒快捷键(如 `Ctrl+E`)。可空;仅 `panel` 形态注册热键
46    #[serde(default, rename = "hotkey")]
47    pub hotkey: Option<String>,
48    /// 触发关键词;`panel` 形态下作为默认候选项的匹配关键字
49    #[serde(rename = "triggerKeywords")]
50    pub trigger_keywords: Vec<String>,
51    /// 支持的操作系统标识(如 `["windows"]`)
52    #[serde(rename = "supportedOs")]
53    pub supported_os: Vec<String>,
54    /// 默认搜索候选项优先级
55    #[serde(rename = "priority")]
56    pub priority: u32,
57    /// 项目主页 URL(可选)
58    #[serde(default, rename = "homepage")]
59    pub homepage: Option<String>,
60    /// 开源许可证标识(可选),如 `MIT`、`GPL-3.0`
61    #[serde(default, rename = "license")]
62    pub license: Option<String>,
63}
64
65/// 运行时配置段。
66#[derive(Debug, Clone, Default, Serialize, Deserialize)]
67pub struct RuntimeSection {
68    /// 可执行文件路径(相对于插件目录),如 `./bin/my-plugin`
69    #[serde(rename = "command")]
70    pub command: String,
71    /// 启动参数列表
72    #[serde(default, rename = "args")]
73    pub args: Vec<String>,
74    /// 启动超时秒数,默认 10 秒
75    #[serde(default = "default_startup_timeout", rename = "startupTimeout")]
76    pub startup_timeout: u64,
77    /// 崩溃后是否自动重启,默认 true
78    #[serde(default = "default_true", rename = "autoRestart")]
79    pub auto_restart: bool,
80    /// 最大重启次数,超过后不再自动拉起,默认 3
81    #[serde(default = "default_max_restart", rename = "maxRestart")]
82    pub max_restart: u32,
83}
84
85/// 组件声明段。
86/// 插件在此声明对外提供哪些能力。
87#[derive(Debug, Clone, Default, Serialize, Deserialize)]
88pub struct ComponentsSection {
89    /// 能力列表,可选值见 `REQUIRED_PROVIDES_VALUES`。
90    /// 插件可以声明多个能力(如同时提供 `data_source` 和 `action_executor`),
91    /// 每个能力在构建期对应一个 `RemoteConfigurableAdapter`。
92    #[serde(default = "default_provides", rename = "provides")]
93    pub provides: Vec<String>,
94}
95
96/// 前端 UI 入口段(可选)。
97/// 第三方插件可以注册自定义 Vue 面板,嵌入宿主设置页。
98#[derive(Debug, Clone, Serialize, Deserialize)]
99pub struct UiSection {
100    /// 插件信息面板入口组件路径
101    #[serde(rename = "panelEntry")]
102    pub panel_entry: Option<String>,
103    /// 插件配置面板入口组件路径
104    #[serde(rename = "settingsEntry")]
105    pub settings_entry: Option<String>,
106    /// 搜索结果项自定义渲染组件路径
107    #[serde(rename = "resultItemEntry")]
108    pub result_item_entry: Option<String>,
109}
110
111/// 图标配置段(可选)。
112#[derive(Debug, Clone, Serialize, Deserialize)]
113pub struct IconSection {
114    /// 图标文件路径(相对于插件目录),建议使用 PNG 或 SVG
115    #[serde(rename = "path")]
116    pub path: String,
117}
118
119fn default_startup_timeout() -> u64 {
120    10
121}
122fn default_true() -> bool {
123    true
124}
125fn default_max_restart() -> u32 {
126    3
127}
128fn default_provides() -> Vec<String> {
129    vec![]
130}
131
132/// 必须存在的 manifest 字段。
133pub const REQUIRED_PROVIDES_VALUES: &[&str] = &[
134    "plugin",
135    "data_source",
136    "action_executor",
137    "search_engine",
138    "score_booster",
139    "keyword_optimizer",
140    "keyword_injector",
141];
142
143/// 反向域名格式插件 ID 的正则表达式。
144pub const PLUGIN_ID_RE: &str = r"\A[a-z][a-z0-9]*(\.[a-z][a-z0-9_-]*)+\z";