← Commit history

v1.8.28: launch background windows OFF-SCREEN (never visually pops/covers user's work); raise repositions on-screen

John Lauer ·9d1598a7ad · ·parent b9418c5
4 files changed +25−8
adom-bridge-puppeteer-manifest.json+5−5
@@ -1,10 +1,10 @@ {   "manifest_version": 1,   "name": "puppeteer",-  "version": "1.8.27",-  "url": "https://wiki.adom.inc/download/adom/adom-desktop-puppeteer-bridge/1.8.27/adom-bridge-puppeteer-v1.8.27.zip",-  "sha256": "4fb299c0a4bd85e4382d69ed1ea1ce2565f644b701122a750cf13b5655319cbd",-  "size": 155251,+  "version": "1.8.28",+  "url": "https://wiki.adom.inc/download/adom/adom-desktop-puppeteer-bridge/1.8.28/adom-bridge-puppeteer-v1.8.28.zip",+  "sha256": "6f157c9b6f668e95e3679cbb8fcee828faf88ab000a9463d812cf189380068dd",+  "size": 155793,   "verbPrefixes": [     "browser_",     "desktop_recorder_",@@ -12,5 +12,5 @@   ],   "healthEndpoint": "/status",   "statusVerb": "browser_readiness",-  "released_at": "2026-07-14T18:54:10Z"+  "released_at": "2026-07-14T18:59:52Z" }\ No newline at end of file
src/BRIDGE_VERSION+1−1
@@ -1 +1 @@-1.8.27+1.8.28
src/bridge.json+1−1
@@ -2,7 +2,7 @@   "manifest_version": 1,   "name": "puppeteer",   "displayName": "Puppeteer (Chrome for Testing + Native)",-  "version": "1.8.27",+  "version": "1.8.28",   "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+18−1
@@ -1847,10 +1847,18 @@ async function getOrLaunchBrowser(profileName, { freshProfile = false, strictPer       // no candidate path was resolved (the no-system-browser edge case).       const chromePath = chromePathArg || puppeteer.executablePath();       const debugPort = 9200 + Math.floor(Math.random() * 800);+      // v1.8.26: BACKGROUND-BY-DEFAULT, done right. Chrome/Edge aggressively grab the+      // foreground on launch (and re-grab it whenever shown), so minimizing/z-ordering+      // AFTER the fact loses the race and the window flashes over the user's work. The+      // reliable fix: launch it OFF-SCREEN (far past any monitor). CDP still renders it,+      // so browser_screenshot/eval/record all work, but the user NEVER sees it pop up and+      // it never covers their active window. foreground:true launches maximized on-screen+      // as before. browser_raise_os_window moves it on-screen when the user asks to watch.       const chromeArgs = [-        ...launchOpts.args.filter(a => a !== '--remote-debugging-port=0'),+        ...launchOpts.args.filter(a => a !== '--remote-debugging-port=0' && (foreground || a !== '--start-maximized')),         `--remote-debugging-port=${debugPort}`,         `--user-data-dir=${userDataDir}`,+        ...(foreground ? [] : ['--window-position=-32000,-32000', '--window-size=1280,800']),       ];       console.log(`Chrome launch attempt ${attemptNum} for profile "${profileName}" on CDP port ${debugPort}`);       const child = spawn(chromePath, chromeArgs, {@@ -3315,6 +3323,15 @@ const server = http.createServer(async (req, res) => {           }           const session = sessions.get(sessionId);           try {+            // v1.8.26: background windows launch OFF-SCREEN (-32000). To actually SHOW one,+            // move it back onto the primary monitor + maximize it (via CDP, no OS activation)+            // BEFORE we foreground it — otherwise "raise" would focus an invisible window.+            try {+              const cdp = await session.page.target().createCDPSession();+              const { windowId } = await cdp.send('Browser.getWindowForTarget');+              await cdp.send('Browser.setWindowBounds', { windowId, bounds: { left: 0, top: 0, width: 1280, height: 800, windowState: 'normal' } });+              await cdp.send('Browser.setWindowBounds', { windowId, bounds: { windowState: 'maximized' } });+            } catch (e) {}             // v1.8.23: BLUR the page's active element BEFORE raising. Raising steals the OS             // focus, and a keystroke the user was mid-typing can land in whatever input the             // pup page had focused (a form field became "John Lauer a"). With no focused