app
Pup - the AI's own browser
Public Made by Adomby adom
pup gives your AI a real browser on your desktop that it drives completely, in the background, signed in as you: windows that never jump in front of your work, one shared profile that learns your logins, and every window labeled on the taskbar with its AI thread's name.
master
John Lauer
v2.0.720 (insiders): Groundwork for the macOS build of the Rust pup (Kyle's pull request #3, pup-bridge#128): the Mac h…
87f5051
27d ago
//! Live probe of the mac host against Chrome for Testing: non-activating launch, pid resolution,
//! window discovery by pid, park (hide), unpark, kill. Run: cargo run -p pup-host-mac --example live_probe <cft-exe> <profile-dir>
use pup_host::{HostProcess, HostWindows};
use pup_host_mac::MacHost;
use std::path::Path;
use std::time::{Duration, Instant};
fn main() {
let a: Vec<String> = std::env::args().collect();
let exe = Path::new(&a[1]); let profile = &a[2];
let h = MacHost;
let front_before = h.foreground();
let t0 = Instant::now();
let args = vec![format!("--user-data-dir={profile}"), "--remote-debugging-port=0".into(), "--no-first-run".into(), "--no-default-browser-check".into(), "--window-size=900,600".into(), "about:blank".into()];
let pid = h.spawn_detached(exe, &args, None).expect("spawn");
println!("spawned pid {pid} in {:?}; alive={}", t0.elapsed(), h.alive(pid));
let mut wins = Vec::new();
let deadline = Instant::now() + Duration::from_secs(15);
while Instant::now() < deadline { wins = h.windows_for_pids(&[pid], Some("Chrome_WidgetWin_1")); if !wins.is_empty() { break; } std::thread::sleep(Duration::from_millis(100)); }
println!("windows for pid after {:?}: {:?}", t0.elapsed(), wins.iter().map(|w| (w.hwnd, &w.class, w.rect, w.visible)).collect::<Vec<_>>());
let front_after = h.foreground();
println!("foreground before={front_before} after={front_after} (stolen={})", wins.iter().any(|w| w.hwnd == front_after));
let Some(w) = wins.first() else { h.kill(pid); return; };
println!("tag: {} has_tag: {}", h.tag(w.hwnd, "AdomPupSid=probe"), h.has_tag(w.hwnd, "AdomPupSid=probe"));
println!("park (hide): {}", h.send_to_bottom_no_activate(w.hwnd));
std::thread::sleep(Duration::from_millis(300));
let hidden_rows = h.windows_for_pids(&[pid], Some("Chrome_WidgetWin_1"));
println!("after hide: found={} visible={:?} is_alive={}", hidden_rows.len(), hidden_rows.iter().map(|w| w.visible).collect::<Vec<_>>(), h.is_alive(w.hwnd));
println!("set_bounds (AX): {}", h.set_bounds_no_activate(w.hwnd, 40, 60, 800, 500));
println!("unhide (no activate): {}", h.set_visible_no_activate(w.hwnd, true));
std::thread::sleep(Duration::from_millis(300));
println!("foreground now={} (ours={})", h.foreground(), h.foreground() == w.hwnd);
println!("idle_ms={:?} work_area={:?}", h.idle_ms(), h.work_area());
println!("kill: {}", h.kill(pid));
std::thread::sleep(Duration::from_millis(500));
println!("alive after kill: {} window alive: {}", h.alive(pid), h.is_alive(w.hwnd));
}