diff --git a/cli/Cargo.lock b/cli/Cargo.lock index 18194a3..ecb4aea 100644 --- a/cli/Cargo.lock +++ b/cli/Cargo.lock @@ -9,6 +9,7 @@ dependencies = [ "libc", "serde", "serde_json", + "windows-sys", ] [[package]] @@ -107,6 +108,79 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + [[package]] name = "zmij" version = "1.0.12" diff --git a/cli/Cargo.toml b/cli/Cargo.toml index ef47f9b..6f36cec 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -12,6 +12,9 @@ serde_json = "1.0" [target.'cfg(unix)'.dependencies] libc = "0.2" +[target.'cfg(windows)'.dependencies] +windows-sys = { version = "0.52", features = ["Win32_System_Threading", "Win32_Foundation"] } + [profile.release] opt-level = 3 lto = true diff --git a/cli/src/main.rs b/cli/src/main.rs index cb0f767..1f86fe3 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -6,14 +6,93 @@ mod output; use serde_json::json; use std::env; +use std::fs; use std::process::exit; +#[cfg(unix)] +use libc; + +#[cfg(windows)] +use windows_sys::Win32::Foundation::CloseHandle; +#[cfg(windows)] +use windows_sys::Win32::System::Threading::{OpenProcess, PROCESS_QUERY_LIMITED_INFORMATION}; + use commands::{gen_id, parse_command, ParseError}; use connection::{ensure_daemon, send_command}; use flags::{clean_args, parse_flags}; use install::run_install; use output::{print_help, print_response}; +fn run_session(args: &[String], session: &str, json_mode: bool) { + let subcommand = args.get(1).map(|s| s.as_str()); + + match subcommand { + Some("list") => { + let tmp = env::temp_dir(); + let mut sessions: Vec = Vec::new(); + + if let Ok(entries) = fs::read_dir(&tmp) { + for entry in entries.flatten() { + let name = entry.file_name().to_string_lossy().to_string(); + // Look for socket files (Unix) or pid files + if name.starts_with("agent-browser-") && name.ends_with(".pid") { + let session_name = name + .strip_prefix("agent-browser-") + .and_then(|s| s.strip_suffix(".pid")) + .unwrap_or(""); + if !session_name.is_empty() { + // Check if session is actually running + let pid_path = tmp.join(&name); + if let Ok(pid_str) = fs::read_to_string(&pid_path) { + if let Ok(pid) = pid_str.trim().parse::() { + #[cfg(unix)] + let running = unsafe { libc::kill(pid as i32, 0) == 0 }; + #[cfg(windows)] + let running = unsafe { + let handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, 0, pid); + if handle != 0 { + CloseHandle(handle); + true + } else { + false + } + }; + if running { + sessions.push(session_name.to_string()); + } + } + } + } + } + } + } + + if json_mode { + println!( + r#"{{"success":true,"data":{{"sessions":{}}}}}"#, + serde_json::to_string(&sessions).unwrap_or_default() + ); + } else if sessions.is_empty() { + println!("No active sessions"); + } else { + println!("Active sessions:"); + for s in &sessions { + let marker = if s == session { "→" } else { " " }; + println!("{} {}", marker, s); + } + } + } + None | Some(_) => { + // Just show current session + if json_mode { + println!(r#"{{"success":true,"data":{{"session":"{}"}}}}"#, session); + } else { + println!("{}", session); + } + } + } +} + fn main() { let args: Vec = env::args().skip(1).collect(); let flags = parse_flags(&args); @@ -31,6 +110,12 @@ fn main() { return; } + // Handle session separately (doesn't need daemon) + if clean.get(0).map(|s| s.as_str()) == Some("session") { + run_session(&clean, &flags.session, flags.json); + return; + } + let cmd = match parse_command(&clean, &flags) { Ok(c) => c, Err(e) => { diff --git a/cli/src/output.rs b/cli/src/output.rs index 18b4eba..9a4a775 100644 --- a/cli/src/output.rs +++ b/cli/src/output.rs @@ -215,6 +215,10 @@ Debug: errors [--clear] View page errors highlight Highlight element +Sessions: + session Show current session name + session list List active sessions + Setup: install Install browser binaries install --with-deps Also install system dependencies (Linux)