use serde::{Deserialize, Serialize};
pub const PLUGIN_MANIFEST_RELPATH: &str = ".claude-plugin/plugin.json";
pub const PLUGIN_MANIFEST_DIRS: &[&str] = &[".claude-plugin", "claude-plugin"];
pub const PLUGIN_MANIFEST_FILE: &str = "plugin.json";
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PluginManifest {
pub name: String,
#[serde(default)]
pub description: String,
#[serde(default)]
pub version: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub author: Option<ManifestAuthor>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub hooks: Option<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub keywords: Vec<String>,
#[serde(
default,
rename = "installationPreference",
skip_serializing_if = "Option::is_none"
)]
pub installation_preference: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ManifestAuthor {
pub name: String,
#[serde(default, skip_serializing_if = "String::is_empty")]
pub email: String,
}
pub fn bundle_has_manifest<S: AsRef<str>>(paths: impl IntoIterator<Item = S>) -> bool {
paths
.into_iter()
.any(|path| path.as_ref() == PLUGIN_MANIFEST_RELPATH)
}