← Commit history
v0.1.2/ext0.1.1: badge the correct-profile window via BOUNDS correlation (fixes badge landing on the wrong Chrome profile taskbar) + self-heal on list_windows/owned
7 files changed
+38−16
bridge/BRIDGE_VERSION+1−1@@ -1 +1 @@-0.1.1+0.1.2
bridge/bridge.json+2−2@@ -2,8 +2,8 @@ "manifest_version": 1, "name": "native-browser", "displayName": "Adom Native Browser (Chrome + Edge)",- "version": "0.1.1",- "expectedExtensionVersion": "0.1.0",+ "version": "0.1.2",+ "expectedExtensionVersion": "0.1.1", "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.1.1",+ "version": "0.1.2", "private": true, "description": "adom-desktop bridge for the Adom native-browser extension (Chrome + Edge)", "main": "server.js",
bridge/server.js+25−6@@ -448,16 +448,29 @@ function matchHwnd(list, bounds, title) { if (title) { const t = String(title).slice(0, 24); const m = list.find((w) => (w.title || '').includes(t)); if (m) return m.hwnd; } return null; }-// Paint the "Adom is driving" badge on any adopted SPAWNED window in a nbrowser_owned / nbrowser_list_windows-// payload we haven't badged yet — so child/popup windows get the trust tell too, not just open_window.+// (Re)paint the "Adom is driving" badge from a nbrowser_owned / nbrowser_list_windows payload, correlating+// each window's OS hwnd by BOUNDS (profile-independent). This badges adopted SPAWNED windows AND+// SELF-HEALS agent-OPENED windows: if the open-time badge landed on the wrong profile's window (the old+// diff bug), a list call re-correlates by bounds, clears the STALE badge, and paints the correct one. async function badgeSpawnsIn(payload) {- const spawns = [];+ const spawns = []; // { windowId, bounds, title }+ const owned = []; // { sid, bounds, title } if (payload && Array.isArray(payload.spawned)) for (const s of payload.spawned) if (s.kind === 'window' && s.windowId != null) spawns.push({ windowId: s.windowId, bounds: s.bounds, title: s.title });- if (payload && Array.isArray(payload.sessions)) for (const s of payload.sessions) if (s.owner === 'agent-spawned' && s.windowId != null) spawns.push({ windowId: s.windowId, bounds: s.bounds, title: s.url });+ if (payload && Array.isArray(payload.sessions)) for (const s of payload.sessions) {+ if (s.windowId == null) continue;+ if (s.owner === 'agent-spawned') spawns.push({ windowId: s.windowId, bounds: s.bounds, title: s.url });+ else if (s.owner === 'agent-opened' && s.id) owned.push({ sid: s.id, bounds: s.bounds, title: s.url });+ } const fresh = spawns.filter((s) => !spawnHwnd.has(s.windowId));- if (!fresh.length) return;+ if (!fresh.length && !owned.length) return; let list; try { list = await chromeWindowsDetailed(); } catch { return; } for (const s of fresh) { const h = matchHwnd(list, s.bounds, s.title); if (h) { spawnHwnd.set(s.windowId, h); taskbar(h, { overlay: { badge: 'adom', tooltip: 'Adom is driving this browser' } }); } }+ for (const o of owned) {+ const h = matchHwnd(list, o.bounds, o.title);+ if (!h) continue;+ const old = sessionHwnd.get(o.sid);+ if (old !== h) { if (old) taskbar(old, { overlay: { badge: 'none' } }).catch(() => {}); sessionHwnd.set(o.sid, h); lastHwnd = h; taskbar(h, { overlay: { badge: 'adom', tooltip: 'Adom is driving this browser' } }); }+ } } // A "come look" moment = a verb in COMELOOK, OR a semantic signal in the payload that the user should // glance over: an error/refusal, an idle-timeout risk, a human gate (captcha/2FA/login), or fresh spawned@@ -1274,7 +1287,13 @@ async function onHostFrame(frame) { // desktop_screenshot_window (the window+chrome+child-popup capture technique). let neu = null; for (let i = 0; i < 4; i++) {- try { const after = await chromeHwnds(); neu = [...after].find((h) => !preOpenHwnds.has(h)) || null; } catch {}+ try {+ const list = await chromeWindowsDetailed();+ // Correlate by BOUNDS first (profile-independent + precise — the new-window DIFF can't tell+ // profiles apart and badged the WRONG profile's taskbar button). Diff only as a fallback.+ if (payload.bounds) neu = matchHwnd(list, payload.bounds, null);+ if (!neu) neu = list.map((w) => w.hwnd).find((h) => !preOpenHwnds.has(h)) || null;+ } catch {} if (neu) { lastHwnd = neu; if (sid) sessionHwnd.set(sid, neu); taskbar(neu, { overlay: { badge: 'adom', tooltip: 'Adom is driving this browser' } }); break; } await new Promise((r) => setTimeout(r, 250)); }
extension/manifest.json+1−1@@ -2,7 +2,7 @@ "manifest_version": 3, "name": "Adom for Chrome & Edge", "short_name": "Adom",- "version": "0.1.0",+ "version": "0.1.1", "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/native.js+4−1@@ -497,8 +497,11 @@ export async function openWindow(args = {}) { await persist(); const warn = await enforceBackground(win.id, args, 'nbrowser_open_window', prev); // backstop: never leaves it topmost const tab = (win.tabs && win.tabs[0]) || {};+ // Return the window's BOUNDS so the bridge can correlate its OS hwnd by rect (profile-independent) for+ // the taskbar badge — the old "new Chrome window" diff can't tell profiles apart and badged the wrong one.+ let bounds; try { const w2 = await chrome.windows.get(win.id); bounds = { left: w2.left, top: w2.top, width: w2.width, height: w2.height }; } catch { bounds = { left: win.left, top: win.top, width: win.width, height: win.height }; } const res = {- ok: true, sessionId: sid, tabId: String(tab.id), windowId: win.id, url: tab.url || args.url,+ ok: true, sessionId: sid, tabId: String(tab.id), windowId: win.id, url: tab.url || args.url, bounds, _hint: 'New window opened in the BACKGROUND — the user\'s focus is deliberately NOT stolen. ' + POLITE_HINT + ' Screenshot it where it sits with nbrowser_screenshot (CDP) or AD desktop_screenshot_window (WGC); both capture a background/occluded window, so NEVER foreground it to grab a shot. To raise it you must justify it (userRequestedForeground:true + foregroundReason) AND warn the user first. Remember to nbrowser_close_window {sessionId:"' + sid + '"} when done so you don\'t leave abandoned windows.', };
native-browser-bridge-manifest.json+4−4@@ -1,8 +1,8 @@ { "manifest_version": 1,- "version": "0.1.1",- "url": "https://wiki.adom.inc/download/adom/adom-browser-extension/0.1.1/native-browser-bridge-v0.1.1.bin",- "sha256": "5412f87a9f81ee457f4c2315dba5ad464446b33f600adeb260b1df64013b39e9",- "size": 53513,+ "version": "0.1.2",+ "url": "https://wiki.adom.inc/download/adom/adom-browser-extension/0.1.2/native-browser-bridge-v0.1.2.bin",+ "sha256": "0742cfbb954e12600a8bc453401d88881dc636fc9da5aa95636151c06671e84c",+ "size": 53867, "released_at": "2026-07-14T00:00:00Z" }