diff --git a/src/mcp_server_gitea.rs b/src/mcp_server_gitea.rs index 40cfc99..4cca38b 100644 --- a/src/mcp_server_gitea.rs +++ b/src/mcp_server_gitea.rs @@ -239,10 +239,22 @@ fn build_docker_command(settings: &GiteaContextServerSettings) -> Result Result { - // Standard docker locations - return first one - // WASM sandbox may restrict PathBuf::exists() but process spawning should work + // Try using 'which' to find docker in PATH + if let Ok(output) = std::process::Command::new("which").arg("docker").output() { + if output.status.success() { + if let Ok(path) = String::from_utf8(output.stdout) { + let path = path.trim(); + if !path.is_empty() { + return Ok(path.to_string()); + } + } + } + } + + // Standard docker locations as fallback + // Return the first common location - Zed will execute it and fail clearly if not found Ok("/usr/bin/docker".to_string()) } @@ -250,14 +262,12 @@ fn find_docker_binary() -> Result { /// /// Resolution strategy: /// 1. If explicit path provided in settings, use it directly -/// 2. Try common paths in platform-specific order -/// 3. Fall back to PATH environment variable -/// 4. Return error with helpful guidance if not found +/// 2. Search PATH environment variable for gitea-mcp or gitea-mcp-server +/// 3. Try common installation locations as fallback +/// 4. Return error with helpful instructions if not found /// -/// Note: WASM sandbox restricts filesystem access via exists() checks, -/// so we try common paths in priority order and return the first one. -/// If the binary is at that path, execution will succeed. If not, Zed's -/// error will clearly show which path failed. +/// Note: WASM sandbox restricts process spawning and filesystem checks, +/// but we CAN read environment variables and construct paths. /// /// Returns the path to the binary (as a string) to use, or an error with guidance fn resolve_binary_path(explicit_path: &Option) -> Result { @@ -266,33 +276,59 @@ fn resolve_binary_path(explicit_path: &Option) -> Result { return Ok(path.clone()); } - // WASM Limitation: Cannot reliably detect platform or use exists() checks. - // Simple approach: Try common absolute paths in priority order. - // Return the first one - Zed will execute it and fail clearly if not found. + // Try to search PATH environment variable manually + // WASM can't spawn 'which', but CAN read env vars + if let Ok(path_env) = std::env::var("PATH") { + let binary_names = ["gitea-mcp", "gitea-mcp-server"]; - let mut paths = vec![ - "/usr/local/bin/gitea-mcp".to_string(), - "/usr/local/bin/gitea-mcp-server".to_string(), - "/usr/bin/gitea-mcp".to_string(), - "/usr/bin/gitea-mcp-server".to_string(), - "/opt/homebrew/bin/gitea-mcp".to_string(), - "/opt/homebrew/bin/gitea-mcp-server".to_string(), + // Parse PATH and try each directory with each binary name + for path_dir in path_env.split(':') { + for binary_name in &binary_names { + let full_path = format!("{}/{}", path_dir, binary_name); + // We can't check if file exists in WASM, but we can return the path + // and let Zed try to execute it. We'll return the first match from + // common directories to increase success rate. + if path_dir.contains("/usr/local/bin") + || path_dir.contains("/usr/bin") + || path_dir.contains("/opt/homebrew/bin") + || path_dir.contains("/.local/bin") + || path_dir.contains("/.cargo/bin") + { + // This looks like a plausible location, try it + return Ok(full_path); + } + } + } + } + + // Fallback: Try common absolute paths + // Order by likelihood across platforms + let common_paths = [ + "/usr/local/bin/gitea-mcp", + "/usr/local/bin/gitea-mcp-server", + "/opt/homebrew/bin/gitea-mcp", + "/opt/homebrew/bin/gitea-mcp-server", + "/usr/bin/gitea-mcp", + "/usr/bin/gitea-mcp-server", ]; - // Add home directory paths if HOME is available - if let Ok(home) = std::env::var("HOME") { - paths.push(format!("{}/.local/bin/gitea-mcp", home)); - paths.push(format!("{}/.local/bin/gitea-mcp-server", home)); - paths.push(format!("{}/.cargo/bin/gitea-mcp", home)); - paths.push(format!("{}/.cargo/bin/gitea-mcp-server", home)); + // Return first path and let Zed try it + // If it fails, the error will show which path was attempted + if let Some(path) = common_paths.first() { + return Ok(path.to_string()); } - // Return the first path - if let Some(path) = paths.first() { - return Ok(path.clone()); - } - - Ok("/usr/local/bin/gitea-mcp".to_string()) + // Last resort error message + Err( + "gitea-mcp binary not found. Please set 'gitea_mcp_binary_path' in settings.\n\ + \n\ + Examples:\n\ + • macOS: \"gitea_mcp_binary_path\": \"/opt/homebrew/bin/gitea-mcp-server\"\n\ + • Linux: \"gitea_mcp_binary_path\": \"/usr/local/bin/gitea-mcp\"\n\ + \n\ + Or use Docker: \"use_docker\": true" + .into(), + ) } // Register the extension with Zed