← Commit history
bridge 0.0.22 + host node fix: bridge publishes AD-provisioned node path; native-host.bat reuses it so no system Node needed (SDK runtime contract)
6 files changed
+54−11
bridge/BRIDGE_VERSION+1−1@@ -1 +1 @@-0.0.21+0.0.22
bridge/bridge.json+1−1@@ -2,7 +2,7 @@ "manifest_version": 1, "name": "native-browser", "displayName": "Adom Native Browser (Chrome + Edge)",- "version": "0.0.21",+ "version": "0.0.22", "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.",
bridge/server.js+9@@ -32,6 +32,13 @@ let VERSION = '0.0.1'; try { VERSION = require('./package.json').version || VERSION; } catch {} const HOSTFILE = path.join(os.homedir(), '.adom', 'bridges', BRIDGE, 'host.json');+// The Chrome-launched native-messaging host needs a Node to run its stdio pump, but Chrome does NOT+// inherit AD's managed-runtime PATH (AD only puts its Node on the PATH of processes IT spawns). THIS+// bridge, however, IS spawned by AD, so process.execPath is exactly the Node AD provisioned (system or+// the portable no-UAC copy). We publish that absolute path here in plain text so native-host.bat can+// point at a guaranteed-present Node even on a machine with no system Node. Self-heals across AD runtime+// upgrades: every respawn rewrites it. See the adom-desktop-bridges SDK "runtime contract".+const NODEPATHFILE = path.join(os.homedir(), '.adom', 'bridges', BRIDGE, 'node-path.txt'); const DEBUGLOG = path.join(os.homedir(), '.adom', 'bridges', BRIDGE, 'bridge-debug.log'); // ---- persistence hardening -------------------------------------------------@@ -860,6 +867,8 @@ const hostSrv = net.createServer((sock) => { function writeHostFile(hostPort) { fs.mkdirSync(path.dirname(HOSTFILE), { recursive: true }); fs.writeFileSync(HOSTFILE, JSON.stringify({ host: '127.0.0.1', hostPort, pid: process.pid, version: VERSION }));+ // Publish the Node AD gave us so the Chrome-launched host can reuse it (see NODEPATHFILE note above).+ try { fs.writeFileSync(NODEPATHFILE, process.execPath); } catch {} } // PID-aware cleanup: ONLY delete host.json if it still points at *this* process. Otherwise a churning // instance (AD respawn, a manual run, a crash-restart) deletes the discovery file that another LIVE
host/native-host.bat+15−4@@ -1,6 +1,17 @@ @echo off-REM Chrome/Edge launch this as the native-messaging host "path".-REM It runs the Node stdio<->bridge pump. Node is resolved from PATH; the installer may rewrite this-REM line with an absolute node.exe path (the way adom-desktop resolves node for its bridges) if PATH-REM is unreliable under the browser's launch environment.+REM Chrome/Edge launch this as the native-messaging host "path". It runs the Node stdio<->bridge pump.+REM+REM Node resolution order (Chrome does NOT inherit adom-desktop's managed-runtime PATH, so we must NOT+REM assume `node` is on PATH on a machine with no system Node install):+REM 1. node-path.txt published by the AD-spawned bridge = the EXACT Node adom-desktop provisioned+REM (system, or its portable no-UAC copy). Self-healing: the bridge rewrites it on every respawn,+REM so an AD runtime upgrade never leaves us pointing at a dead node.exe.+REM 2. `node` from PATH (a system install), as a fallback.+set "NODE_EXE="+set "NPFILE=%USERPROFILE%\.adom\bridges\native-browser\node-path.txt"+if exist "%NPFILE%" set /p NODE_EXE=<"%NPFILE%"+if defined NODE_EXE if exist "%NODE_EXE%" (+ "%NODE_EXE%" "%~dp0native-host.js"+ exit /b+) node "%~dp0native-host.js"
native-browser-bridge-manifest.json+5−5@@ -1,8 +1,8 @@ { "manifest_version": 1,- "version": "0.0.21",- "url": "native-browser-bridge-v0.0.21.bin",- "sha256": "c06bc4a0ab4dce3e485e3c7ea1cdb3b015e7df42a056fa5f8ea9a0778296a781",- "size": 28083,- "released_at": "2026-07-02T19:12:07Z"+ "version": "0.0.22",+ "url": "native-browser-bridge-v0.0.22.bin",+ "sha256": "2e7a8dded6b7137a4f1c47b8c4ba11f46cfdfe1b494f6b3c0e576440cdfe3b30",+ "size": 28451,+ "released_at": "2026-07-02T19:43:28Z" }
skills/installing-the-extension/SKILL.md+23@@ -26,6 +26,29 @@ getting "Load unpacked" to pick the right folder; everything else is determinist 2. **The native-messaging host is registered** (`install/install.ps1`, or its steps): host manifest written with `allowed_origins` = the pinned ID, and `HKCU\...\NativeMessagingHosts\inc.adom.native_browser` pointing at it (Chrome and/or Edge). No UAC. 3. **The bridge is installed** in AD's cache (`bridge_install`, once). See the install-flow doc. +### ⚠ The host's Node - do NOT assume system Node exists (SDK runtime contract)+The bridge (`server.js`) is spawned by adom-desktop, so **AD guarantees its Node** (v1.9.63+ runtime+contract: system Node if on PATH, else a portable no-UAC copy AD provisions). **But the+native-messaging host is launched by CHROME, not AD**, so it does NOT inherit AD's managed-runtime+PATH. A machine with **no system Node** would then fail to start the host (`'node' is not recognized`)+even though the bridge is healthy - the extension would connect and immediately drop.++This is handled automatically, and you usually do nothing:+- **The bridge publishes the exact Node AD gave it** (`process.execPath`) to+ `~/.adom/bridges/native-browser/node-path.txt` every time it starts (bridge >= 0.0.22).+- **`native-host.bat` reads that file first**, falls back to `node` on PATH only if it's absent. Since+ the bridge always runs before the extension is installed, the file is already there by first host+ launch. Self-healing: an AD Node upgrade rewrites it on the next bridge respawn.++**If you ever need to write it explicitly** (e.g. a repair, or the host somehow launched before the+bridge ever ran): ask AD for the managed Node path and drop it in yourself -+```+adom-desktop runtimes # -> runtimes.node.exe (source: system|cache), e.g. C:/Program Files/nodejs/node.exe+# then write that absolute path (one line, no newline games) to:+# %USERPROFILE%\.adom\bridges\native-browser\node-path.txt+```+Never `winget install node` / prompt the user to install Node - AD already has one; reuse it.+ ## ⭐ Verify by SCREENSHOT, not by control state (the rule for the whole flow) `desktop_find_control` / UIA state is a fast **hint** and it lies often enough to burn you: a toggle can read ambiguously, the folder picker can select the wrong directory silently, and **Load unpacked can