Skip to main content

skm_cli/commands/
list.rs

1//! List command: list skills in a directory.
2
3use clap::Args;
4use std::path::PathBuf;
5
6use skm_core::SkillRegistry;
7
8#[derive(Args)]
9pub struct ListArgs {
10    /// Skill directories to scan
11    #[arg(default_value = ".")]
12    paths: Vec<PathBuf>,
13
14    /// Output format (text, json, csv)
15    #[arg(short, long, default_value = "text")]
16    format: String,
17
18    /// Show triggers
19    #[arg(long)]
20    triggers: bool,
21
22    /// Show tags
23    #[arg(long)]
24    tags: bool,
25
26    /// Show token estimates
27    #[arg(long)]
28    tokens: bool,
29}
30
31pub async fn list(args: ListArgs) -> anyhow::Result<()> {
32    let registry = SkillRegistry::new(&args.paths).await?;
33    let catalog = registry.catalog().await;
34
35    match args.format.as_str() {
36        "json" => {
37            let skills: Vec<serde_json::Value> = catalog
38                .iter()
39                .map(|s| {
40                    serde_json::json!({
41                        "name": s.name.as_str(),
42                        "description": s.description,
43                        "triggers": s.triggers,
44                        "tags": s.tags,
45                        "estimated_tokens": s.estimated_tokens,
46                        "source": s.source_path.display().to_string()
47                    })
48                })
49                .collect();
50            println!("{}", serde_json::to_string_pretty(&skills)?);
51        }
52        "csv" => {
53            println!("name,description,triggers,tags,tokens");
54            for s in &catalog {
55                println!(
56                    "{},{:?},{:?},{:?},{}",
57                    s.name,
58                    s.description,
59                    s.triggers.join(";"),
60                    s.tags.join(";"),
61                    s.estimated_tokens
62                );
63            }
64        }
65        _ => {
66            println!("Found {} skills:\n", catalog.len());
67
68            for s in &catalog {
69                println!("  {} - {}", s.name, s.description);
70
71                if args.triggers && !s.triggers.is_empty() {
72                    println!("    triggers: {}", s.triggers.join(", "));
73                }
74
75                if args.tags && !s.tags.is_empty() {
76                    println!("    tags: {}", s.tags.join(", "));
77                }
78
79                if args.tokens {
80                    println!("    tokens: ~{}", s.estimated_tokens);
81                }
82            }
83        }
84    }
85
86    Ok(())
87}