systemprompt_models/bridge/
plugin_bundle.rs1use serde::{Deserialize, Serialize};
16
17pub const PLUGIN_MANIFEST_RELPATH: &str = ".claude-plugin/plugin.json";
18
19pub const PLUGIN_MANIFEST_DIRS: &[&str] = &[".claude-plugin", "claude-plugin"];
20
21pub const PLUGIN_MANIFEST_FILE: &str = "plugin.json";
22
23#[derive(Debug, Clone, Serialize, Deserialize)]
24pub struct PluginManifest {
25 pub name: String,
26 #[serde(default)]
27 pub description: String,
28 #[serde(default)]
29 pub version: String,
30 #[serde(default, skip_serializing_if = "Option::is_none")]
31 pub author: Option<ManifestAuthor>,
32 #[serde(default, skip_serializing_if = "Option::is_none")]
33 pub hooks: Option<String>,
34 #[serde(default, skip_serializing_if = "Vec::is_empty")]
35 pub keywords: Vec<String>,
36 #[serde(
37 default,
38 rename = "installationPreference",
39 skip_serializing_if = "Option::is_none"
40 )]
41 pub installation_preference: Option<String>,
42}
43
44#[derive(Debug, Clone, Serialize, Deserialize)]
45pub struct ManifestAuthor {
46 pub name: String,
47 #[serde(default, skip_serializing_if = "String::is_empty")]
48 pub email: String,
49}
50
51pub fn bundle_has_manifest<S: AsRef<str>>(paths: impl IntoIterator<Item = S>) -> bool {
52 paths
53 .into_iter()
54 .any(|path| path.as_ref() == PLUGIN_MANIFEST_RELPATH)
55}