1use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6use std::path::PathBuf;
7
8#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
10#[serde(rename_all = "snake_case")]
11pub enum PluginSource {
12 Git { url: String, branch: String },
14 Local { path: PathBuf },
16 Marketplace { marketplace: String },
18}
19
20#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
22#[serde(rename_all = "snake_case")]
23pub enum PluginStatus {
24 Installed,
26 Disabled,
28 Error(String),
30}
31
32#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
34#[serde(rename_all = "snake_case")]
35pub enum PluginScope {
36 User,
38 Project,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
44pub struct ToolDefinition {
45 pub name: String,
47 #[serde(default)]
49 pub description: String,
50 #[serde(default)]
52 pub parameters: serde_json::Value,
53}
54
55#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
57pub struct PromptTemplate {
58 pub name: String,
60 #[serde(default)]
62 pub description: String,
63 #[serde(default)]
65 pub template: String,
66}
67
68#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
70pub struct PluginManifest {
71 pub name: String,
73 pub version: String,
75 #[serde(default)]
77 pub description: String,
78 #[serde(default)]
80 pub author: Option<String>,
81 #[serde(default)]
83 pub tools: Vec<ToolDefinition>,
84 #[serde(default)]
86 pub prompts: Vec<PromptTemplate>,
87 #[serde(default)]
89 pub dependencies: Vec<String>,
90 #[serde(default)]
92 pub skills: Vec<String>,
93 #[serde(default)]
95 pub repository: Option<String>,
96 #[serde(default)]
98 pub license: Option<String>,
99}
100
101#[derive(Debug, Clone, Serialize, Deserialize)]
103pub struct PluginConfig {
104 pub name: String,
106 pub version: String,
108 pub source: PluginSource,
110 pub status: PluginStatus,
112 pub scope: PluginScope,
114 pub enabled: bool,
116 pub path: PathBuf,
118 pub installed_at: DateTime<Utc>,
120 #[serde(default)]
122 pub marketplace: Option<String>,
123}
124
125#[derive(Debug, Clone, Serialize, Deserialize)]
127pub struct MarketplaceInfo {
128 pub name: String,
130 pub url: String,
132 #[serde(default = "default_branch")]
134 pub branch: String,
135 pub added_at: DateTime<Utc>,
137 #[serde(default)]
139 pub last_updated: Option<DateTime<Utc>>,
140}
141
142fn default_branch() -> String {
143 "main".to_string()
144}
145
146#[derive(Debug, Clone, Serialize, Deserialize, Default)]
148pub struct KnownMarketplaces {
149 #[serde(default)]
151 pub marketplaces: HashMap<String, MarketplaceInfo>,
152}
153
154#[derive(Debug, Clone, Serialize, Deserialize, Default)]
156pub struct InstalledPlugins {
157 #[serde(default)]
159 pub plugins: HashMap<String, PluginConfig>,
160}
161
162impl InstalledPlugins {
163 pub fn make_key(marketplace: &str, plugin: &str) -> String {
165 format!("{}:{}", marketplace, plugin)
166 }
167
168 pub fn add(&mut self, plugin: PluginConfig) {
170 let key = Self::make_key(
171 plugin.marketplace.as_deref().unwrap_or("local"),
172 &plugin.name,
173 );
174 self.plugins.insert(key, plugin);
175 }
176
177 pub fn remove(&mut self, marketplace: &str, plugin: &str) -> Option<PluginConfig> {
179 let key = Self::make_key(marketplace, plugin);
180 self.plugins.remove(&key)
181 }
182
183 pub fn get(&self, marketplace: &str, plugin: &str) -> Option<&PluginConfig> {
185 let key = Self::make_key(marketplace, plugin);
186 self.plugins.get(&key)
187 }
188
189 pub fn get_mut(&mut self, marketplace: &str, plugin: &str) -> Option<&mut PluginConfig> {
191 let key = Self::make_key(marketplace, plugin);
192 self.plugins.get_mut(&key)
193 }
194}
195
196#[derive(Debug, Clone, Serialize, Deserialize, Default)]
198pub struct MarketplaceCatalog {
199 #[serde(default)]
201 pub plugins: Vec<String>,
202 #[serde(default)]
204 pub auto_discovered: bool,
205}
206
207#[derive(Debug, Clone, Serialize, Deserialize)]
209pub struct PluginMetadata {
210 pub name: String,
212 pub version: String,
214 #[serde(default)]
216 pub description: String,
217 #[serde(default)]
219 pub author: Option<String>,
220 #[serde(default)]
222 pub skills: Vec<String>,
223 #[serde(default)]
225 pub repository: Option<String>,
226 #[serde(default)]
228 pub license: Option<String>,
229}