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.634 (insiders): background windows proven: default ext lane gets --no-startup-window + --keep-alive-for-test (was…
3fcc8b8
1mo ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
//! Z-order doctrine from Node (v1.9.181 userIsUsingWindow, v2.0.26/2.0.27 osBottomUnlessForeground,
//! v2.0.261 birth grace). pup must NEVER pull a window out from under the user: every re-park after a
//! navigation, reload, view switch or recording asks first whether the user is using the window.
//! A newborn window (8 s, no granted raise) cannot be "in use": Chrome self-activates a new window and
//! the user's typing is not a click on a taskbar button that did not exist yet, so it is bottomed.
//! Missing from the Rust port until 2.0.426 (John, 2026-09-06: "you seem to be acting odd").
use crate::Ctx;
pub const BIRTH_GRACE_MS: u64 = 8_000;
const USER_MEMORY_MS: u64 = 10 * 60_000;
pub fn in_birth_grace(s: &pup_session::Session) -> bool { !s.raise_granted && pup_core::now_ms().saturating_sub(s.born_at_ms) < BIRTH_GRACE_MS }
pub fn user_is_using(s: &pup_session::Session) -> bool {
if in_birth_grace(s) { return false; }
s.foreground || (s.user_active_at_ms > 0 && pup_core::now_ms().saturating_sub(s.user_active_at_ms) < USER_MEMORY_MS)
}
/// Node osBottomUnlessForeground. Returns "bottomed" | "foreground" | "user-foreground" | "no-hwnd".
pub fn bottom_unless_foreground(ctx: &Ctx, sid: &str, force: bool) -> &'static str {
let Some(s) = ctx.sessions.get(sid) else { return "no-hwnd" };
let Some(h) = s.hwnd else { return "no-hwnd" };
let fg = ctx.host.foreground();
if fg == h && fg != 0 {
if !force { return "foreground"; }
// 2.0.584 (John: "within like 200ms a human might click the windows taskbar icon"): the birth grace may
// override the session FLAGS (they lag), never INPUT. A programmatic self-raise happens with idle hands
// (the 2.0.26 insight); keyboard or mouse activity in the last 5 s is a person, grace or not. Before
// this, a taskbar click inside the first 8 s was undone by the +2.5 s re-assert.
// 2.0.588 (John: "you cannot fuck over the user if they bring it to the foreground to look at it"): a pup
// window that IS the foreground belongs to the user, full stop, and READING it involves no input, so the
// 5 s idle rule must never expire that. The only self-raise pup may undo is a NEWBORN's (Chrome's first
// paint or a PDF viewer) with idle hands inside the birth grace. Everything else: hands off, and remember
// it for 10 minutes so the re-asserts that follow stay off too.
// 2.0.589 (John: "a user could click the windows taskbar icon within 200ms"): no magic idle number.
// Inside the birth grace pup may demote ONLY when nobody has touched the machine since the window
// was born (so the raise was Chrome's), and only on the CDP lane, where Chrome self-activates a
// newborn at all (an extension-lane window is created unfocused and never does). Any input since
// birth, a click at 200 ms included, means a person: hands off, remembered for 10 minutes, and a
// remembered person stays a person for the rest of the grace even while they read without input.
let idle = ctx.host.idle_ms().unwrap_or(u64::MAX);
let since_birth = pup_core::now_ms().saturating_sub(s.born_at_ms);
let remembered = s.user_active_at_ms > 0 && pup_core::now_ms().saturating_sub(s.user_active_at_ms) < USER_MEMORY_MS;
// 2.0.628: the extension lane is no longer excluded. The exclusion rested on "Chrome never self-activates
// an unfocused-created window on this lane", which is true for a warm birth and FALSE for the first
// window of a freshly started browser: measured 2026-09-18, the cold-birth re-assert answered
// "foreground" with no input since birth, while a Notepad window held the keyboard a second earlier.
// The idle-hands rule is lane-independent: no input since birth means Chrome raised it, not a person.
let chrome_self_raise = in_birth_grace(&s) && !remembered && idle >= since_birth;
if chrome_self_raise {
pup_core::log(format!("[park] \"{sid}\" is foreground {since_birth} ms after birth with no input since birth: Chrome's self-raise, bottoming"));
} else {
ctx.sessions.with_mut(sid, |x| x.user_active_at_ms = pup_core::now_ms());
if in_birth_grace(&s) { pup_core::log(format!("[park] \"{sid}\" is foreground inside the birth grace with input {idle} ms ago: a person raised it, hands off")); }
return "user-foreground";
}
}
ctx.host.send_to_bottom_no_activate(h);
"bottomed"
}