← Commit history

v1.8.31: park background window ON-SCREEN sized-to-monitor at z-bottom (behind user windows, invisible, but clickable via taskbar); single background retry to avoid flicker

John Lauer ·337b651c26 · ·parent 306bb10
4 files changed +22−18
adom-bridge-puppeteer-manifest.json+5−5
@@ -1,10 +1,10 @@ {   "manifest_version": 1,   "name": "puppeteer",-  "version": "1.8.30",-  "url": "https://wiki.adom.inc/download/adom/adom-desktop-puppeteer-bridge/1.8.30/adom-bridge-puppeteer-v1.8.30.zip",-  "sha256": "81b800e7772043cf18ae1e95aee21328db99ce4cd8861d99d2a4e940989336de",-  "size": 156021,+  "version": "1.8.31",+  "url": "https://wiki.adom.inc/download/adom/adom-desktop-puppeteer-bridge/1.8.31/adom-bridge-puppeteer-v1.8.31.zip",+  "sha256": "1fcc521481a903860af1dbf241057680e1ac60faa2da95147c8c105504c76d38",+  "size": 156260,   "verbPrefixes": [     "browser_",     "desktop_recorder_",@@ -12,5 +12,5 @@   ],   "healthEndpoint": "/status",   "statusVerb": "browser_readiness",-  "released_at": "2026-07-14T19:17:21Z"+  "released_at": "2026-07-14T19:40:23Z" }\ No newline at end of file
src/BRIDGE_VERSION+1−1
@@ -1 +1 @@-1.8.30+1.8.31
src/bridge.json+1−1
@@ -2,7 +2,7 @@   "manifest_version": 1,   "name": "puppeteer",   "displayName": "Puppeteer (Chrome for Testing + Native)",-  "version": "1.8.30",+  "version": "1.8.31",   "description": "Drives a browser ALREADY on the machine — installed Chrome, else Microsoft Edge (every Windows PC ships with Edge) — 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 → Edge → 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. browser_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. browser_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, …). 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 — 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 — a separate bridge, not pup's job.",   "homepage": "https://wiki.adom.inc/adom/adom-desktop",   "author": "Adom Inc.",
src/server.js+15−11
@@ -1525,12 +1525,15 @@ function osBackgroundWindowByPid(pid, cdpPort) {       '  [DllImport("user32.dll")] public static extern bool SetWindowPos(IntPtr h, IntPtr a, int x, int y, int cx, int cy, uint f);',       '  [DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr h, int n);',       '  [DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow();',+      '  [DllImport("user32.dll")] public static extern int GetSystemMetrics(int i);',       '}',       '"@',       `$targetPid = ${Number(pid) || 0}`,       `$cdpPort = ${port}`,       '$BOTTOM = [IntPtr]1',                 // HWND_BOTTOM-      '$SWP = 0x1 -bor 0x2 -bor 0x10',       // SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE+      '$SWP = 0x10',                          // SWP_NOACTIVATE (allow move+size)+      '$scrW = [WinBgP]::GetSystemMetrics(0)', // SM_CXSCREEN (primary monitor)+      '$scrH = [WinBgP]::GetSystemMetrics(1)', // SM_CYSCREEN       '$SW_MINIMIZE = 6',       '$SW_SHOWNOACTIVATE = 4',       '$handles = New-Object System.Collections.ArrayList',@@ -1545,14 +1548,16 @@ function osBackgroundWindowByPid(pid, cdpPort) {       '  Get-CimInstance Win32_Process -Filter "ParentProcessId=$tp" -ErrorAction SilentlyContinue | Where-Object { $_.Name -in @("chrome.exe","msedge.exe") } | ForEach-Object { $cp = Get-Process -Id $_.ProcessId -ErrorAction SilentlyContinue; if ($cp -and $cp.MainWindowHandle -ne 0) { [void]$handles.Add($cp.MainWindowHandle) } }',       '}',       'if ($handles.Count -eq 0) { Write-Output "no-window"; exit }',-      // The window is OFF-SCREEN (invisible). Minimize drops any foreground it grabbed on-      // launch (Windows hands focus back to the user), then re-show WITHOUT activating so it-      // still composites for CDP screenshots (minimized windows stop compositing and time-      // screenshots out), and pin to z-bottom.+      // The window launched OFF-SCREEN (so nothing ever popped up on the user's monitor).+      // Now: minimize to drop any foreground it grabbed (Windows hands focus back to the+      // user), re-show WITHOUT activating (minimized windows stop compositing → screenshots+      // time out, so it must stay shown), then MOVE it ON-SCREEN sized to the monitor at the+      // BOTTOM of the z-order. Result: fully behind the user's windows (invisible, never+      // covering) BUT reachable — its taskbar button brings it up on click, like any window.       'foreach($h in $handles){',       '  [WinBgP]::ShowWindow($h, $SW_MINIMIZE) | Out-Null',       '  [WinBgP]::ShowWindow($h, $SW_SHOWNOACTIVATE) | Out-Null',-      '  [WinBgP]::SetWindowPos($h, $BOTTOM, 0,0,0,0, $SWP) | Out-Null',+      '  [WinBgP]::SetWindowPos($h, $BOTTOM, 0, 0, $scrW, $scrH, $SWP) | Out-Null',       '}',       // Verify: is any pup window STILL the foreground window?       '$fg = [WinBgP]::GetForegroundWindow()',@@ -1940,11 +1945,10 @@ async function getOrLaunchBrowser(profileName, { freshProfile = false, strictPer       if (!foreground && process.platform === 'win32') {         b._bgResult = osBackgroundWindowByPid(child.pid, debugPort);         console.log(`[bg] initial background result for "${profileName}": ${b._bgResult}`);-        // Retry a few times: Chrome/Edge can re-raise itself during startup (first paint,-        // restore prompts). Each retry re-verifies and updates the recorded result.-        for (const delay of [250, 700, 1500]) {-          setTimeout(() => { try { b._bgResult = osBackgroundWindowByPid(child.pid, debugPort); } catch (e) {} }, delay);-        }+        // ONE late retry (Chrome/Edge can re-raise itself right after first paint). Keep it+        // to a single pass — each pass does a minimize/re-show, which on an on-screen window+        // is a visible flicker, so we don't want a burst of them.+        setTimeout(() => { try { b._bgResult = osBackgroundWindowByPid(child.pid, debugPort); } catch (e) {} }, 800);       }       return b;     };