diff --git a/build-agent-browser.ps1 b/build-agent-browser.ps1 new file mode 100644 index 00000000..227b48ae --- /dev/null +++ b/build-agent-browser.ps1 @@ -0,0 +1,30 @@ +#!/usr/bin/env pwsh +# Build script for agent-browser native binary +# Usage: .\build-agent-browser.ps1 + +$ErrorActionPreference = "Stop" + +Write-Host "Building agent-browser native binary..." -ForegroundColor Cyan +Write-Host "" + +# Step 1: Sync version +Write-Host "[1/3] Syncing version..." -ForegroundColor Yellow +pnpm run version:sync + +# Step 2: Build Rust binary +Write-Host "[2/3] Building Rust binary..." -ForegroundColor Yellow +cargo build --release --manifest-path cli/Cargo.toml + +if ($LASTEXITCODE -ne 0) { + Write-Error "Cargo build failed!" +} + +# Step 3: Copy binary to bin directory +Write-Host "[3/3] Copying binary to bin directory..." -ForegroundColor Yellow +node scripts/copy-native.js + +Write-Host "" +Write-Host "Build complete!" -ForegroundColor Green +Write-Host "" +Write-Host "To test the fix:" -ForegroundColor Cyan +Write-Host " cd bin; .\agent-browser.exe connect 9222" -ForegroundColor White diff --git a/build-agent-browser.sh b/build-agent-browser.sh new file mode 100644 index 00000000..1d02f741 --- /dev/null +++ b/build-agent-browser.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# Build script for agent-browser native binary +# Usage: ./build-agent-browser.sh + +set -e + +echo "Building agent-browser native binary..." +echo "" + +# Step 1: Sync version +echo "[1/3] Syncing version..." +pnpm run version:sync + +# Step 2: Build Rust binary +echo "[2/3] Building Rust binary..." +cargo build --release --manifest-path cli/Cargo.toml + +# Step 3: Copy binary to bin directory +echo "[3/3] Copying binary to bin directory..." +node scripts/copy-native.js + +echo "" +echo "Build complete!" +echo "" +echo "To test the fix:" +echo " cd bin; ./agent-browser connect 9222" diff --git a/cli/src/connection.rs b/cli/src/connection.rs index f6a7a39a..089c35c3 100644 --- a/cli/src/connection.rs +++ b/cli/src/connection.rs @@ -216,6 +216,25 @@ pub fn ensure_daemon( let exe_path = exe_path.canonicalize().unwrap_or(exe_path); let exe_dir = exe_path.parent().unwrap(); + // Determine the working directory for the daemon + // We need to find a directory where daemon.js or dist/daemon.js exists + let daemon_cwd = if exe_dir.join("daemon.js").exists() { + exe_dir.to_path_buf() + } else if exe_dir.join("dist").join("daemon.js").exists() { + exe_dir.to_path_buf() + } else { + // Check if we're in a bin directory and the project is one level up + let parent_dir = exe_dir.parent().unwrap_or(&exe_dir); + if parent_dir.join("daemon.js").exists() { + parent_dir.to_path_buf() + } else if parent_dir.join("dist").join("daemon.js").exists() { + parent_dir.to_path_buf() + } else { + // Fallback to current working directory + env::current_dir().unwrap_or(exe_dir.to_path_buf()) + } + }; + let mut daemon_paths = vec![ exe_dir.join("daemon.js"), exe_dir.join("../dist/daemon.js"), @@ -234,6 +253,19 @@ pub fn ensure_daemon( .find(|p| p.exists()) .ok_or("Daemon not found. Set AGENT_BROWSER_HOME environment variable or run from project directory.")?; + // Remove any Windows extended length path prefix (\\?\) for compatibility with Node.js + let daemon_path = daemon_path.to_str() + .map(|s| { + let prefix = r"\\?\"; + let normalized = if s.starts_with(prefix) { + &s[prefix.len()..] + } else { + s + }; + PathBuf::from(normalized) + }) + .unwrap_or_else(|| daemon_path.clone()); + // Spawn daemon as a fully detached background process #[cfg(unix)] { @@ -242,7 +274,8 @@ pub fn ensure_daemon( let mut cmd = Command::new("node"); cmd.arg(daemon_path) .env("AGENT_BROWSER_DAEMON", "1") - .env("AGENT_BROWSER_SESSION", session); + .env("AGENT_BROWSER_SESSION", session) + .current_dir(daemon_cwd.clone()); if headed { cmd.env("AGENT_BROWSER_HEADED", "1"); @@ -307,9 +340,10 @@ pub fn ensure_daemon( // On Windows, call node directly. Command::new handles PATH resolution (node.exe or node.cmd) // and automatically quotes arguments containing spaces. let mut cmd = Command::new("node"); - cmd.arg(daemon_path) + cmd.arg(&daemon_path) .env("AGENT_BROWSER_DAEMON", "1") - .env("AGENT_BROWSER_SESSION", session); + .env("AGENT_BROWSER_SESSION", session) + .current_dir(&daemon_cwd); if headed { cmd.env("AGENT_BROWSER_HEADED", "1");