diff --git a/src/skill.rs b/src/skill.rs index 700d00e..09d9174 100644 --- a/src/skill.rs +++ b/src/skill.rs @@ -195,16 +195,19 @@ fn is_managed_by_skills_agent() -> bool { } fn download_and_extract() -> Result<(), String> { - let url = download_url(); + download_and_extract_from_url(&download_url()) +} + +fn download_and_extract_from_url(url: &str) -> Result<(), String> { eprintln!("Downloading skill..."); // Binary download — can't route through `send_debug` (which calls // `resp.text()` and would corrupt the gzip stream). Log the // request line manually so `--debug` still shows the URL. - crate::util::debug_request("GET", &url, &[], None); + crate::util::debug_request("GET", url, &[], None); let client = reqwest::blocking::Client::new(); let resp = client - .get(&url) + .get(url) .send() .map_err(|e| format!("error downloading skill: {e}"))?; @@ -250,6 +253,29 @@ fn download_and_extract() -> Result<(), String> { Ok(()) } +/// Download and install skills for `version`. Called from `run_update()` after +/// the binary has been atomically swapped so that skills match the new CLI on +/// first use. Uses the release tarball URL for `version` (not `CURRENT_VERSION`, +/// which is still the old binary at call time). Skips silently when managed by +/// a skills agent. Prints a warning on failure so the binary update is not +/// rolled back. +pub fn install_for_version(version: &Version) { + if is_managed_by_skills_agent() { + return; + } + let url = format!("https://github.com/{REPO}/releases/download/v{version}/skills.tar.gz"); + if let Err(e) = download_and_extract_from_url(&url) { + eprintln!( + "{}", + format!("warning: could not update agent skills: {e}").yellow() + ); + return; + } + let _symlinks = ensure_symlinks(); + clear_skill_auto_update_suppression(); + println!("{}", format!("Agent skills updated to v{version}.").green()); +} + fn copy_dir_recursive(src: &PathBuf, dst: &PathBuf) -> Result<(), String> { fs::create_dir_all(dst).map_err(|e| format!("error creating directory: {e}"))?; for entry in fs::read_dir(src).map_err(|e| format!("error reading directory: {e}"))? { diff --git a/src/update.rs b/src/update.rs index 3aa8ba2..92bec7d 100644 --- a/src/update.rs +++ b/src/update.rs @@ -185,6 +185,12 @@ pub fn run_update() { } println!("{}", format!("Updated to v{latest}.").green()); + // Install/update skills to match the new binary. The tarball URL is built + // from `latest` (not CURRENT_VERSION) because the old binary is still + // running at this point — we want the skills for the version we just + // downloaded, not the one we replaced. + crate::skill::install_for_version(&latest); + // Bust the cache so the notice clears on the next run. write_cache(&UpdateCheckCache { checked_at: now_secs(),