diff --git a/src-tauri/src/wsl_bridge.rs b/src-tauri/src/wsl_bridge.rs index cafc4e3..08b0651 100644 --- a/src-tauri/src/wsl_bridge.rs +++ b/src-tauri/src/wsl_bridge.rs @@ -138,11 +138,6 @@ impl WslBridge { return Err("Process already running".to_string()); } - // Check if Claude binary is installed before attempting to start - // if Command::new("which").arg("claude").output().ok().is_none_or(|output| !output.status.success()) { - // return Err("Claude Code is not installed. Please install it using:\n\ncurl -fsSL https://claude.ai/install.sh | bash".to_string()); - // } - // Load saved achievements and stats when starting a new session let app_clone = app.clone(); let stats = self.stats.clone(); @@ -272,6 +267,16 @@ impl WslBridge { // Running on Windows - use wsl with bash login shell to ensure PATH is loaded tracing::debug!("Windows path - using wsl"); + // Check if Claude binary is installed inside WSL + let binary_check = Command::new("wsl") + .args(["-e", "bash", "-lc", "which claude"]) + .output(); + if let Ok(output) = binary_check { + if !output.status.success() { + return Err("Claude Code is not installed. Please install it using:\n\ncurl -fsSL https://claude.ai/install.sh | bash".to_string()); + } + } + // Validate the working directory exists inside WSL before spawning let dir_check = Command::new("wsl") .args(["-e", "test", "-d", working_dir]) @@ -1935,20 +1940,28 @@ mod tests { let _ = has_exited; // suppress unused warning } + /// Build the WSL binary check command structure without executing it (for testing) + #[cfg(test)] + fn build_wsl_binary_check_args() -> Vec<&'static str> { + vec!["-e", "bash", "-lc", "which claude"] + } + #[test] - fn test_claude_binary_check_command_structure() { - // Test that we're using the correct command to check for Claude binary - let output = Command::new("which").arg("claude").output(); + fn test_wsl_binary_check_command_structure() { + // Windows path: verify Claude is detected inside WSL via `wsl -e bash -lc "which claude"` + let args = build_wsl_binary_check_args(); + assert_eq!(args[0], "-e"); + assert_eq!(args[1], "bash"); + assert_eq!(args[2], "-lc"); + assert_eq!(args[3], "which claude"); + } - // The command should execute successfully (even if claude is not found) - // We're just verifying the command structure is valid - assert!(output.is_ok(), "which command should execute without error"); - - // Verify the check logic returns a boolean - // This is the same logic used in start() to check if claude is installed - let _result = output.ok().is_none_or(|o| !o.status.success()); - // If claude is not installed, _result will be true (show error) - // If claude is installed, _result will be false (proceed with connection) + #[test] + fn test_linux_binary_check_does_not_panic() { + // Linux/WSL path: find_claude_binary() searches Linux filesystem paths. + // We just verify it runs without panicking; whether it returns Some depends + // on whether Claude is actually installed in this environment. + let _result = find_claude_binary(); } #[test]