agent_exec/
install_skills.rs1use anyhow::Result;
7
8use crate::schema::{InstallSkillsData, InstalledSkillSummary, Response};
9use crate::skills::{LockEntry, LockFile, install_builtin, now_rfc3339, resolve_root_dir};
10
11pub struct InstallSkillsOpts {
13 pub global: bool,
15 pub claude: bool,
17}
18
19pub fn execute(opts: InstallSkillsOpts) -> Result<()> {
24 let root_dir = resolve_root_dir(opts.global, opts.claude)?;
25
26 let installed = install_builtin(&root_dir)?;
27
28 let lock_path = root_dir.join(".skill-lock.json");
29 let mut lock = LockFile::read(&lock_path)?;
30 let entry = LockEntry {
31 name: installed.name.clone(),
32 source_type: installed.source_type.clone(),
33 installed_at: now_rfc3339(),
34 path: installed.path.to_string_lossy().into_owned(),
35 };
36 lock.upsert(entry);
37 lock.write(&lock_path)?;
38
39 let data = InstallSkillsData {
41 skills: vec![InstalledSkillSummary {
42 name: installed.name,
43 source_type: installed.source_type,
44 path: installed.path.to_string_lossy().into_owned(),
45 }],
46 global: opts.global,
47 lock_file_path: lock_path.to_string_lossy().into_owned(),
48 };
49 Response::new("install_skills", data).print();
50 Ok(())
51}