use anyhow::{Context, Result};
use std::path::{Path, PathBuf};
use vtcode_core::skills::discovery::SkillDiscovery;
use vtcode_core::skills::manifest::parse_skill_file;
use vtcode_core::skills::model::SkillScope;
use vtcode_core::skills::prompt_integration::generate_skills_prompt_xml;
pub async fn handle_skills_ref_validate(path: &Path) -> Result<()> {
println!("Validating skill at: {}\n", path.display());
let (manifest, _instructions) =
parse_skill_file(path).context(format!("Failed to parse skill at {}", path.display()))?;
manifest
.validate()
.context("Skill manifest validation failed")?;
println!("✓ Skill validation passed");
println!(" Name: {}", manifest.name);
println!(" Description: {}", manifest.description);
if let Some(license) = &manifest.license {
println!(" License: {}", license);
}
if let Some(compatibility) = &manifest.compatibility {
println!(" Compatibility: {}", compatibility);
}
if let Some(tools) = &manifest.tools {
println!(" Tools: {}", tools.join(", "));
}
Ok(())
}
pub async fn handle_skills_ref_to_prompt(paths: &[PathBuf]) -> Result<()> {
use vtcode_core::skills::model::SkillMetadata;
let mut skills = Vec::new();
for path in paths {
if path.is_dir() {
match parse_skill_file(path) {
Ok((manifest, _)) => {
skills.push(SkillMetadata {
name: manifest.name.clone(),
description: manifest.description.clone(),
short_description: None,
path: path.clone(),
scope: SkillScope::User,
manifest: Some(manifest),
});
}
Err(e) => {
eprintln!(
"Warning: Failed to parse skill at {}: {}",
path.display(),
e
);
}
}
}
}
if skills.is_empty() {
println!("<!-- No valid skills found -->");
return Ok(());
}
let xml = generate_skills_prompt_xml(&skills);
println!("{}", xml);
Ok(())
}
pub async fn handle_skills_ref_list(path: Option<&Path>) -> Result<()> {
let workspace_root = path
.map(PathBuf::from)
.unwrap_or_else(|| std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")));
let mut discovery = SkillDiscovery::new();
let result = discovery
.discover_all(&workspace_root)
.await
.context("Failed to discover skills")?;
println!(
"Discovered {} skills:\n",
result.skills.len() + result.tools.len()
);
if !result.skills.is_empty() {
println!("Traditional Skills:");
for skill_ctx in &result.skills {
let manifest = skill_ctx.manifest();
println!(" {} - {}", manifest.name, manifest.description);
}
println!();
}
if !result.tools.is_empty() {
println!("CLI Tool Skills:");
for tool in &result.tools {
println!(" {} - {}", tool.name, tool.description);
}
}
println!("\nDiscovery Stats:");
println!(
" Directories scanned: {}",
result.stats.directories_scanned
);
println!(" Files checked: {}", result.stats.files_checked);
println!(" Discovery time: {}ms", result.stats.discovery_time_ms);
Ok(())
}