diff --git a/packages/tauri-app/src-tauri/src/cli_manager.rs b/packages/tauri-app/src-tauri/src/cli_manager.rs index 613b1c2e..d89247af 100644 --- a/packages/tauri-app/src-tauri/src/cli_manager.rs +++ b/packages/tauri-app/src-tauri/src/cli_manager.rs @@ -38,6 +38,7 @@ use windows_sys::Win32::System::JobObjects::{ #[cfg(windows)] const CREATE_NO_WINDOW: u32 = 0x08000000; +const MISSING_NODE_PREFIX: &str = "CODENOMAD_MISSING_NODE:"; #[cfg(windows)] #[derive(Debug)] @@ -630,6 +631,13 @@ impl CliProcessManager { let use_user_shell = supports_user_shell(); + if !use_user_shell && which::which(&resolution.node_binary).is_err() { + return Err(anyhow::anyhow!( + "Node binary '{}' not found. CodeNomad desktop currently requires Node.js installed on the system, or set NODE_BINARY to a valid runtime path.", + resolution.node_binary + )); + } + let command_info = if use_user_shell { log_line("spawning via user shell"); ShellCommandType::UserShell(build_shell_command_string(&resolution, &args)?) @@ -641,14 +649,6 @@ impl CliProcessManager { }) }; - if !use_user_shell { - if which::which(&resolution.node_binary).is_err() { - return Err(anyhow::anyhow!( - "Node binary not found. Make sure Node.js is installed." - )); - } - } - let child = match &command_info { ShellCommandType::UserShell(cmd) => { log_line(&format!("spawn command: {} {:?}", cmd.shell, cmd.args)); @@ -920,6 +920,17 @@ impl CliProcessManager { continue; } + if let Some(node_binary) = line.strip_prefix(MISSING_NODE_PREFIX) { + let mut locked = status.lock(); + if locked.error.is_none() { + locked.error = Some(format!( + "Node binary '{}' not found in the desktop shell environment. CodeNomad desktop currently requires Node.js installed on the system, or set NODE_BINARY to a valid runtime path.", + node_binary.trim() + )); + } + continue; + } + if let Some(url) = local_url_regex .as_ref() .and_then(|re| re.captures(line).and_then(|c| c.get(1))) @@ -1248,7 +1259,13 @@ fn build_shell_command_string( for arg in entry.runner_args(cli_args) { quoted.push(shell_escape(&arg)); } - let command = format!("ELECTRON_RUN_AS_NODE=1 exec {}", quoted.join(" ")); + let command = format!( + "if command -v {} >/dev/null 2>&1; then ELECTRON_RUN_AS_NODE=1 exec {}; else printf '%s%s\\n' '{}' {} >&2; exit 127; fi", + shell_escape(&entry.node_binary), + quoted.join(" "), + MISSING_NODE_PREFIX, + shell_escape(&entry.node_binary), + ); let args = build_shell_args(&shell, &command); log_line(&format!("user shell command: {} {:?}", shell, args)); Ok(ShellCommand { shell, args })