← Commit history
0.3.6: demo bounded (never hangs) + skips a pointless 2.4s pre-close
5 files changed
+19−11
bridge/BRIDGE_VERSION+1−1@@ -1 +1 @@-0.3.5+0.3.6
bridge/bridge.json+1−1@@ -2,7 +2,7 @@ "manifest_version": 1, "name": "native-browser", "displayName": "Adom Native Browser",- "version": "0.3.5",+ "version": "0.3.6", "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.5",+ "version": "0.3.6", "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+11−3@@ -1932,15 +1932,23 @@ function dispatch(verb, args) { let profile = da.profile; if (!profile) { const ps = await callSelf('nbrowser_profiles'); const live = (ps.profiles || []).find((p) => p.live && p.email) || (ps.profiles || []).find((p) => p.email); profile = live && live.profile; steps.push({ step: 'resolve profile', ok: !!profile, profile }); } if (!profile) return resolve({ success: false, error: 'no drivable profile found', _hint: 'Run nbrowser_readiness: if state is needs-extension, offer the nbe install (installing-the-extension).', steps });- await callSelf('nbrowser_close_window', { sessionId: sid }); // idempotent re-run+ // idempotent re-run, but only if we actually track it: close_window on an unknown session costs+ // ~2.4s to tell us it is unknown, and a showcase verb should not pay that on every call.+ if (sessionHwnd.has(sid) || sessionProfile.has(sid)) await callSelf('nbrowser_close_window', { sessionId: sid }); const open = await callSelf('nbrowser_open_window', { sessionId: sid, thread: da.thread || 'nbrowser_demo', purpose: 'nb demo: show the AI driving the real signed-in browser', profile, url }); steps.push({ step: 'open in real browser (background)', ok: open.ok === true, hwnd: open.hwnd, tabId: open.tabId }); if (open.ok !== true) return resolve({ success: false, error: open.error || 'open failed', steps }); await new Promise((r) => setTimeout(r, 1200));- const shot = await callSelf('nbrowser_screenshot', { sessionId: sid });- steps.push({ step: 'screenshot the exact window', ok: !!shot.base64, bytes: shot.sizeKB });+ // BOUND the capture: a page still loading (or a window that died) must degrade to "opened, no+ // shot" rather than hanging the caller past its CLI timeout with nothing to show.+ const shot = await Promise.race([+ callSelf('nbrowser_screenshot', { sessionId: sid }),+ new Promise((r) => setTimeout(() => r({ __timeout: true }), Math.min(Number(da.screenshotTimeoutMs) || 12000, 25000))),+ ]);+ steps.push({ step: 'screenshot the exact window', ok: !!shot.base64, bytes: shot.sizeKB, timedOut: !!shot.__timeout }); resolve({ success: true, output: JSON.stringify({ ok: true, sessionId: sid, profile, url, hwnd: open.hwnd || null, tabId: open.tabId || null, base64: shot.base64 || null, width: shot.width, height: shot.height, steps,+ screenshotError: shot.base64 ? null : (shot.__timeout ? 'capture timed out - the window IS open (see hwnd); retry nbrowser_screenshot {sessionId} once it finishes loading' : (shot.error || null)), _hint: `Opened ${url} in the user's REAL signed-in browser (profile ${profile}) in the BACKGROUND, badged as AI-driven, and captured that EXACT window - no title matching anywhere. Render base64 inline. Clean up with nbrowser_close_window {sessionId:"${sid}"} when the demo is done.`, _next: 'nbrowser_close_window' }) }); });
native-browser-bridge-manifest.json+5−5@@ -1,8 +1,8 @@ { "manifest_version": 1,- "version": "0.3.5",- "url": "https://wiki.adom.inc/download/adom/nb-bridge/0.3.5/native-browser-bridge-v0.3.5.zip",- "sha256": "65ebfd4ab939f918ba1dacc894a1b73e62575a709a2d68216c64a267ba6ffc55",- "size": 107771,- "released_at": "2026-08-19T08:49:54Z"+ "version": "0.3.6",+ "url": "https://wiki.adom.inc/download/adom/nb-bridge/0.3.6/native-browser-bridge-v0.3.6.zip",+ "sha256": "b91738dcddd78af2df12ee32da172676bab9c6b1b3d734b050682654f8c90bcf",+ "size": 108026,+ "released_at": "2026-08-19T08:53:31Z" }