← Commit history

Bridge v0.0.20 (SDK audit): add updateManifestUrl + statusVerb; add read-only nbrowser_readiness (Level-2 needs-extension cold-start probe)

John Lauer ·95c88ff39a ·4mo ago ·parent 11147e4
5 files changed +31−9
bridge/BRIDGE_VERSION+1−1
@@ -1 +1 @@-0.0.19\ No newline at end of file+0.0.20\ No newline at end of file
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" }