From 0abf410aa9f93df6c52c258ad27aa31647c923c1 Mon Sep 17 00:00:00 2001 From: Hikari Date: Mon, 23 Feb 2026 20:15:27 -0800 Subject: [PATCH] fix: correct WSL detection and binary lookup for GUI context - detect_wsl() now short-circuits on Windows builds (cfg! compile-time check), preventing inherited WSL_DISTRO_NAME from routing a native Windows .exe through the Linux code path - find_claude_binary() no longer early-exits when HOME is unset; falls back to bash -lc "which claude" so GUI apps (which don't inherit shell PATH) can still locate the binary via the login shell --- src-tauri/src/wsl_bridge.rs | 40 ++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src-tauri/src/wsl_bridge.rs b/src-tauri/src/wsl_bridge.rs index 08b0651..b06cd33 100644 --- a/src-tauri/src/wsl_bridge.rs +++ b/src-tauri/src/wsl_bridge.rs @@ -39,6 +39,12 @@ const SEARCH_TOOLS: [&str; 5] = ["Read", "Glob", "Grep", "WebSearch", "WebFetch" const CODING_TOOLS: [&str; 3] = ["Edit", "Write", "NotebookEdit"]; fn detect_wsl() -> bool { + // A native Windows binary is never running inside WSL, even if launched from a WSL + // terminal that has WSL_DISTRO_NAME set in its environment. + if cfg!(target_os = "windows") { + return false; + } + // Check /proc/version for WSL indicators if let Ok(version) = std::fs::read_to_string("/proc/version") { let version_lower = version.to_lowercase(); @@ -61,23 +67,29 @@ fn detect_wsl() -> bool { } fn find_claude_binary() -> Option { - // Check common installation locations for claude - let home = std::env::var("HOME").ok()?; - let paths_to_check = [ - format!("{}/.local/bin/claude", home), - format!("{}/.claude/local/claude", home), - "/usr/local/bin/claude".to_string(), - "/usr/bin/claude".to_string(), - ]; - - for path in &paths_to_check { - if std::path::Path::new(path).exists() { - return Some(path.clone()); + // Check common installation locations for claude (when HOME is available) + if let Ok(home) = std::env::var("HOME") { + let paths_to_check = [ + format!("{}/.local/bin/claude", home), + format!("{}/.claude/local/claude", home), + ]; + for path in &paths_to_check { + if std::path::Path::new(path).exists() { + return Some(path.clone()); + } } } - // Fall back to checking PATH via which - if let Ok(output) = Command::new("which").arg("claude").output() { + // Check system-wide locations + for path in &["/usr/local/bin/claude", "/usr/bin/claude"] { + if std::path::Path::new(path).exists() { + return Some((*path).to_string()); + } + } + + // Use a login shell to resolve claude via the user's PATH - GUI apps don't + // inherit shell PATH, so bare `which` may miss ~/.local/bin entries + if let Ok(output) = Command::new("bash").args(["-lc", "which claude"]).output() { if output.status.success() { let path = String::from_utf8_lossy(&output.stdout).trim().to_string(); if !path.is_empty() {