Skip to main content

zerolaunch_plugin_protocol/
messages.rs

1use serde::{Deserialize, Serialize};
2use zerolaunch_plugin_api::host::PluginSdkConfig;
3use zerolaunch_plugin_api::services::focus_monitor::FocusEvent;
4use zerolaunch_plugin_api::services::hotkey::types::{HotkeyEvent, HotkeyEventFilter};
5use zerolaunch_plugin_api::services::installation_monitor::types::InstallationEvent;
6use zerolaunch_plugin_api::services::shell::CommandRunMode;
7use zerolaunch_plugin_api::services::IconRequest;
8use zerolaunch_plugin_api::{
9    CandidateCacheSnapshot, CandidateId, ExecutionContext, KeywordInputSource, PluginContext,
10    Query, ScoredCandidate, SearchCandidate, TargetType,
11};
12
13// ─── plugin/initialize ───────────────────────────────────────────
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct InitializeParams {
17    #[serde(rename = "hostVersion")]
18    pub host_version: String,
19    #[serde(rename = "protocolVersion")]
20    pub protocol_version: String,
21    #[serde(rename = "dataDir")]
22    pub data_dir: String,
23    #[serde(rename = "logDir")]
24    pub log_dir: String,
25    #[serde(rename = "pluginId")]
26    pub plugin_id: String,
27    #[serde(rename = "locale")]
28    pub locale: String,
29}
30
31#[derive(Debug, Clone, Serialize, Deserialize)]
32pub struct InitializeResult {
33    #[serde(rename = "protocolVersion")]
34    pub protocol_version: String,
35}
36
37// ─── plugin/get_components ───────────────────────────────────────
38
39#[derive(Debug, Clone, Serialize, Deserialize)]
40pub struct ComponentDescriptor {
41    #[serde(rename = "componentId")]
42    pub component_id: String,
43    #[serde(rename = "componentName")]
44    pub component_name: String,
45    #[serde(rename = "componentDescription", default)]
46    pub component_description: String,
47    /// 组件种类(唯一权威);宿主据此派生 `ComponentType`,插件不得重复声明类型。
48    #[serde(rename = "kind")]
49    pub kind: ComponentKind,
50    #[serde(rename = "priority", default = "default_component_priority")]
51    pub priority: u32,
52}
53
54/// 默认组件优先级,与 `Configurable::priority()` 的默认值(50)一致。
55fn default_component_priority() -> u32 {
56    50
57}
58
59/// 与内置插件完全对等:Plugin / DataSource / ActionExecutor / SearchEngine /
60/// ScoreBooster / KeywordOptimizer / KeywordInjector 均可由第三方插件提供,
61/// 宿主按 kind 注册进对应管道(触发词路由 / 候选采集 / 执行器 / 搜索管道 / 候选管道)。
62#[derive(Debug, Clone, Serialize, Deserialize)]
63#[serde(tag = "type")]
64pub enum ComponentKind {
65    /// 主插件组件(插件级元数据由宿主从清单读取)。
66    #[serde(rename = "plugin")]
67    Plugin,
68    #[serde(rename = "data_source")]
69    DataSource,
70    #[serde(rename = "action_executor")]
71    ActionExecutor {
72        #[serde(rename = "targetTypes")]
73        target_types: Vec<TargetType>,
74    },
75    /// 搜索引擎 —— 参与搜索管道(与内置引擎互斥,仅允许一个启用)。
76    #[serde(rename = "search_engine")]
77    SearchEngine,
78    /// 分数增强器 —— 在引擎打分后追加分数修正(多个可同时启用)。
79    #[serde(rename = "score_booster")]
80    ScoreBooster,
81    /// 关键词优化器 —— 在候选管道中扩展搜索关键词。
82    /// input_source / priority 为声明属性,经 keyword_optimizer_info RPC 拉取。
83    #[serde(rename = "keyword_optimizer")]
84    KeywordOptimizer,
85    /// 关键词注入器 —— 基于候选项完整上下文注入额外关键词。
86    #[serde(rename = "keyword_injector")]
87    KeywordInjector,
88}
89
90// ─── plugin/get_settings_schema ──────────────────────────────────
91
92#[derive(Debug, Clone, Serialize, Deserialize)]
93pub struct GetSettingsSchemaParams {
94    #[serde(rename = "componentId")]
95    pub component_id: String,
96}
97
98// ─── plugin/get_settings ─────────────────────────────────────────
99
100#[derive(Debug, Clone, Serialize, Deserialize)]
101pub struct GetSettingsParams {
102    #[serde(rename = "componentId")]
103    pub component_id: String,
104}
105
106// ─── plugin/apply_settings ───────────────────────────────────────
107
108#[derive(Debug, Clone, Serialize, Deserialize)]
109pub struct ApplySettingsParams {
110    #[serde(rename = "componentId")]
111    pub component_id: String,
112    #[serde(rename = "settings")]
113    pub settings: serde_json::Value,
114}
115
116// ─── plugin/validate_settings ────────────────────────────────────
117
118#[derive(Debug, Clone, Serialize, Deserialize)]
119pub struct ValidateSettingsParams {
120    #[serde(rename = "componentId")]
121    pub component_id: String,
122    #[serde(rename = "settings")]
123    pub settings: serde_json::Value,
124}
125
126#[derive(Debug, Clone, Serialize, Deserialize)]
127pub struct ValidateSettingsResult {
128    #[serde(default)]
129    pub error: Option<String>,
130}
131
132// ─── plugin/config_actions ───────────────────────────────────────
133//
134// 响应为裸数组 `Vec<ConfigActionDef>`(宿主 discover 流程以数组反序列化,
135// 与 get_settings_schema 的裸数组约定一致)。
136
137#[derive(Debug, Clone, Serialize, Deserialize)]
138pub struct ConfigActionsParams {
139    #[serde(rename = "componentId")]
140    pub component_id: String,
141}
142
143// ─── plugin/execute_config_action ────────────────────────────────
144
145#[derive(Debug, Clone, Serialize, Deserialize)]
146pub struct ExecuteConfigActionParams {
147    #[serde(rename = "componentId")]
148    pub component_id: String,
149    #[serde(rename = "action")]
150    pub action: String,
151    #[serde(rename = "params")]
152    pub params: serde_json::Value,
153}
154
155// ─── plugin/query ────────────────────────────────────────────────
156
157#[derive(Debug, Clone, Serialize, Deserialize)]
158pub struct QueryParams {
159    #[serde(rename = "pluginId")]
160    pub plugin_id: String,
161    #[serde(rename = "ctx")]
162    pub ctx: PluginContext,
163    #[serde(rename = "query")]
164    pub query: Query,
165}
166
167// ─── plugin/match_query ──────────────────────────────────────────
168
169/// `plugin/match_query` 请求参数 —— 宿主路由阶段询问插件是否接管当前输入。
170///
171/// 使用范围:宿主(`RemoteComponent` → SDK 分发);对全部启用中的行内插件调用。
172/// 响应为布尔值(true = 接管)。
173#[derive(Debug, Clone, Serialize, Deserialize)]
174pub struct MatchQueryParams {
175    /// 用户在搜索栏中输入的原始字符串(未做小写化等预处理)。
176    #[serde(rename = "rawQuery")]
177    pub raw_query: String,
178    /// 该插件声明的触发词(宿主从清单/代码元数据读取后随请求下发)。
179    /// 用途:让插件的默认 `match_query` 实现能就地完成框架关键词判定,无需在插件代码里重复声明。
180    #[serde(rename = "triggerKeywords")]
181    pub trigger_keywords: Vec<String>,
182}
183
184// ─── plugin/execute_action ───────────────────────────────────────
185
186#[derive(Debug, Clone, Serialize, Deserialize)]
187pub struct ExecuteActionParams {
188    #[serde(rename = "pluginId")]
189    pub plugin_id: String,
190    #[serde(rename = "ctx")]
191    pub ctx: PluginContext,
192    #[serde(rename = "actionId")]
193    pub action_id: String,
194    #[serde(rename = "payload")]
195    pub payload: serde_json::Value,
196}
197
198// ─── plugin/fetch_candidates ─────────────────────────────────────
199
200#[derive(Debug, Clone, Serialize, Deserialize)]
201pub struct FetchCandidatesParams {
202    #[serde(rename = "componentId")]
203    pub component_id: String,
204}
205
206/// Serializable candidate payload returned by remote DataSource plugins.
207/// The host reconstructs CachedCandidateData from these on receipt.
208#[derive(Debug, Clone, Serialize, Deserialize)]
209pub struct FetchCandidatesResult {
210    #[serde(rename = "candidates")]
211    pub candidates: Vec<SearchCandidate>,
212}
213
214// ─── plugin/supported_target_types ───────────────────────────────
215
216#[derive(Debug, Clone, Serialize, Deserialize)]
217pub struct SupportedTargetTypesParams {
218    #[serde(rename = "componentId")]
219    pub component_id: String,
220}
221
222// ─── plugin/supported_actions ────────────────────────────────────
223
224#[derive(Debug, Clone, Serialize, Deserialize)]
225pub struct SupportedActionsParams {
226    #[serde(rename = "componentId")]
227    pub component_id: String,
228    #[serde(rename = "targetType")]
229    pub target_type: TargetType,
230}
231
232// ─── plugin/executor_execute ─────────────────────────────────────
233
234#[derive(Debug, Clone, Serialize, Deserialize)]
235pub struct ExecutorExecuteParams {
236    #[serde(rename = "componentId")]
237    pub component_id: String,
238    /// 完整执行上下文原样透传(与进程内 ActionExecutor 拿到的 ExecutionContext 一致:
239    /// target / display_name / user_args / parameter_snapshot / locale)。
240    #[serde(rename = "executionCtx")]
241    pub execution_ctx: ExecutionContext,
242    #[serde(rename = "actionId")]
243    pub action_id: String,
244}
245
246#[derive(Debug, Clone, Serialize, Deserialize)]
247pub struct ExecutorExecuteResult {
248    #[serde(default)]
249    pub error: Option<String>,
250}
251
252// ─── plugin/calculate_scores ─────────────────────────────────────
253//
254// SearchEngine 组件:对缓存候选计算分数(含全量候选与查询词,宿主按
255// ScoredCandidate 列表重建结果)。
256
257/// plugin/calculate_scores 请求参数。
258#[derive(Debug, Clone, Serialize, Deserialize)]
259pub struct CalculateScoresParams {
260    /// 目标组件 id(SearchEngine 组件)。
261    #[serde(rename = "componentId")]
262    pub component_id: String,
263    /// 全量候选快照(宿主 CachedCandidateData::to_data 导出,id 保真)。
264    #[serde(rename = "candidates")]
265    pub candidates: CandidateCacheSnapshot,
266    /// 用户查询词。
267    #[serde(rename = "query")]
268    pub query: String,
269}
270
271// ─── plugin/booster_boost ────────────────────────────────────────
272//
273// ScoreBooster 组件:对已计算分数做增强,返回增强后的分数列表(索引与传入一致)。
274
275/// plugin/booster_boost 请求参数。
276#[derive(Debug, Clone, Serialize, Deserialize)]
277pub struct BoosterBoostParams {
278    /// 目标组件 id(ScoreBooster 组件)。
279    #[serde(rename = "componentId")]
280    pub component_id: String,
281    /// 全量候选快照(宿主 CachedCandidateData::to_data 导出,id 保真)。
282    #[serde(rename = "candidates")]
283    pub candidates: CandidateCacheSnapshot,
284    /// 引擎计算出的当前分数列表。
285    #[serde(rename = "scored")]
286    pub scored: Vec<ScoredCandidate>,
287    /// 用户查询词。
288    #[serde(rename = "query")]
289    pub query: String,
290}
291
292// ─── plugin/booster_record ───────────────────────────────────────
293//
294// ScoreBooster 组件:记录用户确认(选中候选 → 学习用户习惯)。
295
296/// plugin/booster_record 请求参数。
297#[derive(Debug, Clone, Serialize, Deserialize)]
298pub struct BoosterRecordParams {
299    /// 目标组件 id(ScoreBooster 组件)。
300    #[serde(rename = "componentId")]
301    pub component_id: String,
302    /// 被选中候选项的 id(宿主侧缓存内的原始 id)。
303    #[serde(rename = "candidateId")]
304    pub candidate_id: CandidateId,
305    /// 全量候选快照(宿主 CachedCandidateData::to_data 导出,id 保真)。
306    #[serde(rename = "candidates")]
307    pub candidates: CandidateCacheSnapshot,
308    /// 用户查询词。
309    #[serde(rename = "query")]
310    pub query: String,
311}
312
313// ─── plugin/keyword_optimizer_info ───────────────────────────────
314//
315// KeywordOptimizer 组件的声明属性(input_source / priority),
316// 宿主在发现与设置变更时经本方法拉取并缓存。
317//
318// 响应为裸 `KeywordOptimizerInfo`。
319//
320// 载荷说明:`inputSource`(嵌套对象)取代了 1.x 的 `usesContext: bool`,属载荷级
321// breaking change,已随协议 major 提升到 2.0 —— 1.x 插件在 initialize 握手期被拒绝。
322
323/// KeywordOptimizer 组件的优化属性(经 keyword_optimizer_info RPC 拉取)。
324#[derive(Debug, Clone, Serialize, Deserialize)]
325pub struct KeywordOptimizerInfo {
326    /// 优化器消费的关键词产物来源(分层 DAG-lite 输入层)。
327    #[serde(rename = "inputSource")]
328    pub input_source: KeywordInputSource,
329    /// 链式执行优先级,小者先执行。
330    #[serde(rename = "priority")]
331    pub priority: u32,
332}
333
334impl KeywordOptimizerInfo {
335    /// RPC 未返回时的兜底声明(唯一构造入口)。
336    ///
337    /// 参数:priority - 组件自身优先级。
338    /// 返回:只做幂等精化的默认属性(`Refined` 层)。
339    pub fn fallback(priority: u32) -> Self {
340        Self {
341            input_source: KeywordInputSource::Refined,
342            priority,
343        }
344    }
345}
346
347/// plugin/keyword_optimizer_info 请求参数。
348#[derive(Debug, Clone, Serialize, Deserialize)]
349pub struct KeywordOptimizerInfoParams {
350    /// 目标组件 id(KeywordOptimizer 组件)。
351    #[serde(rename = "componentId")]
352    pub component_id: String,
353}
354
355// ─── plugin/keyword_optimize ─────────────────────────────────────
356//
357// KeywordOptimizer 组件:优化单个关键词(宿主按链序逐级调用)。
358//
359// 响应为裸 `Vec<String>`(优化生成的新关键词)。
360
361/// plugin/keyword_optimize 请求参数。
362#[derive(Debug, Clone, Serialize, Deserialize)]
363pub struct KeywordOptimizeParams {
364    /// 目标组件 id(KeywordOptimizer 组件)。
365    #[serde(rename = "componentId")]
366    pub component_id: String,
367    /// 待优化的关键词。
368    #[serde(rename = "keyword")]
369    pub keyword: String,
370    /// 本次调用携带的来源层(供第三方优化器决策,宿主按声明来源调用)。
371    /// serde default:字段缺失时反序列化回退 Refined,避免 INVALID_PARAMS
372    /// 导致优化器整体跳过。
373    #[serde(rename = "inputSource", default)]
374    pub input_source: KeywordInputSource,
375}
376
377// KeywordInjector 组件:对单个候选注入关键词(与内置逐候选语义一致)。
378//
379// 响应为裸 `Vec<String>`。
380
381/// plugin/keyword_inject 请求参数。
382#[derive(Debug, Clone, Serialize, Deserialize)]
383pub struct KeywordInjectParams {
384    /// 目标组件 id(KeywordInjector 组件)。
385    #[serde(rename = "componentId")]
386    pub component_id: String,
387    /// 待注入的候选项(完整上下文:target、keywords 等)。
388    #[serde(rename = "candidate")]
389    pub candidate: SearchCandidate,
390}
391
392// ─── plugin/init ─────────────────────────────────────────────────
393//
394// 插件初始化钩子:宿主在组件注册完成后调用,通知插件进程完成初始化。
395// 与 plugin/initialize(进程级握手)不同层:init 携带真实查询上下文
396// (trace_id / locale),对应内置插件启动期的 Plugin::init。
397
398/// plugin/init 请求参数。
399#[derive(Debug, Clone, Serialize, Deserialize)]
400pub struct InitParams {
401    /// 目标插件 id(宿主覆盖为 manifest 插件 id)。
402    #[serde(rename = "pluginId")]
403    pub plugin_id: String,
404    /// 宿主构造的初始化上下文(真实 trace_id 与当前语言)。
405    #[serde(rename = "ctx")]
406    pub ctx: PluginContext,
407}
408
409// ─── plugin/shutdown ─────────────────────────────────────────────
410//
411// 插件退出钩子:宿主在关闭子进程(发送 stdin EOF)之前调用,与 plugin/init 成对。
412// 响应为空对象;旧插件未实现该方法时宿主按 METHOD_NOT_FOUND 视为无收尾逻辑。
413
414/// plugin/shutdown 请求参数 —— 宿主关闭插件进程前下发的收尾上下文。
415///
416/// 由宿主在关闭插件进程前构造(应用退出经插件注册表、卸载经 teardown),
417/// 经远端适配器下发;插件 SDK 反序列化后调用
418/// `Plugin::on_shutdown`,不跨 IPC 之外的其他模块使用。
419#[derive(Debug, Clone, Serialize, Deserialize)]
420pub struct ShutdownParams {
421    /// 宿主构造的收尾上下文(trace_id、plugin_id 与最近一次启动时下发的界面语言);
422    /// 插件据此记录日志与生成局部化文案。
423    #[serde(rename = "ctx")]
424    pub ctx: PluginContext,
425}
426
427// ─── plugin/interaction_policy ───────────────────────────────────
428//
429// 响应为裸 `PanelInteraction`(与 get_settings_schema 的裸数组约定一致)。
430// 策略为插件级语义:宿主仅对 Plugin 种类组件调用;SDK 恒返回主插件策略。
431
432/// plugin/interaction_policy 请求参数。
433#[derive(Debug, Clone, Serialize, Deserialize)]
434pub struct InteractionPolicyParams {
435    /// 目标组件 id(仅 Plugin 种类组件会收到该请求)。
436    #[serde(rename = "componentId")]
437    pub component_id: String,
438}
439
440// ─── plugin/get_default_enabled ──────────────────────────────────
441//
442// 响应为裸 `bool`。
443
444/// plugin/get_default_enabled 请求参数。
445#[derive(Debug, Clone, Serialize, Deserialize)]
446pub struct GetDefaultEnabledParams {
447    /// 目标组件 id。
448    #[serde(rename = "componentId")]
449    pub component_id: String,
450}
451
452// ─── host/log ────────────────────────────────────────────────────
453
454#[derive(Debug, Clone, Serialize, Deserialize)]
455pub struct LogParams {
456    #[serde(rename = "level")]
457    pub level: String,
458    #[serde(rename = "message")]
459    pub message: String,
460}
461
462// ─── host/notify ─────────────────────────────────────────────────
463
464#[derive(Debug, Clone, Serialize, Deserialize)]
465pub struct NotifyParams {
466    #[serde(rename = "title")]
467    pub title: String,
468    #[serde(rename = "message")]
469    pub message: String,
470}
471
472// ─── host/shell.open ─────────────────────────────────────────────
473
474#[derive(Debug, Clone, Serialize, Deserialize)]
475pub struct ShellOpenParams {
476    #[serde(rename = "target")]
477    pub target: String,
478}
479
480// ─── host/shell.open_folder ─────────────────────────────────────
481
482#[derive(Debug, Clone, Serialize, Deserialize)]
483pub struct ShellOpenFolderParams {
484    #[serde(rename = "path")]
485    pub path: String,
486}
487
488// ─── host/shell.execute_elevation ────────────────────────────────
489
490#[derive(Debug, Clone, Serialize, Deserialize)]
491pub struct ShellExecuteElevationParams {
492    #[serde(rename = "path")]
493    pub path: String,
494}
495
496// ─── host/shell.execute_command ──────────────────────────────────
497
498/// `host/shell.execute_command` 参数 —— 由 SDK `HostProxy` 代理构造,
499/// 宿主 `host_handler` 反序列化后转发到 `PluginHandle::shell_execute_command`。
500#[derive(Debug, Clone, Serialize, Deserialize)]
501pub struct ShellExecuteCommandParams {
502    /// 要执行的命令字符串(原样交给 cmd 解析,不做参数转义)。
503    #[serde(rename = "cmd")]
504    pub cmd: String,
505    /// 执行方式;载荷缺省(旧插件只发 cmd)时按后台静默执行处理。
506    #[serde(rename = "mode", default)]
507    pub mode: CommandRunMode,
508}
509
510// ─── host/window.activate_by_process ─────────────────────────────
511
512#[derive(Debug, Clone, Serialize, Deserialize)]
513pub struct WindowActivateParams {
514    #[serde(rename = "pid")]
515    pub pid: u32,
516}
517
518// ─── host/icon.get / host/icon.extract / host/icon.refresh ───────
519// 返回值为图标字节的 base64 字符串。字节格式为 WebP(编码失败回退可能为
520// PNG),消费方按字节头嗅探 MIME(RIFF....WEBP → image/webp,否则 image/png)。
521// icon.get 在提取失败时回退默认图标;extract / refresh 失败返回错误。
522
523/// 图标请求参数(icon.get / extract / refresh 共用)。
524#[derive(Debug, Clone, Serialize, Deserialize)]
525pub struct IconRequestParams {
526    /// 图标提取请求(文件路径 / 网址 / 扩展名 / 已编码数据)。
527    #[serde(rename = "request")]
528    pub request: IconRequest,
529}
530
531// ─── host/path.resolve ───────────────────────────────────────────
532
533#[derive(Debug, Clone, Serialize, Deserialize)]
534pub struct PathResolveParams {
535    #[serde(rename = "kind")]
536    pub kind: String,
537}
538
539// ─── host/resource.upload ────────────────────────────────────────
540
541#[derive(Debug, Clone, Serialize, Deserialize)]
542pub struct ResourceUploadParams {
543    #[serde(rename = "resourceId")]
544    pub resource_id: String,
545    #[serde(rename = "filePath")]
546    pub file_path: String,
547    #[serde(rename = "maxSize")]
548    #[serde(default)]
549    pub max_size: Option<usize>,
550}
551
552// ─── host/resource.put ────────────────────────────────────────────
553
554#[derive(Debug, Clone, Serialize, Deserialize)]
555pub struct ResourcePutParams {
556    #[serde(rename = "resourceId")]
557    pub resource_id: String,
558    #[serde(rename = "bytesB64")]
559    pub bytes_b64: String,
560}
561
562// ─── host/resource.get ───────────────────────────────────────────
563
564#[derive(Debug, Clone, Serialize, Deserialize)]
565pub struct ResourceGetParams {
566    #[serde(rename = "resourceId")]
567    pub resource_id: String,
568}
569
570// ─── host/resource.delete ────────────────────────────────────────
571
572#[derive(Debug, Clone, Serialize, Deserialize)]
573pub struct ResourceDeleteParams {
574    #[serde(rename = "resourceId")]
575    pub resource_id: String,
576}
577
578// ─── host/resource.list ──────────────────────────────────────────
579
580#[derive(Debug, Clone, Serialize, Deserialize)]
581pub struct ResourceListParams {}
582
583// ─── host/parameter.resolve ──────────────────────────────────────
584
585#[derive(Debug, Clone, Serialize, Deserialize)]
586pub struct ParameterResolveParams {
587    #[serde(rename = "userArgs")]
588    pub user_args: Vec<String>,
589    /// 参数模板字符串(如 "https://google.com/search?q={query}")。
590    /// 命名注意:此字段是模板,不是插件 ID。字段曾名为 pluginId 但造成混淆,已更正。
591    #[serde(rename = "template")]
592    pub template: String,
593}
594
595// ─── host/sdk_config.update ──────────────────────────────────────
596
597/// 更新插件 SDK 配置的参数。
598///
599/// 由插件的 `host/sdk_config.update` 调用携带;宿主将该配置应用到
600/// 该插件的 PluginHandle(影响后续图标缓存等级等行为),立即生效。
601#[derive(Debug, Clone, Serialize, Deserialize)]
602pub struct SdkConfigUpdateParams {
603    /// 新的插件 SDK 配置;未设置字段表示沿用宿主当前值。
604    #[serde(rename = "config")]
605    pub config: PluginSdkConfig,
606}
607
608// ─── host/icon.override_cache ────────────────────────────────────
609
610/// 覆盖图标缓存条目为自定义图标文件的参数。
611#[derive(Debug, Clone, Serialize, Deserialize)]
612pub struct IconOverrideCacheParams {
613    /// 需要覆盖缓存图标的原始图标请求。
614    #[serde(rename = "request")]
615    pub request: IconRequest,
616    /// 用户选择的自定义图标文件路径。
617    #[serde(rename = "customIconPath")]
618    pub custom_icon_path: String,
619}
620
621// ─── host/window.activate_by_process ─────────────────────────────
622
623/// 按进程名激活窗口的参数。
624#[derive(Debug, Clone, Serialize, Deserialize)]
625pub struct WindowActivateByProcessParams {
626    /// 进程名(如 "chrome.exe")。
627    #[serde(rename = "processName")]
628    pub process_name: String,
629}
630
631// ─── host/window.activate_by_title ───────────────────────────────
632
633/// 按窗口标题片段激活窗口的参数。
634#[derive(Debug, Clone, Serialize, Deserialize)]
635pub struct WindowActivateByTitleParams {
636    /// 窗口标题片段。
637    #[serde(rename = "title")]
638    pub title: String,
639}
640
641// ─── host/clipboard.set_text ─────────────────────────────────────
642
643/// 写入系统剪贴板的参数。
644#[derive(Debug, Clone, Serialize, Deserialize)]
645pub struct ClipboardSetTextParams {
646    /// 待写入剪贴板的文本。
647    #[serde(rename = "text")]
648    pub text: String,
649}
650
651// ─── host/app.launch ─────────────────────────────────────────────
652// 返回值为启动进程的 PID。
653
654/// 启动已安装应用的参数。
655#[derive(Debug, Clone, Serialize, Deserialize)]
656pub struct AppLaunchParams {
657    /// 应用 ID(AppInfo.id / AppsFolder 条目 ID)。
658    #[serde(rename = "appId")]
659    pub app_id: String,
660    /// 启动参数列表;None 表示不传参数。
661    #[serde(rename = "args")]
662    #[serde(default)]
663    pub args: Option<Vec<String>>,
664}
665
666// ─── host/app.icon_path ──────────────────────────────────────────
667
668/// 查询内置应用图标资源路径的参数。
669#[derive(Debug, Clone, Serialize, Deserialize)]
670pub struct AppIconPathParams {
671    /// 资源名称(如 "tray_icon"、"terminal")。
672    #[serde(rename = "name")]
673    pub name: String,
674}
675
676// ─── host/path.resolve_lnk ───────────────────────────────────────
677
678/// 解析 .lnk 快捷方式目标的参数。
679#[derive(Debug, Clone, Serialize, Deserialize)]
680pub struct PathResolveLnkParams {
681    /// .lnk 文件路径。
682    #[serde(rename = "lnkPath")]
683    pub lnk_path: String,
684}
685
686// ─── host/path.localized_names ───────────────────────────────────
687
688/// 解析目录本地化文件名的参数。
689#[derive(Debug, Clone, Serialize, Deserialize)]
690pub struct PathLocalizedNamesParams {
691    /// 目标目录路径。
692    #[serde(rename = "dirPath")]
693    pub dir_path: String,
694}
695
696// ─── host/parameter.count_user / host/parameter.has_system ───────
697
698/// 参数模板查询参数(统计用户参数 / 判断系统参数共用)。
699#[derive(Debug, Clone, Serialize, Deserialize)]
700pub struct ParameterTemplateParams {
701    /// 参数模板字符串(如 "https://example.com?q={query}")。
702    #[serde(rename = "template")]
703    pub template: String,
704}
705
706// ─── host/cache.put ──────────────────────────────────────────────
707
708/// 写入插件本地缓存的参数。
709#[derive(Debug, Clone, Serialize, Deserialize)]
710pub struct CachePutParams {
711    /// 缓存域(插件内逻辑分组,需为非空且不含路径分隔符/..)。
712    #[serde(rename = "domain")]
713    pub domain: String,
714    /// 缓存键(域内唯一,允许子路径但不得逃逸域目录)。
715    #[serde(rename = "key")]
716    pub key: String,
717    /// 缓存字节数据的 base64 编码。
718    #[serde(rename = "bytesB64")]
719    pub bytes_b64: String,
720}
721
722// ─── host/cache.get ──────────────────────────────────────────────
723
724/// 读取插件本地缓存的参数。
725#[derive(Debug, Clone, Serialize, Deserialize)]
726pub struct CacheGetParams {
727    /// 缓存域。
728    #[serde(rename = "domain")]
729    pub domain: String,
730    /// 缓存键。
731    #[serde(rename = "key")]
732    pub key: String,
733}
734
735// ─── host/cache.delete ───────────────────────────────────────────
736
737/// 删除插件本地缓存条目的参数。
738#[derive(Debug, Clone, Serialize, Deserialize)]
739pub struct CacheDeleteParams {
740    /// 缓存域。
741    #[serde(rename = "domain")]
742    pub domain: String,
743    /// 缓存键。
744    #[serde(rename = "key")]
745    pub key: String,
746}
747
748// ─── host/cache.cleanup ──────────────────────────────────────────
749
750/// 按条目数上限清理插件本地缓存域的参数。
751#[derive(Debug, Clone, Serialize, Deserialize)]
752pub struct CacheCleanupParams {
753    /// 缓存域。
754    #[serde(rename = "domain")]
755    pub domain: String,
756    /// 保留的最大条目数,超出部分按修改时间从旧到新删除。
757    #[serde(rename = "maxEntries")]
758    pub max_entries: usize,
759}
760
761// ─── host/timer.set_timeout ──────────────────────────────────────
762// 返回值为宿主分配的定时器 ID(u64),到期由宿主推送 plugin/timer.fired。
763
764/// 创建一次性定时器的参数。
765#[derive(Debug, Clone, Serialize, Deserialize)]
766pub struct TimerSetTimeoutParams {
767    /// 延迟毫秒数。
768    #[serde(rename = "delayMs")]
769    pub delay_ms: u64,
770}
771
772// ─── host/timer.set_interval ─────────────────────────────────────
773
774/// 创建重复定时器的参数。
775#[derive(Debug, Clone, Serialize, Deserialize)]
776pub struct TimerSetIntervalParams {
777    /// 触发间隔毫秒数。
778    #[serde(rename = "intervalMs")]
779    pub interval_ms: u64,
780}
781
782// ─── host/timer.cancel ───────────────────────────────────────────
783
784/// 取消指定定时器的参数。
785#[derive(Debug, Clone, Serialize, Deserialize)]
786pub struct TimerCancelParams {
787    /// 定时器 ID(host/timer.set_* 的返回值)。
788    #[serde(rename = "id")]
789    pub id: u64,
790}
791
792// ─── host/timer.cancel_all ───────────────────────────────────────
793
794/// 取消本插件全部定时器的参数(无字段)。
795#[derive(Debug, Clone, Serialize, Deserialize)]
796pub struct TimerCancelAllParams {}
797
798// ─── plugin/timer.fired ──────────────────────────────────────────
799
800/// 宿主推送的定时器到期通知载荷。
801#[derive(Debug, Clone, Serialize, Deserialize)]
802pub struct TimerFiredParams {
803    /// 到期的定时器 ID。
804    #[serde(rename = "id")]
805    pub id: u64,
806}
807
808// ─── host/hotkey.subscribe ───────────────────────────────────────
809
810/// 订阅按键事件的参数。
811#[derive(Debug, Clone, Serialize, Deserialize)]
812pub struct HotkeySubscribeParams {
813    /// 插件内订阅 ID(宿主按 "{plugin_id}:{id}" 前缀化,退订时用同一 ID)。
814    #[serde(rename = "id")]
815    pub id: String,
816    /// 关注的事件过滤器(全部 / 指定快捷键 / 双击 Ctrl)。
817    #[serde(rename = "filter")]
818    pub filter: HotkeyEventFilter,
819}
820
821// ─── host/hotkey.unsubscribe ─────────────────────────────────────
822
823/// 退订按键事件的参数。
824#[derive(Debug, Clone, Serialize, Deserialize)]
825pub struct HotkeyUnsubscribeParams {
826    /// 订阅时使用的插件内 ID。
827    #[serde(rename = "id")]
828    pub id: String,
829}
830
831// ─── host/installation.subscribe / unsubscribe ───────────────────
832
833/// 订阅安装监控事件的参数。
834#[derive(Debug, Clone, Serialize, Deserialize)]
835pub struct InstallationSubscribeParams {
836    /// 插件内订阅 ID。
837    #[serde(rename = "id")]
838    pub id: String,
839}
840
841/// 退订安装监控事件的参数。
842#[derive(Debug, Clone, Serialize, Deserialize)]
843pub struct InstallationUnsubscribeParams {
844    /// 订阅时使用的插件内 ID。
845    #[serde(rename = "id")]
846    pub id: String,
847}
848
849// ─── host/focus.subscribe / unsubscribe ──────────────────────────
850
851/// 订阅窗口焦点事件的参数。
852#[derive(Debug, Clone, Serialize, Deserialize)]
853pub struct FocusSubscribeParams {
854    /// 插件内订阅 ID。
855    #[serde(rename = "id")]
856    pub id: String,
857}
858
859/// 退订窗口焦点事件的参数。
860#[derive(Debug, Clone, Serialize, Deserialize)]
861pub struct FocusUnsubscribeParams {
862    /// 订阅时使用的插件内 ID。
863    #[serde(rename = "id")]
864    pub id: String,
865}
866
867// ─── plugin/hotkey.event / plugin/installation.event / plugin/focus.event ──
868// 载荷携带订阅时的插件内 ID,使插件可把事件路由到对应订阅的处理函数。
869
870/// 宿主推送的按键事件载荷。
871#[derive(Debug, Clone, Serialize, Deserialize)]
872pub struct HotkeyEventParams {
873    /// 订阅时使用的插件内 ID。
874    #[serde(rename = "id")]
875    pub id: String,
876    /// 事件内容(全局快捷键 / 双击 Ctrl)。
877    #[serde(rename = "event")]
878    pub event: HotkeyEvent,
879}
880
881/// 宿主推送的安装监控事件载荷。
882#[derive(Debug, Clone, Serialize, Deserialize)]
883pub struct InstallationEventParams {
884    /// 订阅时使用的插件内 ID。
885    #[serde(rename = "id")]
886    pub id: String,
887    /// 事件内容(变化类型 + 变化路径)。
888    #[serde(rename = "event")]
889    pub event: InstallationEvent,
890}
891
892/// 宿主推送的窗口焦点事件载荷。
893#[derive(Debug, Clone, Serialize, Deserialize)]
894pub struct FocusEventParams {
895    /// 订阅时使用的插件内 ID。
896    #[serde(rename = "id")]
897    pub id: String,
898    /// 事件内容(当前仅失去焦点)。
899    #[serde(rename = "event")]
900    pub event: FocusEvent,
901}