Skip to main content

systemprompt_loader/
extension_registry.rs

1use anyhow::Result;
2use std::collections::HashMap;
3use std::path::{Path, PathBuf};
4
5use systemprompt_models::DiscoveredExtension;
6
7use crate::ExtensionLoader;
8
9#[derive(Debug)]
10pub struct ExtensionRegistry {
11    discovered: HashMap<String, DiscoveredExtension>,
12    bin_path: PathBuf,
13    is_cloud: bool,
14}
15
16impl ExtensionRegistry {
17    pub fn build(project_root: &Path, is_cloud: bool, bin_path: &str) -> Self {
18        let discovered = if is_cloud {
19            HashMap::new()
20        } else {
21            ExtensionLoader::build_binary_map(project_root)
22        };
23
24        Self {
25            discovered,
26            bin_path: PathBuf::from(bin_path),
27            is_cloud,
28        }
29    }
30
31    pub fn get_path(&self, binary_name: &str) -> Result<PathBuf> {
32        if self.is_cloud {
33            let binary_path = self.bin_path.join(binary_name);
34            return binary_path
35                .exists()
36                .then(|| self.bin_path.clone())
37                .ok_or_else(|| {
38                    anyhow::anyhow!(
39                        "Binary '{}' not found at {}",
40                        binary_name,
41                        binary_path.display()
42                    )
43                });
44        }
45
46        self.discovered
47            .get(binary_name)
48            .map(|ext| ext.path.clone())
49            .ok_or_else(|| {
50                anyhow::anyhow!(
51                    "No manifest.yaml found for extension '{}' in extensions/",
52                    binary_name
53                )
54            })
55    }
56
57    pub fn get_extension(&self, binary_name: &str) -> Option<&DiscoveredExtension> {
58        self.discovered.get(binary_name)
59    }
60
61    pub fn has_extension(&self, binary_name: &str) -> bool {
62        self.bin_path.join(binary_name).exists() || self.discovered.contains_key(binary_name)
63    }
64}