From b2c301166cd42ea22addd04fc652c17b59f0bf72 Mon Sep 17 00:00:00 2001 From: "V. Lascik" Date: Thu, 13 Nov 2025 20:12:52 +0100 Subject: [PATCH 1/3] fix: get win node path from registry Signed-off-by: V. Lascik --- Cargo.lock | 13 ++++++++- crates/goose-server/Cargo.toml | 3 ++ crates/goose-server/src/routes/agent.rs | 37 +++++++++++++++++++++++-- 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d96926345278..be31b26a109f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2873,6 +2873,7 @@ dependencies = [ "tracing-subscriber", "utoipa", "uuid", + "winreg 0.55.0", ] [[package]] @@ -5488,7 +5489,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "winreg", + "winreg 0.50.0", ] [[package]] @@ -8447,6 +8448,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "winreg" +version = "0.55.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb5a765337c50e9ec252c2069be9bf91c7df47afb103b642ba3a53bf8101be97" +dependencies = [ + "cfg-if", + "windows-sys 0.59.0", +] + [[package]] name = "winsafe" version = "0.0.19" diff --git a/crates/goose-server/Cargo.toml b/crates/goose-server/Cargo.toml index 59d4f2041823..34ed900a916d 100644 --- a/crates/goose-server/Cargo.toml +++ b/crates/goose-server/Cargo.toml @@ -40,6 +40,9 @@ tokio-util = "0.7.15" uuid = { version = "1.11", features = ["v4"] } serde_path_to_error = "0.1.20" +[target.'cfg(windows)'.dependencies] +winreg = { version = "0.55.0" } + [[bin]] name = "goosed" path = "src/main.rs" diff --git a/crates/goose-server/src/routes/agent.rs b/crates/goose-server/src/routes/agent.rs index 90c6db9a517d..5e60181d965d 100644 --- a/crates/goose-server/src/routes/agent.rs +++ b/crates/goose-server/src/routes/agent.rs @@ -483,12 +483,43 @@ async fn agent_add_extension( Json(request): Json, ) -> Result { if cfg!(target_os = "windows") { + use winreg::enums::{HKEY_LOCAL_MACHINE, KEY_READ}; + use winreg::RegKey; + if let ExtensionConfig::Stdio { cmd, .. } = &request.config { if cmd.ends_with("npx.cmd") || cmd.ends_with("npx") { - let node_exists = std::path::Path::new(r"C:\Program Files\nodejs\node.exe") + let mut node_exists = std::path::Path::new(r"C:\Program Files\nodejs\node.exe") .exists() || std::path::Path::new(r"C:\Program Files (x86)\nodejs\node.exe").exists(); + // Also check Windows registry: HKEY_LOCAL_MACHINE\\SOFTWARE\\Node.js InstallPath + if !node_exists { + // Try 64-bit view first, then 32-bit. Use open_subkey_with_flags to avoid WOW64 redirection issues. + let install_path_from_reg: Option = (|| { + let hk_local_machine = RegKey::predef(HKEY_LOCAL_MACHINE); + // Common keys to try + let keys = vec!["SOFTWARE\\Node.js", "SOFTWARE\\WOW6432Node\\Node.js"]; + for k in keys.iter() { + if let Ok(subkey) = hk_local_machine.open_subkey_with_flags(k, KEY_READ) + { + if let Ok(val) = subkey.get_value::("InstallPath") { + if !val.trim().is_empty() { + return Some(val); + } + } + } + } + None + })(); + + if let Some(path_str) = install_path_from_reg { + let node_path = std::path::Path::new(&path_str).join("node.exe"); + if node_path.exists() { + node_exists = true; + } + } + } + if !node_exists { let cmd_path = std::path::Path::new(&cmd); let script_dir = cmd_path @@ -497,7 +528,7 @@ async fn agent_add_extension( let install_script = script_dir.join("install-node.cmd"); if install_script.exists() { - eprintln!("Installing Node.js..."); + eprintln!("Node.js not found on the system, installing Node.js..."); let output = std::process::Command::new(&install_script) .arg("https://nodejs.org/dist/v23.10.0/node-v23.10.0-x64.msi") .output() @@ -513,7 +544,7 @@ async fn agent_add_extension( } } else { return Err(ErrorResponse::internal(format!( - "Node.js not detected and no installer script not found at: {}", + "Node.js not found on the system, and no installer script found at: {}", install_script.display() ))); } From 40f8755e353b08dd5ac3d42e9e11894535af9895 Mon Sep 17 00:00:00 2001 From: "V. Lascik" Date: Fri, 14 Nov 2025 19:33:02 +0100 Subject: [PATCH 2/3] winreg dependency Signed-off-by: V. Lascik --- crates/goose-server/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/goose-server/Cargo.toml b/crates/goose-server/Cargo.toml index 34ed900a916d..acc9a6501199 100644 --- a/crates/goose-server/Cargo.toml +++ b/crates/goose-server/Cargo.toml @@ -39,6 +39,7 @@ reqwest = { version = "0.12.9", features = ["json", "rustls-tls", "blocking", "m tokio-util = "0.7.15" uuid = { version = "1.11", features = ["v4"] } serde_path_to_error = "0.1.20" +winreg = { version = "0.55.0", optional = true } [target.'cfg(windows)'.dependencies] winreg = { version = "0.55.0" } From 0daff651121fb9dc0cd59f0c10ff1da672f24714 Mon Sep 17 00:00:00 2001 From: "V. Lascik" Date: Fri, 14 Nov 2025 21:11:42 +0100 Subject: [PATCH 3/3] do not try to include winreg if not in windows build Signed-off-by: V. Lascik --- crates/goose-server/src/routes/agent.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/goose-server/src/routes/agent.rs b/crates/goose-server/src/routes/agent.rs index 5e60181d965d..3d1be23ae215 100644 --- a/crates/goose-server/src/routes/agent.rs +++ b/crates/goose-server/src/routes/agent.rs @@ -482,7 +482,8 @@ async fn agent_add_extension( State(state): State>, Json(request): Json, ) -> Result { - if cfg!(target_os = "windows") { + #[cfg(windows)] + { use winreg::enums::{HKEY_LOCAL_MACHINE, KEY_READ}; use winreg::RegKey;