use clap::Args;
use std::path::PathBuf;
use skm_core::SkillRegistry;
#[derive(Args)]
pub struct ListArgs {
#[arg(default_value = ".")]
paths: Vec<PathBuf>,
#[arg(short, long, default_value = "text")]
format: String,
#[arg(long)]
triggers: bool,
#[arg(long)]
tags: bool,
#[arg(long)]
tokens: bool,
}
pub async fn list(args: ListArgs) -> anyhow::Result<()> {
let registry = SkillRegistry::new(&args.paths).await?;
let catalog = registry.catalog().await;
match args.format.as_str() {
"json" => {
let skills: Vec<serde_json::Value> = catalog
.iter()
.map(|s| {
serde_json::json!({
"name": s.name.as_str(),
"description": s.description,
"triggers": s.triggers,
"tags": s.tags,
"estimated_tokens": s.estimated_tokens,
"source": s.source_path.display().to_string()
})
})
.collect();
println!("{}", serde_json::to_string_pretty(&skills)?);
}
"csv" => {
println!("name,description,triggers,tags,tokens");
for s in &catalog {
println!(
"{},{:?},{:?},{:?},{}",
s.name,
s.description,
s.triggers.join(";"),
s.tags.join(";"),
s.estimated_tokens
);
}
}
_ => {
println!("Found {} skills:\n", catalog.len());
for s in &catalog {
println!(" {} - {}", s.name, s.description);
if args.triggers && !s.triggers.is_empty() {
println!(" triggers: {}", s.triggers.join(", "));
}
if args.tags && !s.tags.is_empty() {
println!(" tags: {}", s.tags.join(", "));
}
if args.tokens {
println!(" tokens: ~{}", s.estimated_tokens);
}
}
}
}
Ok(())
}