use serde::{Deserialize, Serialize};
#[cfg(feature = "claude")]
use crate::host::Scope;
#[derive(Debug, Clone, Deserialize)]
pub(crate) struct PluginManifest {
#[serde(default)]
pub description: Option<String>,
#[serde(default)]
pub author: Option<AuthorField>,
}
#[derive(Debug, Clone, Deserialize)]
#[serde(untagged)]
pub(crate) enum AuthorField {
Obj(Person),
Str(String),
}
impl AuthorField {
pub fn into_person(self) -> Person {
match self {
AuthorField::Obj(p) => p,
AuthorField::Str(name) => Person { name, email: None, url: None },
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub(crate) struct Person {
pub name: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub email: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub url: Option<String>,
}
#[derive(Debug, Clone, Serialize)]
pub(crate) struct MarketplaceManifest {
pub name: String,
pub description: String,
pub owner: Person,
pub plugins: Vec<MarketplacePlugin>,
}
#[derive(Debug, Clone, Serialize)]
pub(crate) struct MarketplacePlugin {
pub name: String,
pub source: String,
pub description: String,
}
#[cfg(feature = "claude")]
#[derive(Debug, Clone, Deserialize)]
#[serde(rename_all = "camelCase")]
pub(crate) struct PluginEntry {
pub id: String,
#[serde(default)]
pub version: Option<String>,
#[serde(default)]
pub enabled: Option<bool>,
#[serde(default)]
pub install_path: Option<String>,
#[serde(default)]
pub errors: Option<Vec<String>>,
#[serde(default)]
pub scope: Option<String>,
}
#[cfg(feature = "claude")]
impl PluginEntry {
pub fn plugin_name(&self) -> &str {
self.id.split_once('@').map_or(self.id.as_str(), |(n, _)| n)
}
pub fn marketplace(&self) -> Option<&str> {
self.id.split_once('@').map(|(_, m)| m)
}
pub fn matches(&self, name: &str, marketplace: &str) -> bool {
self.plugin_name() == name && self.marketplace() == Some(marketplace)
}
pub fn at_scope(&self, scope: &Scope) -> bool {
match self.scope.as_deref() {
None => true,
Some(s) => s == scope.as_cli(),
}
}
}
#[cfg(feature = "claude")]
#[derive(Debug, Clone, Deserialize)]
pub(crate) struct MarketplaceEntry {
#[serde(default)]
pub name: Option<String>,
#[serde(default)]
pub path: Option<String>,
#[serde(default)]
pub source: Option<String>,
#[serde(default, rename = "ref")]
pub ref_: Option<String>,
}