Skip to main content

vtcode_skills/
injection.rs

1use crate::model::SkillLoadOutcome;
2use tokio::fs;
3
4use super::instructions::SkillInstructions;
5
6#[derive(Debug, Default)]
7pub struct SkillInjections {
8    items: Vec<SkillInstructions>,
9    warnings: Vec<String>,
10}
11
12/// Builds injections for the specified skills.
13///
14/// `skill_names` is a list of skill names that should be loaded (e.g. detected from user input).
15pub async fn build_skill_injections(skill_names: &[String], skills: Option<&SkillLoadOutcome>) -> SkillInjections {
16    if skill_names.is_empty() {
17        return SkillInjections::default();
18    }
19
20    let Some(outcome) = skills else {
21        return SkillInjections::default();
22    };
23
24    let mut result = SkillInjections {
25        items: Vec::with_capacity(skill_names.len()),
26        warnings: Vec::new(),
27    };
28
29    for name in skill_names {
30        if let Some(skill) = outcome.skills.iter().find(|s| s.name == *name) {
31            match fs::read_to_string(&skill.path).await {
32                Ok(contents) => {
33                    result.items.push(SkillInstructions {
34                        name: skill.name.clone(),
35                        path: skill.path.clone(),
36                        contents,
37                    });
38                }
39                Err(err) => {
40                    let message = format!("Failed to load skill {} at {}: {err:#}", skill.name, skill.path.display());
41                    result.warnings.push(message);
42                }
43            }
44        }
45    }
46
47    result
48}