use hashbrown::HashMap;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct PluginAuthor {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub email: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub url: Option<String>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct PluginManifest {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub version: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub author: Option<PluginAuthor>,
#[serde(skip_serializing_if = "Option::is_none")]
pub homepage: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub repository: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub license: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub keywords: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub commands: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub agents: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub skills: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub hooks: Option<HookConfig>,
#[serde(skip_serializing_if = "Option::is_none")]
pub mcp_servers: Option<McpServerConfig>,
#[serde(skip_serializing_if = "Option::is_none")]
pub output_styles: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub lsp_servers: Option<LspServerConfig>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum HookConfig {
Path(String),
Inline(HookConfiguration),
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum McpServerConfig {
Path(String),
Inline(HashMap<String, McpServerDefinition>),
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(untagged)]
pub enum LspServerConfig {
Path(String),
Inline(HashMap<String, LspServerDefinition>),
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct HookConfiguration {
pub hooks: HashMap<String, Vec<HookDefinition>>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct HookDefinition {
#[serde(skip_serializing_if = "Option::is_none")]
pub matcher: Option<String>,
pub hooks: Vec<HookAction>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(tag = "type")]
pub enum HookAction {
#[serde(rename = "command")]
Command { command: String },
#[serde(rename = "prompt")]
Prompt { prompt: String },
#[serde(rename = "agent")]
Agent { agent: String },
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct McpServerDefinition {
pub command: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub args: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub env: Option<HashMap<String, String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub cwd: Option<String>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct LspServerDefinition {
pub command: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub args: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub env: Option<HashMap<String, String>>,
pub extension_to_language: HashMap<String, String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub transport: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub initialization_options: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub settings: Option<serde_json::Value>,
#[serde(skip_serializing_if = "Option::is_none")]
pub workspace_folder: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub startup_timeout: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub shutdown_timeout: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub restart_on_crash: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_restarts: Option<u32>,
#[serde(skip_serializing_if = "Option::is_none")]
pub logging_config: Option<LspLoggingConfig>,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct LspLoggingConfig {
#[serde(skip_serializing_if = "Option::is_none")]
pub args: Option<Vec<String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub env: Option<HashMap<String, String>>,
}