systemprompt_models/extension/
mod.rs

1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3use std::path::PathBuf;
4
5#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
6#[serde(rename_all = "lowercase")]
7pub enum ExtensionType {
8    Mcp,
9    Blog,
10    Cli,
11    #[default]
12    Other,
13}
14
15#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
16#[serde(rename_all = "lowercase")]
17pub enum BuildType {
18    #[default]
19    Workspace,
20    Submodule,
21}
22
23#[derive(Debug, Clone, Serialize, Deserialize)]
24pub struct ManifestRole {
25    pub display_name: String,
26    pub description: String,
27    #[serde(default)]
28    pub permissions: Vec<String>,
29}
30
31#[derive(Debug, Clone, Serialize, Deserialize)]
32pub struct CliCommand {
33    pub name: String,
34    #[serde(default)]
35    pub description: String,
36}
37
38#[derive(Debug, Clone, Serialize, Deserialize)]
39pub struct ExtensionManifest {
40    pub extension: Extension,
41}
42
43#[derive(Debug, Clone, Serialize, Deserialize)]
44pub struct Extension {
45    #[serde(rename = "type")]
46    pub type_: ExtensionType,
47
48    pub name: String,
49
50    #[serde(default, skip_serializing_if = "Option::is_none")]
51    pub binary: Option<String>,
52
53    #[serde(default)]
54    pub description: String,
55
56    #[serde(default, skip_serializing_if = "Option::is_none")]
57    pub port: Option<u16>,
58
59    #[serde(default)]
60    pub build_type: BuildType,
61
62    #[serde(default = "default_true")]
63    pub enabled: bool,
64
65    #[serde(default, skip_serializing_if = "HashMap::is_empty")]
66    pub roles: HashMap<String, ManifestRole>,
67
68    #[serde(default, skip_serializing_if = "Vec::is_empty")]
69    pub commands: Vec<CliCommand>,
70}
71
72const fn default_true() -> bool {
73    true
74}
75
76#[derive(Debug, Clone)]
77pub struct DiscoveredExtension {
78    pub manifest: ExtensionManifest,
79    pub path: PathBuf,
80    pub manifest_path: PathBuf,
81}
82
83impl DiscoveredExtension {
84    pub const fn new(manifest: ExtensionManifest, path: PathBuf, manifest_path: PathBuf) -> Self {
85        Self {
86            manifest,
87            path,
88            manifest_path,
89        }
90    }
91
92    pub const fn extension_type(&self) -> ExtensionType {
93        self.manifest.extension.type_
94    }
95
96    pub fn binary_name(&self) -> Option<&str> {
97        self.manifest.extension.binary.as_deref()
98    }
99
100    pub const fn is_enabled(&self) -> bool {
101        self.manifest.extension.enabled
102    }
103
104    pub fn is_mcp(&self) -> bool {
105        self.manifest.extension.type_ == ExtensionType::Mcp
106    }
107
108    pub fn is_cli(&self) -> bool {
109        self.manifest.extension.type_ == ExtensionType::Cli
110    }
111
112    pub fn commands(&self) -> &[CliCommand] {
113        &self.manifest.extension.commands
114    }
115
116    pub const fn build_type(&self) -> BuildType {
117        self.manifest.extension.build_type
118    }
119}