← Commit history

Clear-flashes actually clears now + favicon cache-bust (John: 'i just hit clear flashes and it didn't clear all your flashes. have you truly done full ralph testing of yourself?'). Honest answer was no - the ralph test read ok:true from the flash actions but never verified the taskbar effect. ROOT CAUSE, same disease as the badge saga: flashViaAD addressed windows by TITLE tag, so a stop silently no-oped on any window whose title lacked the tag (PDF viewer, retitled pages) - and FlashWindowEx keeps a button orange until a FLASHW_STOP reaches that exact HWND, so those stayed lit forever. Fixes: (1) flashViaAD resolves the session's HWND (same resolver as the badge paint) and addresses flash/stop by hwnd, title only as fallback; (2) pup REMEMBERS every hwnd it ever flashed this boot (_flashedHwnds) and clear-flashes sweeps a stop to ALL of them, catching windows whose session closed or retitled after flashing; (3) the ralph test now asserts the EFFECT: flashedPending (exposed in the snapshot) must drop to 0 after unflash-all, not just ok:true. Also: the dashboard favicon link is now versioned (?v=BRIDGE_VERSION) - the new adom-ui-design favicon shipped in 1.9.239 but Chrome's favicon cache kept showing the old two-dots tile because the URL never changed; every ship now busts it.

John Lauer ·ca8f72df40 ·2mo ago ·parent 8ba2b0e
4 files changed +29−11
adom-bridge-puppeteer-manifest.json+4−4
@@ -1,10 +1,10 @@ {   "manifest_version": 1,   "name": "puppeteer",-  "version": "1.9.241",-  "url": "https://wiki.adom.inc/download/adom/adom-desktop-puppeteer-bridge/1.9.241/adom-bridge-puppeteer-v1.9.241.zip",-  "sha256": "9a4029ac624f9faf9e0b08657281c2d3e379b5e2a56230478251e5e80d232a4d",-  "size": 464209,+  "version": "1.9.242",+  "url": "https://wiki.adom.inc/download/adom/adom-desktop-puppeteer-bridge/1.9.242/adom-bridge-puppeteer-v1.9.242.zip",+  "sha256": "9e721e55a955cdaf3a558725249c94ecae6cc5324ef8dfb9713dd4e068a0b718",+  "size": 464814,   "verbPrefixes": [     "browser_",     "desktop_recorder_",
src/BRIDGE_VERSION+1−1
@@ -1 +1 @@-1.9.241+1.9.242
src/bridge.json+1−1
@@ -2,7 +2,7 @@   "manifest_version": 1,   "name": "puppeteer",   "displayName": "Puppeteer (Chrome for Testing + Native)",-  "version": "1.9.241",+  "version": "1.9.242",   "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. 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, \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, browser_alert_window posts a native toast whose click focuses the window, browser_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-desktop",   "author": "Adom Inc.",
src/server.js+23−5
@@ -5942,12 +5942,21 @@ async function flashViaAD(sessionId, opts) {   if (minimalTouch() && !(opts && opts.force)) return;   opts = opts || {};   if (process.platform !== 'win32' || !sessionId) return null;-  const args = opts.stop-    ? { titleContains: `(session: ${sessionId}`, stop: true }-    : { titleContains: `(session: ${sessionId}`, mode: 'count', count: 4 };+  // v1.9.242 (John: "i just hit 'clear flashes' and it didn't clear all your flashes"). Same disease+  // as the badge saga: targeting by TITLE tag silently no-ops on any window whose title can't carry+  // it (PDF viewer, retitled pages) — and FlashWindowEx leaves the button highlighted until a STOP+  // reaches that exact HWND. So: resolve the hwnd (same resolver the badge paint uses), address by+  // hwnd with title as fallback only, and REMEMBER every hwnd we ever flashed so clear-all can sweep+  // them even if the session is gone or retitled by then.+  const session = sessions.get(sessionId);+  if (session && !session._hwnd) { try { await resolveSessionHwndByBounds(session, sessionId); } catch (e) {} }+  const tgt = (session && session._hwnd) ? { hwnd: session._hwnd } : { titleContains: `(session: ${sessionId}` };+  if (!opts.stop && session && session._hwnd) _flashedHwnds.add(session._hwnd);+  const args = opts.stop ? { ...tgt, stop: true } : { ...tgt, mode: 'count', count: 4 };   try { return await chrome.adCommand('desktop_flash_window', args, { timeoutMs: 6000 }); }   catch (e) { return null; } }+const _flashedHwnds = new Set(); // every hwnd pup ever flashed this boot — the clear-all sweep list  // v1.8.23: verbs that MUTATE a session's visible state → auto-flash the window so the // user knows the agent changed it. evaluate counts UNLESS {readOnly:true}.@@ -8013,7 +8022,7 @@ async function dashboardSnapshot() {   let depsOk = false; try { require.resolve('puppeteer'); depsOk = true; } catch (e) {}   return {     ts: now,-    bridge: { version: BRIDGE_VERSION, platform: process.platform, uptimeMs: Math.round(process.uptime() * 1000), depsOk, minimalTouch: minimalTouch() },+    bridge: { version: BRIDGE_VERSION, platform: process.platform, uptimeMs: Math.round(process.uptime() * 1000), depsOk, minimalTouch: minimalTouch(), flashedPending: _flashedHwnds.size },     counts: { windows: wins.length, tabs: wins.reduce((a, w) => a + w.tabCount, 0), browsers: browsers.size, threads: threads.length },     threads, profiles,     taskbarButtons: [...buttons.values()],@@ -8027,7 +8036,7 @@ async function dashboardSnapshot() { const DASHBOARD_HTML = `<!doctype html><html lang="en"><head> <meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"> <title>pup live windows</title>-<link rel="icon" type="image/svg+xml" href="/dashboard/icon.svg">+<link rel="icon" type="image/svg+xml" href="/dashboard/icon.svg?v=${BRIDGE_VERSION}"> <style> *{box-sizing:border-box} html,body{margin:0;background:#0b1116;color:#e6edf3;font:14px/1.5 "Segoe UI",system-ui,sans-serif} a{color:#12e0c4}@@ -8336,6 +8345,15 @@ const server = http.createServer(async (req, res) => {         if (act === 'flash-all' || act === 'unflash-all') {           const stop = act === 'unflash-all';           for (const id of [...sessions.keys()]) { try { await flashViaAD(id, stop ? { stop: true, force: true } : { force: true }); } catch (e) {} }+          if (stop) {+            // v1.9.242: ALSO sweep every hwnd pup ever flashed this boot. A per-session stop misses+            // windows whose session closed/renamed since the flash, and FlashWindowEx keeps those+            // buttons highlighted forever without an explicit stop on that exact hwnd.+            for (const h of [..._flashedHwnds]) {+              try { await chrome.adCommand('desktop_flash_window', { hwnd: h, stop: true }, { timeoutMs: 6000 }); } catch (e) {}+              _flashedHwnds.delete(h);+            }+          }           return done({ ok: true, n: sessions.size });         }         return done({ ok: false, error: 'unknown action' });