Skip to main content

zerolaunch_plugin_protocol/
messages.rs

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