← Commit history

v1.8.30: run all window-mgmt PowerShell HIDDEN (execFileSync+windowsHide, no cmd shell) so pup never flashes a console; keep off-screen background shown for screenshots

John Lauer ·306bb1075a · ·parent 53714aa
4 files changed +28−17
adom-bridge-puppeteer-manifest.json+5−5
@@ -1,10 +1,10 @@ {   "manifest_version": 1,   "name": "puppeteer",-  "version": "1.8.29",-  "url": "https://wiki.adom.inc/download/adom/adom-desktop-puppeteer-bridge/1.8.29/adom-bridge-puppeteer-v1.8.29.zip",-  "sha256": "93b7def84fe8b2b203ab3ccd37007cf3525ebd7beda73339205543eaf4b22371",-  "size": 155873,+  "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,   "verbPrefixes": [     "browser_",     "desktop_recorder_",@@ -12,5 +12,5 @@   ],   "healthEndpoint": "/status",   "statusVerb": "browser_readiness",-  "released_at": "2026-07-14T19:10:42Z"+  "released_at": "2026-07-14T19:17:21Z" }\ No newline at end of file
src/BRIDGE_VERSION+1−1
@@ -1 +1 @@-1.8.29+1.8.30
src/bridge.json+1−1
@@ -2,7 +2,7 @@   "manifest_version": 1,   "name": "puppeteer",   "displayName": "Puppeteer (Chrome for Testing + Native)",-  "version": "1.8.29",+  "version": "1.8.30",   "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+21−10
@@ -6,7 +6,17 @@ const http = require('http'); const fs = require('fs'); const path = require('path'); const os = require('os');-const { execSync } = require('child_process');+const { execSync, execFileSync, execFile } = require('child_process');+// v1.8.29: run a PowerShell script file with NO console window (windowsHide) and no cmd+// shell (execFileSync directly), so pup's window-management PS never flashes a terminal on+// the user's screen. -WindowStyle Hidden is belt-and-suspenders. Sync variant returns stdout.+function runPsHidden(scriptPath, { timeout = 6000 } = {}) {+  return execFileSync('powershell.exe', ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-WindowStyle', 'Hidden', '-File', scriptPath], { encoding: 'utf8', timeout, windowsHide: true });+}+// Fire-and-forget async variant (never blocks the driving verb).+function runPsHiddenAsync(scriptPath, { timeout = 6000 } = {}) {+  execFile('powershell.exe', ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-WindowStyle', 'Hidden', '-File', scriptPath], { timeout, windowsHide: true }, () => {});+} const puppeteer = require('puppeteer'); const credentialVault = require('./credential_vault'); const chrome = require('./chrome'); // Chrome-for-Testing self-heal: detect / auto-install / readiness (cold-start fix)@@ -1486,7 +1496,7 @@ function osSendWindowToBack(profileName) {       'Write-Output "bg"',     ].join('\r\n');     fs.writeFileSync(psScript, ps);-    execSync(`powershell.exe -NoProfile -ExecutionPolicy Bypass -File "${psScript}"`, { timeout: 6000 });+    runPsHidden(psScript);     return true;   } catch (e) { console.error(`[bg] send-to-back failed for "${profileName}": ${e.message}`); return false; } }@@ -1535,13 +1545,14 @@ 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.       'foreach($h in $handles){',-      // v1.8.29: just MINIMIZE and leave it — the window is already OFF-SCREEN, so it's-      // invisible either way, and minimizing is the one action that reliably makes Windows-      // hand foreground back to the user (no re-show for the browser to re-grab focus on).-      // CDP screenshots keep working because pup runs the renderer with anti-throttle flags-      // (--disable-backgrounding-occluded-windows etc.), so the page still paints minimized.       '  [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',       '}',       // Verify: is any pup window STILL the foreground window?       '$fg = [WinBgP]::GetForegroundWindow()',@@ -1550,7 +1561,7 @@ function osBackgroundWindowByPid(pid, cdpPort) {       'if ($stillFg) { Write-Output "still-foreground" } else { Write-Output "backgrounded" }',     ].join('\r\n');     fs.writeFileSync(scriptPath, ps);-    const out = execSync(`powershell.exe -NoProfile -ExecutionPolicy Bypass -File "${scriptPath}"`, { encoding: 'utf8', timeout: 6000 }).trim();+    const out = runPsHidden(scriptPath).trim();     return out || 'error';   } catch (e) { console.error(`[bg] pid ${pid} port ${cdpPort}: ${e.message}`); return 'error'; } }@@ -1594,7 +1605,7 @@ function osFlashWindow(profileName) {       'else { Get-CimInstance Win32_Process -Filter "ParentProcessId=$targetPid" -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) { [WinFlash]::Flash($cp.MainWindowHandle) } } }',     ].join('\r\n');     fs.writeFileSync(psScript, ps);-    exec(`powershell.exe -NoProfile -ExecutionPolicy Bypass -File "${psScript}"`, { timeout: 6000 }, () => {});+    runPsHiddenAsync(psScript);   } catch (e) {} } @@ -3381,7 +3392,7 @@ const server = http.createServer(async (req, res) => {               ].join('\r\n');               fs.writeFileSync(psScript, psContent);               try {-                const result = execSync(`powershell.exe -NoProfile -ExecutionPolicy Bypass -File "${psScript}"`, { timeout: 8000 }).toString().trim();+                const result = runPsHidden(psScript, { timeout: 8000 }).toString().trim();                 console.log(`Focused session "${sessionId}" via SetForegroundWindow: ${result}`);               } catch (e) {                 console.error(`SetForegroundWindow failed for session "${sessionId}":`, e.message);