systemprompt_models/extension/
mod.rs1use 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 #[serde(default)]
72 pub supports_json_output: bool,
73}
74
75const fn default_true() -> bool {
76 true
77}
78
79#[derive(Debug, Clone)]
80pub struct DiscoveredExtension {
81 pub manifest: ExtensionManifest,
82 pub path: PathBuf,
83 pub manifest_path: PathBuf,
84}
85
86impl DiscoveredExtension {
87 pub const fn new(manifest: ExtensionManifest, path: PathBuf, manifest_path: PathBuf) -> Self {
88 Self {
89 manifest,
90 path,
91 manifest_path,
92 }
93 }
94
95 pub const fn extension_type(&self) -> ExtensionType {
96 self.manifest.extension.type_
97 }
98
99 pub fn binary_name(&self) -> Option<&str> {
100 self.manifest.extension.binary.as_deref()
101 }
102
103 pub const fn is_enabled(&self) -> bool {
104 self.manifest.extension.enabled
105 }
106
107 pub fn is_mcp(&self) -> bool {
108 self.manifest.extension.type_ == ExtensionType::Mcp
109 }
110
111 pub fn is_cli(&self) -> bool {
112 self.manifest.extension.type_ == ExtensionType::Cli
113 }
114
115 pub fn commands(&self) -> &[CliCommand] {
116 &self.manifest.extension.commands
117 }
118
119 pub const fn build_type(&self) -> BuildType {
120 self.manifest.extension.build_type
121 }
122
123 pub const fn supports_json_output(&self) -> bool {
124 self.manifest.extension.supports_json_output
125 }
126}