← Commit history
Bridge v0.0.20 (SDK audit): add updateManifestUrl + statusVerb; add read-only nbrowser_readiness (Level-2 needs-extension cold-start probe)
5 files changed
+31−9
bridge/BRIDGE_VERSION+1−1@@ -1 +1 @@-0.0.19+0.0.20
bridge/bridge.json+5−2@@ -2,7 +2,7 @@ "manifest_version": 1, "name": "native-browser", "displayName": "Adom Native Browser (Chrome + Edge)",- "version": "0.0.19",+ "version": "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.",@@ -21,6 +21,7 @@ ], "verbs": [ "nbrowser_status",+ "nbrowser_readiness", "nbrowser_ping", "nbrowser_open_window", "nbrowser_close_window",@@ -90,5 +91,7 @@ "supported": false, "reason": "Pending; bridge + host are OS-agnostic Node, only the install/registration layer is Windows-specific." }- }+ },+ "statusVerb": "nbrowser_status",+ "updateManifestUrl": "https://wiki.adom.inc/api/pages/adom/adom-browser-extension/files/native-browser-bridge-manifest.json" }
bridge/package.json+1−1@@ -1,6 +1,6 @@ { "name": "adom-native-browser-bridge",- "version": "0.0.19",+ "version": "0.0.20", "private": true, "description": "adom-desktop bridge for the Adom native-browser extension (Chrome + Edge)", "main": "server.js",
bridge/server.js+19@@ -405,6 +405,7 @@ function flashHint() { const OWN_ONLY = 'ONLY operate on a window/tab YOU opened via nbrowser_open_window. NEVER navigate/reload/close a window or tab the user already had open - the bridge drives their REAL browser, so you would destroy their live page, forms, sessions, or other AI threads.'; const VERB_META = { nbrowser_status: { hint: 'Connectivity check: connected profiles + active browser. Call this first if any verb errors "not connected".', related: ['nbrowser_profiles', 'nbrowser_ping', 'nbrowser_open_window'], pitfalls: ['a profile\'s extension SLEEPS when that profile has no open windows - it then shows disconnected; open a window to wake it'] },+ nbrowser_readiness: { hint: 'READ-ONLY cold-start probe: is the native-browser extension connected + ready to drive? NEVER spawns work or installs anything. state:"ready" = drive now; state:"needs-extension" = offer to install it (Level-2, see installing-the-extension) or it is asleep (open a window in that profile).', related: ['nbrowser_status', 'nbrowser_open_window'], pitfalls: ['"needs-extension" can mean not-installed OR installed-but-asleep - nbrowser_status\'s tooltip distinguishes', 'this verb never installs; to install, run the installing-the-extension flow', 'for a machine-wide "what do I have" answer prefer AD\'s bridge_readiness (aggregates all bridges, spawns none)'] }, nbrowser_ping: { hint: 'Round-trip liveness through to the extension.', related: ['nbrowser_status'], pitfalls: [] }, nbrowser_open_window: { hint: 'Open a NEW background window YOU own and get a sessionId; do ALL your work through that sessionId. This is how you get a surface to drive WITHOUT touching the user\'s own windows.', related: ['nbrowser_navigate', 'nbrowser_screenshot', 'nbrowser_close_window'], next: 'nbrowser_navigate', pitfalls: ['opens UNFOCUSED - do NOT pass focused:true unless the user asked to watch', 'this is the safe way to work: always drive a window you opened, never the user\'s existing ones'] }, nbrowser_close_window: { hint: 'Close a window you opened. Clean up your own sessions when done.', related: ['nbrowser_list_windows'], pitfalls: ['⛔ only close a sessionId YOU opened - closing the user\'s window can wipe their live work and other AI threads'] },@@ -469,6 +470,23 @@ function dispatch(verb, args) { if (verb === 'nbrowser_help') { return resolve({ success: true, output: JSON.stringify({ ok: true, bridge: BRIDGE, version: VERSION, extConnected: anyConnected(), flashMode, ...HELP }) }); }+ // nbrowser_readiness - READ-ONLY cold-start probe (SDK Cold-start tiers). Never spawns work, never+ // installs. This bridge has no heavy runtime (tiny Node), so "readiness" == the Level-2 extension+ // being connected. AD's own bridge_readiness aggregates across bridges; this reports THIS one.+ if (verb === 'nbrowser_readiness') {+ const live = liveConns();+ const ready = live.length > 0;+ return resolve({ success: true, output: JSON.stringify({+ ready,+ state: ready ? 'ready' : 'needs-extension',+ installing: false,+ extensionConnected: ready,+ profiles: live.map(([k]) => k),+ _hint: ready+ ? `The Adom browser extension is connected (${live.length} profile(s)); drive it with nbrowser_open_window. Read-only probe - it never spawns work or installs.`+ : 'The Adom browser extension is NOT connected. It may be not-yet-installed (a Level-2 proactively-offered install: OFFER to install it for the user, then run the installing-the-extension flow - never make them do it) OR installed-but-asleep (the service worker sleeps when a profile has no open window; open one). Read-only: this verb never installs or spawns.',+ }) });+ } // nbrowser_describe - per-verb schemas for AD's Verbs tab + inline runner (AD v1.9.23+). // AD POSTs {command:"nbrowser_describe",args:{}} and renders each verb expandable with these I/O // docs, prefilling the runner with `example`. One entry per declared verb (+ describe itself).@@ -481,6 +499,7 @@ function dispatch(verb, args) { }; const verbs = [ d('nbrowser_status', 'Is the extension connected? Reports ext id/version + active browser.', {}, { ok: 'bool', ext: 'str', version: 'str', engine: 'str', browser: '"chrome"|"edge"' }, 15),+ d('nbrowser_readiness', 'READ-ONLY cold-start probe: is the native-browser extension connected + ready to drive? Never spawns work or installs. Use for "is it ready / do I have the browser extension" instead of nbrowser_status.', {}, { ready: 'bool', state: '"ready"|"needs-extension"', installing: 'bool', extensionConnected: 'bool', profiles: '[str]' }, 15, { example: {} }), d('nbrowser_ping', 'Round-trip liveness check through to the extension.', {}, { ok: 'bool', pong: 'bool' }, 15), d('nbrowser_open_window', 'Open a NEW window in the BACKGROUND (unfocused) and return a sessionId to drive it.', { url: 'required str', profile: P, focused: 'optional bool (default false = background)' }, { ok: 'bool', sessionId: 'str', tabId: 'str', windowId: 'int', url: 'str' }, 30, { example: { url: 'https://wiki.adom.inc' } }), d('nbrowser_close_window', 'Close a window the agent opened.', { sessionId: 'required str', profile: P }, { ok: 'bool', closed: 'bool', sessionId: 'str' }, 20, { example: { sessionId: 'work' } }),
native-browser-bridge-manifest.json+5−5@@ -1,8 +1,8 @@ { "manifest_version": 1,- "version": "0.0.19",- "url": "native-browser-bridge-v0.0.19.bin",- "sha256": "4cef2a4e27dc73c461c819457a603aeaada86d0bb8251e249a4bdaa63219680d",- "size": 27226,- "released_at": "2026-06-27T20:47:59Z"+ "version": "0.0.20",+ "url": "native-browser-bridge-v0.0.20.bin",+ "sha256": "a65bff1def96ee414a323ed89469556e08fba7fa33f18e53ad675e403e4675fa",+ "size": 27940,+ "released_at": "2026-07-01T11:47:34Z" }