//! Embedding Kana Engineering best-practice skills as compiled-in static assets. //! //! Skill markdown files from `apps/infrastructure/skills/` are embedded at //! compile time via `include_dir!` and served through [`EmbeddedSkills`]. //! //! # Flow //! //! `EmbeddedSkills::load()` reads the compile-time directory tree → indexes //! every `SKILL.md` by its parent directory name → exposes lookup / listing. use include_dir::{include_dir, Dir, DirEntry}; use std::collections::HashMap; /// The compile-time-embedded skills directory tree. static SKILLS_DIR: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/skills"); /// Index of embedded best-practice skills, built once at startup. /// /// Each skill is identified by its directory name (e.g. `"clean-code"`) and /// its content is the full text of `SKILL.md` within that directory. pub struct EmbeddedSkills { skills: HashMap<&'static str, &'static str>, } impl EmbeddedSkills { /// Walk the embedded directory tree and build the skill index. /// /// Flow: iterate `Dir::entries()` → find every `SKILL.md` file → /// store `(parent_dir_name, file_contents)` in the map. pub fn load() -> Self { let mut skills: HashMap<&str, &str> = HashMap::new(); fn walk<'a>(dir: &Dir<'a>, skills: &mut HashMap<&'a str, &'a str>) { for entry in dir.entries() { match entry { DirEntry::Dir(sub) => walk(sub, skills), DirEntry::File(file) => { if file.path().file_name().is_some_and(|n| n == "SKILL.md") { if let Some(parent) = file .path() .parent() .and_then(|p| p.file_name()) .and_then(|n| n.to_str()) { if let Some(content) = file.contents_utf8() { skills.entry(parent).or_insert(content); } } } } } } } walk(&SKILLS_DIR, &mut skills); EmbeddedSkills { skills } } /// Return the full `SKILL.md` content for a named skill, if present. pub fn get(&self, name: &str) -> Option<&'static str> { self.skills.get(name).copied() } /// List all available skill names. pub fn list(&self) -> Vec<&'static str> { let mut names: Vec<&str> = self.skills.keys().copied().collect(); names.sort(); names } /// Return an iterator of `(name, trimmed_description)` pairs. /// /// Description is extracted from the YAML frontmatter `description:` field. pub fn summaries(&self) -> Vec<(&'static str, &'static str)> { let mut out: Vec<(&str, &str)> = Vec::new(); for name in self.list() { let content = self.skills.get(name).copied().unwrap_or(""); let desc = Self::extract_description(content).unwrap_or(""); out.push((name, desc)); } out } /// Extract the `description:` field from YAML frontmatter. fn extract_description(content: &str) -> Option<&str> { let lines: Vec<&str> = content.lines().collect(); if lines.first()? != &"---" { return None; } for line in &lines[1..] { if let Some(rest) = line.strip_prefix("description: ") { return Some(rest.trim()); } if line == &"---" { break; } } None } } #[cfg(test)] mod tests { use super::*; #[test] fn embedded_skills_loads_known_skills() { let skills = EmbeddedSkills::load(); let names = skills.list(); assert!( names.contains(&"clean-code"), "expected clean-code skill, got {names:?}" ); assert!( names.contains(&"commit-convention"), "expected commit-convention skill, got {names:?}" ); assert!( names.contains(&"kana-rust-backend-best-practice"), "expected kana-rust-backend-best-practice skill, got {names:?}" ); } #[test] fn each_skill_has_content() { let skills = EmbeddedSkills::load(); for name in skills.list() { let content = skills.get(name); assert!(content.is_some(), "skill '{name}' has no content"); assert!( content.unwrap().len() > 50, "skill '{name}' content suspiciously short" ); } } #[test] fn unknown_skill_returns_none() { let skills = EmbeddedSkills::load(); assert!(skills.get("nonexistent-skill").is_none()); } #[test] fn summaries_include_all_skills() { let skills = EmbeddedSkills::load(); let summaries = skills.summaries(); assert_eq!(summaries.len(), skills.list().len()); for (name, desc) in &summaries { assert!(!desc.is_empty(), "skill '{name}' has empty description"); } } }