Skip to main content

synaps_cli/skills/
config.rs

1//! Apply disable lists to discovered skills.
2
3use crate::skills::LoadedSkill;
4
5pub fn filter_disabled(
6    skills: Vec<LoadedSkill>,
7    disabled_plugins: &[String],
8    disabled_skills: &[String],
9) -> Vec<LoadedSkill> {
10    skills.into_iter().filter(|s| {
11        if let Some(ref p) = s.plugin {
12            if disabled_plugins.iter().any(|d| d == p) {
13                tracing::debug!("skill '{}' disabled via disabled_plugins='{}'", s.name, p);
14                return false;
15            }
16        }
17        if disabled_skills.iter().any(|d| d == &s.name) {
18            tracing::debug!("skill '{}' disabled via disabled_skills (bare)", s.name);
19            return false;
20        }
21        if let Some(ref p) = s.plugin {
22            let qualified = format!("{}:{}", p, s.name);
23            if disabled_skills.iter().any(|d| d == &qualified) {
24                tracing::debug!("skill '{}' disabled via disabled_skills (qualified)", qualified);
25                return false;
26            }
27        }
28        true
29    }).collect()
30}
31
32#[cfg(test)]
33mod tests {
34    use super::*;
35    use std::path::PathBuf;
36
37    fn mk_skill(name: &str, plugin: Option<&str>) -> LoadedSkill {
38        LoadedSkill {
39            name: name.to_string(),
40            description: String::new(),
41            body: String::new(),
42            plugin: plugin.map(str::to_string),
43            base_dir: PathBuf::from("/"),
44            source_path: PathBuf::from("/SKILL.md"),
45        }
46    }
47
48    #[test]
49    fn disable_by_plugin() {
50        let s = vec![mk_skill("a", Some("p1")), mk_skill("b", Some("p2"))];
51        let out = filter_disabled(s, &["p1".to_string()], &[]);
52        assert_eq!(out.len(), 1);
53        assert_eq!(out[0].name, "b");
54    }
55
56    #[test]
57    fn disable_by_bare_name() {
58        let s = vec![mk_skill("a", Some("p1")), mk_skill("a", Some("p2")), mk_skill("b", None)];
59        let out = filter_disabled(s, &[], &["a".to_string()]);
60        assert_eq!(out.len(), 1);
61        assert_eq!(out[0].name, "b");
62    }
63
64    #[test]
65    fn disable_by_qualified_name() {
66        let s = vec![mk_skill("a", Some("p1")), mk_skill("a", Some("p2"))];
67        let out = filter_disabled(s, &[], &["p1:a".to_string()]);
68        assert_eq!(out.len(), 1);
69        assert_eq!(out[0].plugin.as_deref(), Some("p2"));
70    }
71
72    #[test]
73    fn empty_filters_pass_through() {
74        let s = vec![mk_skill("a", None), mk_skill("b", Some("p"))];
75        let out = filter_disabled(s, &[], &[]);
76        assert_eq!(out.len(), 2);
77    }
78}