1use hashbrown::HashMap;
7
8use serde::{Deserialize, Serialize};
9
10#[derive(Debug, Clone, Deserialize, Serialize)]
12pub struct PluginAuthor {
13 pub name: String,
14 #[serde(skip_serializing_if = "Option::is_none")]
15 pub email: Option<String>,
16 #[serde(skip_serializing_if = "Option::is_none")]
17 pub url: Option<String>,
18}
19
20#[derive(Debug, Clone, Deserialize, Serialize)]
22pub struct PluginManifest {
23 pub name: String,
25
26 #[serde(skip_serializing_if = "Option::is_none")]
28 pub version: Option<String>,
29
30 #[serde(skip_serializing_if = "Option::is_none")]
32 pub description: Option<String>,
33
34 #[serde(skip_serializing_if = "Option::is_none")]
36 pub author: Option<PluginAuthor>,
37
38 #[serde(skip_serializing_if = "Option::is_none")]
40 pub homepage: Option<String>,
41
42 #[serde(skip_serializing_if = "Option::is_none")]
44 pub repository: Option<String>,
45
46 #[serde(skip_serializing_if = "Option::is_none")]
48 pub license: Option<String>,
49
50 #[serde(skip_serializing_if = "Option::is_none")]
52 pub keywords: Option<Vec<String>>,
53
54 #[serde(skip_serializing_if = "Option::is_none")]
56 pub commands: Option<Vec<String>>,
57
58 #[serde(skip_serializing_if = "Option::is_none")]
60 pub agents: Option<Vec<String>>,
61
62 #[serde(skip_serializing_if = "Option::is_none")]
64 pub skills: Option<Vec<String>>,
65
66 #[serde(skip_serializing_if = "Option::is_none")]
68 pub hooks: Option<HookConfig>,
69
70 #[serde(skip_serializing_if = "Option::is_none")]
72 pub mcp_servers: Option<McpServerConfig>,
73
74 #[serde(skip_serializing_if = "Option::is_none")]
76 pub output_styles: Option<Vec<String>>,
77
78 #[serde(skip_serializing_if = "Option::is_none")]
80 pub lsp_servers: Option<LspServerConfig>,
81}
82
83#[derive(Debug, Clone, Deserialize, Serialize)]
85#[serde(untagged)]
86pub enum HookConfig {
87 Path(String),
89 Inline(HookConfiguration),
91}
92
93#[derive(Debug, Clone, Deserialize, Serialize)]
95#[serde(untagged)]
96pub enum McpServerConfig {
97 Path(String),
99 Inline(HashMap<String, McpServerDefinition>),
101}
102
103#[derive(Debug, Clone, Deserialize, Serialize)]
105#[serde(untagged)]
106pub enum LspServerConfig {
107 Path(String),
109 Inline(HashMap<String, LspServerDefinition>),
111}
112
113#[derive(Debug, Clone, Deserialize, Serialize)]
115pub struct HookConfiguration {
116 pub hooks: HashMap<String, Vec<HookDefinition>>,
117}
118
119#[derive(Debug, Clone, Deserialize, Serialize)]
121pub struct HookDefinition {
122 #[serde(skip_serializing_if = "Option::is_none")]
123 pub matcher: Option<String>,
124 pub hooks: Vec<HookAction>,
125}
126
127#[derive(Debug, Clone, Deserialize, Serialize)]
129#[serde(tag = "type")]
130pub enum HookAction {
131 #[serde(rename = "command")]
132 Command { command: String },
133 #[serde(rename = "prompt")]
134 Prompt { prompt: String },
135 #[serde(rename = "agent")]
136 Agent { agent: String },
137}
138
139#[derive(Debug, Clone, Deserialize, Serialize)]
141pub struct McpServerDefinition {
142 pub command: String,
143 #[serde(skip_serializing_if = "Option::is_none")]
144 pub args: Option<Vec<String>>,
145 #[serde(skip_serializing_if = "Option::is_none")]
146 pub env: Option<HashMap<String, String>>,
147 #[serde(skip_serializing_if = "Option::is_none")]
148 pub cwd: Option<String>,
149}
150
151#[derive(Debug, Clone, Deserialize, Serialize)]
153pub struct LspServerDefinition {
154 pub command: String,
155 #[serde(skip_serializing_if = "Option::is_none")]
156 pub args: Option<Vec<String>>,
157 #[serde(skip_serializing_if = "Option::is_none")]
158 pub env: Option<HashMap<String, String>>,
159 pub extension_to_language: HashMap<String, String>,
160 #[serde(skip_serializing_if = "Option::is_none")]
161 pub transport: Option<String>,
162 #[serde(skip_serializing_if = "Option::is_none")]
163 pub initialization_options: Option<serde_json::Value>,
164 #[serde(skip_serializing_if = "Option::is_none")]
165 pub settings: Option<serde_json::Value>,
166 #[serde(skip_serializing_if = "Option::is_none")]
167 pub workspace_folder: Option<String>,
168 #[serde(skip_serializing_if = "Option::is_none")]
169 pub startup_timeout: Option<u64>,
170 #[serde(skip_serializing_if = "Option::is_none")]
171 pub shutdown_timeout: Option<u64>,
172 #[serde(skip_serializing_if = "Option::is_none")]
173 pub restart_on_crash: Option<bool>,
174 #[serde(skip_serializing_if = "Option::is_none")]
175 pub max_restarts: Option<u32>,
176 #[serde(skip_serializing_if = "Option::is_none")]
177 pub logging_config: Option<LspLoggingConfig>,
178}
179
180#[derive(Debug, Clone, Deserialize, Serialize)]
182pub struct LspLoggingConfig {
183 #[serde(skip_serializing_if = "Option::is_none")]
184 pub args: Option<Vec<String>>,
185 #[serde(skip_serializing_if = "Option::is_none")]
186 pub env: Option<HashMap<String, String>>,
187}