use anyhow::{bail, Result};
use clap::{Args, Subcommand};
use offline_registry::Registry;
use serde_json::json;
use crate::output;
#[derive(Subcommand)]
pub enum SkillsCommand {
List(ListArgs),
Show(ShowArgs),
}
#[derive(Args)]
pub struct ListArgs {
#[arg(long)]
pub json: bool,
}
#[derive(Args)]
pub struct ShowArgs {
pub name: String,
#[arg(long)]
pub json: bool,
}
pub fn run(cmd: SkillsCommand) -> Result<()> {
let registry = Registry::load_default()?;
match cmd {
SkillsCommand::List(args) => {
if args.json {
let skills: Vec<_> = registry
.skills()
.map(|s| {
json!({
"name": s.name,
"title": s.title,
"description": s.description,
"useWhen": s.use_when,
"packages": s.packages,
})
})
.collect();
return output::json(&skills);
}
output::heading("Skills");
for s in registry.skills() {
output::item(&s.name, &s.description);
output::note(&format!("use when: {}", s.use_when.join("; ")));
}
Ok(())
}
SkillsCommand::Show(args) => {
let Some(skill) = registry.skill(&args.name) else {
let hits = registry.search_skills(&args.name);
let hint = hits
.first()
.map(|h| format!(". Did you mean `{}`?", h.name))
.unwrap_or_default();
bail!("skill `{}` not found{hint}", args.name);
};
if args.json {
return output::json(skill);
}
println!("{}", skill.body);
Ok(())
}
}
}