← Commit history
0.3.4: bound the optional screenshot leg so nbrowser_state can never hang the caller
5 files changed
+18−11
bridge/BRIDGE_VERSION+1−1@@ -1 +1 @@-0.3.3+0.3.4
bridge/bridge.json+1−1@@ -2,7 +2,7 @@ "manifest_version": 1, "name": "native-browser", "displayName": "Adom Native Browser",- "version": "0.3.3",+ "version": "0.3.4", "expectedExtensionVersion": "0.2.0", "description": "Drives the user's REAL signed-in Chrome/Edge, in two layers. Layer 1 (nb) needs NOTHING installed and works on any machine: nbrowser_open_os_window (open a URL in the user's real profile, background+flashing, the OAuth/consent path), nbrowser_os_windows, nbrowser_profiles, nbrowser_wake_profile, nbrowser_force_close. Layer 2 (nbe, the Adom Native Browser Extension) unlocks the rest: CDP driving (navigate/click/read/screenshot) inside their logged-in profile. The bridge binds an ephemeral loopback port and the native-messaging host pumps stdio <-> bridge.", "homepage": "https://wiki.adom.inc/adom/nb-bridge",
bridge/package.json+1−1@@ -1,6 +1,6 @@ { "name": "adom-native-browser-bridge",- "version": "0.3.3",+ "version": "0.3.4", "private": true, "description": "Native-browser bridge for Bridge (ab): layer 1 (nb) plus layer 2 via nbe, the Adom Native Browser Extension (Chrome + Edge).", "main": "server.js",
bridge/server.js+10−3@@ -1882,14 +1882,21 @@ function dispatch(verb, args) { const sessions = (sa.all === true ? rows : rows.filter((r) => r.alive && r.yours)) .filter((r) => !want || r.sessionId === want); const hidden = rows.length - sessions.length;- let shot = null;+ // The optional bitmap must never be able to hang the whole call: a session whose window died+ // makes screenshot wait out its own budget, and the caller's CLI dies at 30s having learned+ // NOTHING - the exact failure mode issue #22 is about. Bound it and degrade to state-only.+ let shot = null, shotError = null; const shotSid = want || (sessions[0] && sessions[0].sessionId); if (sa.screenshot && shotSid) {- const s = await callSelf('nbrowser_screenshot', { sessionId: shotSid });+ const s = await Promise.race([+ callSelf('nbrowser_screenshot', { sessionId: shotSid }),+ new Promise((r) => setTimeout(() => r({ __timeout: true }), Math.min(Number(sa.screenshotTimeoutMs) || 8000, 20000))),+ ]); if (s && s.base64) shot = { sessionId: shotSid, base64: s.base64, width: s.width, height: s.height };+ else shotError = s && s.__timeout ? `screenshot of '${shotSid}' timed out - state returned without it` : (s && s.error) || 'screenshot unavailable'; } resolve({ success: true, output: JSON.stringify({ ok: true, count: sessions.length, sessions, screenshot: shot,- hiddenCount: hidden,+ hiddenCount: hidden, screenshotError: shotError, _hint: sessions.length ? `The EXACT windows THIS bridge opened for YOU${hidden ? ` (${hidden} other/dead session(s) hidden - pass all:true to see every tracked session with owner + alive flags)` : ''} - hwnd is authoritative, so never match a browser window by TITLE (a title is the active tab, it changes while loading, and several windows share substrings - that is what broke the web-control demo, issue #22). The user's OWN windows are deliberately excluded (nbrowser_os_windows shows every browser window on the machine, with ownership attribution). screenshot:true returns the page bitmap inline in this same call.` : `This bridge is driving NO live windows for you right now${hidden ? ` (${hidden} tracked session(s) belong to other threads or are dead - all:true to inspect)` : ''}. Open one with nbrowser_open_window {sessionId, thread, purpose, profile, url} - it returns the hwnd + tabId of exactly that window.` }) });
native-browser-bridge-manifest.json+5−5@@ -1,8 +1,8 @@ { "manifest_version": 1,- "version": "0.3.3",- "url": "https://wiki.adom.inc/download/adom/nb-bridge/0.3.3/native-browser-bridge-v0.3.3.zip",- "sha256": "f5093fba6e21a23392d10dac1716bb0702d77f1efacceca604243befd80c902e",- "size": 106751,- "released_at": "2026-08-19T08:23:02Z"+ "version": "0.3.4",+ "url": "https://wiki.adom.inc/download/adom/nb-bridge/0.3.4/native-browser-bridge-v0.3.4.zip",+ "sha256": "3ca007845a04ab9d73ec2327ef9387c090f4cb7cbda336386854b1fb79b1c963",+ "size": 107028,+ "released_at": "2026-08-19T08:24:41Z" }