nexus_core/app/
skills_popup.rs1use super::App;
2use tokio::sync::mpsc;
3
4impl App {
5 pub fn reload_skills(&mut self) {
9 self.skills = crate::skills::load_skills(&crate::skills::skills_dir(&self.space.root));
10 }
11
12 pub fn start_skill_install(&mut self, spec: &str) {
18 let spec = spec.trim().to_string();
19 let Some((owner, repo, path)) = crate::skills::parse_gh_shorthand(&spec) else {
20 self.push_status(format!("expected owner/repo/path, got: {spec}"));
21 return;
22 };
23 let dest = crate::skills::skills_dir(&self.space.root);
24 let (tx, rx) = mpsc::unbounded_channel();
25 self.skills_rx = Some(rx);
26 self.push_status(format!("installing {spec}…"));
27 tokio::spawn(async move {
28 let client = reqwest::Client::new();
29 let result = crate::skills::install_from_github(&client, &owner, &repo, &path, &dest)
30 .await
31 .map_err(|e| e.to_string());
32 let _ = tx.send(result);
33 });
34 }
35
36 pub fn on_skill_install_result(&mut self, result: Option<Result<String, String>>) {
37 self.skills_rx = None;
38 match result {
39 Some(Ok(name)) => {
40 self.reload_skills();
41 self.push_status(format!("installed skill: {name}"));
42 }
43 Some(Err(e)) => self.push_status(format!("skill install failed: {e}")),
44 None => {}
45 }
46 }
47}