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