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