use std::path::Path;
use crate::errors::Result;
use crate::parser::{find_skill_md, read_properties};
fn html_escape(s: &str) -> String {
s.replace('&', "&")
.replace('<', "<")
.replace('>', ">")
.replace('"', """)
.replace('\'', "'")
}
pub fn to_prompt(skill_dirs: &[impl AsRef<Path>]) -> Result<String> {
if skill_dirs.is_empty() {
return Ok("<available_skills>\n</available_skills>".to_string());
}
let mut lines = vec!["<available_skills>".to_string()];
for skill_dir in skill_dirs {
let dir = std::fs::canonicalize(skill_dir.as_ref())
.unwrap_or_else(|_| skill_dir.as_ref().to_path_buf());
let props = read_properties(&dir, false)?;
lines.push("<skill>".to_string());
lines.push("<name>".to_string());
lines.push(html_escape(&props.name));
lines.push("</name>".to_string());
lines.push("<description>".to_string());
lines.push(html_escape(&props.description));
lines.push("</description>".to_string());
let skill_md_path = find_skill_md(&dir);
lines.push("<location>".to_string());
lines.push(match skill_md_path {
Some(p) => p.display().to_string(),
None => "None".to_string(),
});
lines.push("</location>".to_string());
lines.push("</skill>".to_string());
}
lines.push("</available_skills>".to_string());
Ok(lines.join("\n"))
}