← Commit history
v0.0.36/0.0.20: focus-emulation fixes background clicking on occluded windows (was silently landing nowhere) + select readback polish
6 files changed
+20−10
bridge/BRIDGE_VERSION+1−1@@ -1 +1 @@-0.0.35+0.0.36
bridge/bridge.json+2−2@@ -2,8 +2,8 @@ "manifest_version": 1, "name": "native-browser", "displayName": "Adom Native Browser (Chrome + Edge)",- "version": "0.0.35",- "expectedExtensionVersion": "0.0.19",+ "version": "0.0.36",+ "expectedExtensionVersion": "0.0.20", "description": "Drives the user's REAL signed-in Chrome/Edge via an installed extension (native-messaging transport). Mirrors the puppeteer bridge's verb surface as nbrowser_* but runs inside the actual logged-in profile, so cookies/SSO/saved-logins/captcha human-trust all work. The bridge binds an ephemeral loopback port (PORTS.md compliant) and writes a discovery file; the native-messaging host pumps stdio <-> this bridge; the extension never touches a TCP port.", "homepage": "https://wiki.adom.inc/adom/adom-browser-extension", "author": "Adom Inc.",
bridge/package.json+1−1@@ -1,6 +1,6 @@ { "name": "adom-native-browser-bridge",- "version": "0.0.35",+ "version": "0.0.36", "private": true, "description": "adom-desktop bridge for the Adom native-browser extension (Chrome + Edge)", "main": "server.js",
extension/manifest.json+1−1@@ -2,7 +2,7 @@ "manifest_version": 3, "name": "Adom for Chrome & Edge", "short_name": "Adom",- "version": "0.0.19",+ "version": "0.0.20", "description": "Drive your real, logged-in Chrome/Edge from the Adom ecosystem \u2014 the native-browser counterpart to pup.", "minimum_chrome_version": "116", "background": {
extension/src/cdp.js+12−2@@ -42,6 +42,12 @@ async function attach(tabId) { await send(tabId, 'Page.enable').catch(() => {}); await send(tabId, 'Runtime.enable').catch(() => {}); await send(tabId, 'Log.enable').catch(() => {});+ // CRITICAL for BACKGROUND clicking: a window fully occluded by another (e.g. the user's maximized+ // window over our background one) is marked hidden by Chrome's native-occlusion tracking, so+ // Input.dispatchMouseEvent stops hit-testing and clicks silently land NOWHERE (eval/screenshot still+ // work - they don't need a hit-testable frame). Emulating focus makes the page behave as focused+visible+ // so isTrusted CDP input lands, WITHOUT ever raising the window (stays background, no focus theft).+ await send(tabId, 'Emulation.setFocusEmulationEnabled', { enabled: true }).catch(() => {}); bumpIdle(tabId); } @@ -388,7 +394,10 @@ function selectTriggerFn(label, near) { } if (!cand) return { found: false }; var r = cand.getBoundingClientRect();- return { found: true, x: Math.round(r.left + r.width / 2), y: Math.round(r.top + r.height / 2), tag: cand.tagName.toLowerCase(), isNativeSelect: cand.tagName.toLowerCase() === 'select', current: txt(cand).slice(0, 120) };+ // `display` = the trigger's now-VISIBLE text (what a human sees selected), preferred for the readback.+ // `current` = its accessible name (aria-label/title/placeholder, used for finding) - kept as fallback.+ var disp = ((cand.innerText || cand.textContent || '') + '').replace(/\s+/g, ' ').trim();+ return { found: true, x: Math.round(r.left + r.width / 2), y: Math.round(r.top + r.height / 2), tag: cand.tagName.toLowerCase(), isNativeSelect: cand.tagName.toLowerCase() === 'select', current: txt(cand).slice(0, 120), display: disp.slice(0, 120) }; } function nativeSetFn(x, y, optionText) { var el = document.elementFromPoint(x, y); while (el && el.tagName !== 'SELECT') el = el.parentElement;@@ -433,7 +442,8 @@ export async function selectOption(tabId, args) { await mouseClick(tabId, opt.x, opt.y); // pick (isTrusted) await new Promise((r) => setTimeout(r, 220)); const after = await inj(selectTriggerFn, [args.label || '', args.near || '']);- const selected = (after && after.found && after.current) ? after.current : opt.text;+ // Prefer the trigger's now-visible display text; fall back to the option we clicked.+ const selected = (after && after.found && (after.display || after.current)) || opt.text; return { ok: true, selected, matchedExact: opt.exact, clickedText: opt.text, via: 'custom-dropdown', _hint: `selected "${selected}". Verify it matches what you intended before continuing.` }; }
native-browser-bridge-manifest.json+3−3@@ -1,8 +1,8 @@ { "manifest_version": 1,- "version": "0.0.35",- "url": "native-browser-bridge-v0.0.35.bin",- "sha256": "d8bb45d1c1932f028ce8a304258cbb713a4b25c25dc74088391ae5e5c58538a5",+ "version": "0.0.36",+ "url": "native-browser-bridge-v0.0.36.bin",+ "sha256": "df7c7006b6de9efedbd4409df3767306d2c971b3717515e9dfc999c44005946e", "size": 43378, "released_at": "2026-07-06T00:00:00Z" }