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