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