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.
← Commit history
v2.0.310: Window identity without PowerShell (John: 'powershell scripts are heavy and slow'): new src/win32.js binds user32 in-process through koffi (prebuilt FFI, no build step): SetProp at the instant of birth (the caller tags the hwnd the moment the sessionId is known, no lazy resolve), GetProp/EnumWindows sweeps for recovery in microseconds, zero process spawns and zero ab calls. PowerShell remains only as the fallback when koffi is unavailable; /status reports win32.inProcess.
4 files changed
+24−7
adom-bridge-puppeteer-manifest.json+5−5@@ -1,10 +1,10 @@ { "manifest_version": 1, "name": "puppeteer",- "version": "2.0.309",- "url": "https://wiki.adom.inc/download/adom/pup-bridge/2.0.309/adom-bridge-puppeteer-v2.0.309.zip",- "sha256": "ed43a34a006fd34a5a12ef7f13beee630d06c29aa577253d380b59dbdc877633",- "size": 1431603,+ "version": "2.0.310",+ "url": "https://wiki.adom.inc/download/adom/pup-bridge/2.0.310/adom-bridge-puppeteer-v2.0.310.zip",+ "sha256": "907e105f7320da04e17a114e3ded40bd4a817aa6810390c3e35f4c83b9a0431b",+ "size": 1435426, "verbPrefixes": [ "browser_", "desktop_recorder_",@@ -12,5 +12,5 @@ ], "healthEndpoint": "/status", "statusVerb": "browser_readiness",- "released_at": "2026-08-23T14:57:58.773179Z"+ "released_at": "2026-08-23T15:07:56.139689Z" }
src/BRIDGE_VERSION+1−1@@ -1 +1 @@-2.0.309+2.0.310
src/bridge.json+1−1@@ -2,7 +2,7 @@ "manifest_version": 1, "name": "puppeteer", "displayName": "Puppeteer (Chrome for Testing + Native)",- "version": "2.0.309",+ "version": "2.0.310", "description": "Drives a browser ALREADY on the machine \u2014 installed Chrome, else Microsoft Edge (every Windows PC ships with Edge) \u2014 launched with a FRESH isolated profile, so the common case has NO ~150 MB Chrome-for-Testing download and it never touches the user's real tabs/logins. Binds its local server to LOOPBACK (127.0.0.1) only, so no Windows Firewall 'allow Node through the firewall' prompt ever pops. Chrome for Testing is fetched only as a LAST RESORT if the machine has no Chromium browser at all. SPAWN-VERIFIED fallback: pup tries each detected browser (Chrome \u2192 Edge \u2192 CfT) and actually launches it, falling through to the next if one won't start (and handling browsers like Edge that relaunch onto another PID), so a corrupt/partial install never hard-fails an open. The browser that launches is cached as the default (persisted across restarts) so it isn't re-probed each time. On spawn the bridge SELF-WARMS: detects browsers + disk, and only if the box has no Chrome/Edge and no cached CfT does it background-fetch CfT so the first open is instant. pup_use pins a specific browser (chrome | edge | cft | auto); {browser:'chrome',install:true} downloads & installs REAL Google Chrome (user-scoped, no admin) on an Edge-only box. pup_readiness (READ-ONLY) reports which browser will be used + the full candidate list + the default + free disk. Every failure returns a specific errorCode + _hint (chrome_install_no_disk, chrome_download_network, chrome_install_permission, chrome_stable_not_detected, \u2026). Launches with FULL browser permissions by default for full debug (strictPermissions:true opts out). Headful automation: open/close windows+tabs, navigate, screenshot, eval JS, record. pup is a GENERIC, non-profile browser only \u2014 every session is a fresh isolated Chrome/Edge process, never the user's real signed-in browser; profile defaults to sessionId. To drive the user's REAL Chrome/Edge (their profile, cookies, SSO), use the Adom browser EXTENSION's nbrowser_* verbs \u2014 a separate bridge, not pup's job. macOS (v1.9.74+): full parity with mac-native mechanics \u2014 background-by-default is the app-level hide (windows stay drivable/screenshottable while hidden), raise/lower map to unhide+activate/hide, pup_alert_window posts a native toast whose click focuses the window, pup_use {browser:'chrome',install:true} installs Chrome from the official dmg, and taskbar identity/badging remains Windows-only.", "homepage": "https://wiki.adom.inc/adom/adom-bridge", "author": "Adom Inc.",
src/server.js+17@@ -5,6 +5,7 @@ const http = require('http'); const fs = require('fs'); const path = require('path');+const win32 = require('./win32'); // v2.0.310: in-process Win32 (SetProp/GetProp/EnumWindows), no PowerShell const os = require('os'); const { execSync, execFileSync, execFile } = require('child_process'); // v1.8.29: run a PowerShell script file with NO console window (windowsHide) and no cmd@@ -517,6 +518,9 @@ function _sanSid(sessionId) { return String(sessionId == null ? '' : sessionId). async function tagWindowSession(hwnd, sessionId) { if (process.platform !== 'win32' || !hwnd || !sessionId) return false; const sid = _sanSid(sessionId);+ // v2.0.310: direct user32 SetProp through koffi; PowerShell below is only the no-koffi fallback.+ const _fast = win32.setProp(hwnd, `${PUP_WIN_PROP}=${sid}`);+ if (_fast !== null) return !!_fast; const ps = `Add-Type @" using System;using System.Runtime.InteropServices; public class PupTag { [DllImport("user32.dll",CharSet=CharSet.Unicode)] public static extern bool SetProp(IntPtr h,string s,IntPtr v); }@@ -534,6 +538,9 @@ Write-Output ok`; async function resolveHwndBySessionProp(sessionId) { if (process.platform !== 'win32' || !sessionId) return null; const sid = _sanSid(sessionId);+ // v2.0.310: one in-process EnumWindows + GetProp sweep (microseconds, no spawn, no ab call).+ const _fastH = win32.findWindowByProp(`${PUP_WIN_PROP}=${sid}`);+ if (_fastH !== null) return _fastH > 0 ? _fastH : null; // v2.0.308: the candidate list used to come from a FRESH ab enum (more enum spam). The property is // the identity, so enumerate locally and read it in the same script: one PowerShell, zero ab calls. const ps = `Add-Type @"@@ -8618,6 +8625,7 @@ function statusCore() { // enum_windows accounting, so "is pup spamming ab?" is answered with a number, not an argument. // lastMin counts REAL ab calls in the last 60s (cache hits and coalesced callers are not counted). enumWindows: { total: _enumCalls, lastMin: (Date.now() - _enumWindow.at < 60000 ? _enumWindow.n : 0) },+ win32: { inProcess: win32.available(), why: win32.why() }, // v2.0.310: koffi loaded? (else PowerShell fallback) // the CURRENT identity mode, so a test harness asserts against what pup IS, not an assumption settings: { taskbarMode: st.aumidIcons !== 'on' ? 'plain' : (st.threadTiles === 'on' ? 'tiles' : 'aumid'),@@ -10832,6 +10840,15 @@ async function launchSession(sessionId, url, { freshProfile = false, profile, st page = await browser.newPage(); page._pupCreated = true; // v1.9.142 }+ // v2.0.310 (John: "immediately associate the chrome uniqueid to the hwnd and SetProp on that+ // window so the association is in memory forever"): the birth capture stashed the hwnd on the+ // page; THIS is the first moment the sessionId is known, so the property goes on right now,+ // in-process (microseconds), not lazily on some later resolve.+ if (page && page.__pupHwnd && process.platform === 'win32') {+ const _tagged = win32.setProp(page.__pupHwnd, `${PUP_WIN_PROP}=${_sanSid(sessionId)}`);+ if (_tagged) console.log(`[hwnd] "${sessionId}" tagged ${page.__pupHwnd} at birth (SetProp, in-process)`);+ else if (_tagged === null) tagWindowSession(page.__pupHwnd, sessionId).catch(() => {}); // koffi unavailable: PowerShell fallback+ } // Always open the welcome page first — it shows session identity (sessionId, // profile, userDataDir) in the tab title and page body so users can tell