← Commit history

0.3.4: bound the optional screenshot leg so nbrowser_state can never hang the caller

John Lauer ·eebe98f11f ·2mo ago ·parent 36b4ced
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" }