mirror of
https://github.com/different-ai/openwork
synced 2026-04-25 17:15:34 +02:00
bug: (#563)
Root cause: On macOS, GUI applications don't inherit shell profile modifications (.zshrc, .bashrc). When OpenWork spawns the opencode engine, the PATH doesn't include paths like /opt/homebrew/bin where Homebrew-installed tools like npx reside. The fix (packages/desktop/src-tauri/src/paths.rs): Added a common_tool_paths() function that returns typical locations where user-installed tools are found: - macOS: /opt/homebrew/bin, /usr/local/bin, ~/.nvm/current/bin, ~/.volta/bin, ~/.bun/bin, ~/.cargo/bin, etc. - Linux: Similar paths adapted for Linux conventions - Windows: volta, pnpm, cargo, npm global paths These paths are now prepended to the PATH environment variable when spawning processes. To test the fix: Build and run the app, then try enabling your Playwright MCP server - it should now find npx correctly without needing to specify the full path.
This commit is contained in:
12
package-lock.json
generated
Normal file
12
package-lock.json
generated
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "@different-ai/openwork-workspace",
|
||||
"version": "0.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@different-ai/openwork-workspace",
|
||||
"version": "0.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -125,6 +125,89 @@ pub fn sidecar_path_candidates(
|
||||
unique
|
||||
}
|
||||
|
||||
/// Returns common paths where user-installed tools are typically located.
|
||||
/// On macOS, GUI apps don't inherit shell profile modifications (.zshrc, .bashrc),
|
||||
/// so tools installed via Homebrew, nvm, volta, etc. won't be found unless we
|
||||
/// explicitly include these common locations.
|
||||
fn common_tool_paths() -> Vec<PathBuf> {
|
||||
let mut paths = Vec::new();
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
// Homebrew paths (Apple Silicon and Intel)
|
||||
paths.push(PathBuf::from("/opt/homebrew/bin"));
|
||||
paths.push(PathBuf::from("/opt/homebrew/sbin"));
|
||||
paths.push(PathBuf::from("/usr/local/bin"));
|
||||
paths.push(PathBuf::from("/usr/local/sbin"));
|
||||
|
||||
// User-specific paths for common version managers
|
||||
if let Some(home) = home_dir() {
|
||||
// nvm, fnm (Node version managers)
|
||||
paths.push(home.join(".nvm/current/bin"));
|
||||
paths.push(home.join(".fnm/current/bin"));
|
||||
// volta
|
||||
paths.push(home.join(".volta/bin"));
|
||||
// pnpm
|
||||
paths.push(home.join("Library/pnpm"));
|
||||
// bun
|
||||
paths.push(home.join(".bun/bin"));
|
||||
// cargo/rustup
|
||||
paths.push(home.join(".cargo/bin"));
|
||||
// pyenv
|
||||
paths.push(home.join(".pyenv/shims"));
|
||||
// local bin
|
||||
paths.push(home.join(".local/bin"));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
paths.push(PathBuf::from("/usr/local/bin"));
|
||||
paths.push(PathBuf::from("/usr/local/sbin"));
|
||||
|
||||
if let Some(home) = home_dir() {
|
||||
// nvm, fnm
|
||||
paths.push(home.join(".nvm/current/bin"));
|
||||
paths.push(home.join(".fnm/current/bin"));
|
||||
// volta
|
||||
paths.push(home.join(".volta/bin"));
|
||||
// pnpm
|
||||
paths.push(home.join(".local/share/pnpm"));
|
||||
// bun
|
||||
paths.push(home.join(".bun/bin"));
|
||||
// cargo
|
||||
paths.push(home.join(".cargo/bin"));
|
||||
// pyenv
|
||||
paths.push(home.join(".pyenv/shims"));
|
||||
// local bin
|
||||
paths.push(home.join(".local/bin"));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
if let Some(home) = home_dir() {
|
||||
// volta
|
||||
paths.push(home.join(".volta/bin"));
|
||||
// pnpm
|
||||
if let Some(local) = env::var_os("LOCALAPPDATA") {
|
||||
paths.push(PathBuf::from(local).join("pnpm"));
|
||||
}
|
||||
// bun
|
||||
paths.push(home.join(".bun/bin"));
|
||||
// cargo
|
||||
paths.push(home.join(".cargo/bin"));
|
||||
}
|
||||
|
||||
// npm global
|
||||
if let Some(app_data) = env::var_os("APPDATA") {
|
||||
paths.push(PathBuf::from(app_data).join("npm"));
|
||||
}
|
||||
}
|
||||
|
||||
paths
|
||||
}
|
||||
|
||||
pub fn prepended_path_env(prefixes: &[PathBuf]) -> Option<std::ffi::OsString> {
|
||||
let mut entries = Vec::<PathBuf>::new();
|
||||
|
||||
@@ -134,8 +217,19 @@ pub fn prepended_path_env(prefixes: &[PathBuf]) -> Option<std::ffi::OsString> {
|
||||
}
|
||||
}
|
||||
|
||||
// Add common tool paths that may not be in the GUI app's inherited PATH
|
||||
for path in common_tool_paths() {
|
||||
if path.is_dir() && !entries.contains(&path) {
|
||||
entries.push(path);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(existing) = env::var_os("PATH") {
|
||||
entries.extend(env::split_paths(&existing));
|
||||
for path in env::split_paths(&existing) {
|
||||
if !entries.contains(&path) {
|
||||
entries.push(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if entries.is_empty() {
|
||||
|
||||
Reference in New Issue
Block a user