← Commit history
Self-detecting host: walks its process ancestry (node<-cmd<-chrome|msedge) to tag the browser, so a browser registers correctly even when an old extension's hello omits it — Edge proven live in parallel with Chrome (0.3.3)
2 files changed
+43−5
host/native-host.js+42−4@@ -101,6 +101,40 @@ function writeToExtension(obj) { process.stdout.write(json); } +// Which browser launched THIS host? The extension's hello carries `browser` on new builds — prefer it.+// Otherwise (old extension mid-upgrade) detect it from our process ancestry: the host is+// node.exe <- (native-host.bat) cmd.exe <- chrome.exe | msedge.exe. Walk parents until we hit a browser.+// Result is cached; only runs at all for an extension that didn't report its browser.+let _hostBrowser = null;+function hostBrowser(msg) {+ if (msg && msg.browser) return msg.browser;+ if (_hostBrowser) return _hostBrowser;+ _hostBrowser = detectBrowserFromTree();+ return _hostBrowser;+}+function detectBrowserFromTree() {+ try {+ const out = require('child_process').execSync(+ 'powershell -NoProfile -Command "Get-CimInstance Win32_Process | Select-Object ProcessId,ParentProcessId,Name | ConvertTo-Csv -NoTypeInformation"',+ { timeout: 5000, windowsHide: true }+ ).toString();+ const byPid = new Map();+ for (const line of out.split(/\r?\n/)) {+ const m = line.match(/^"?(\d+)"?,"?(\d+)"?,"?([^"]+)"?$/);+ if (m) byPid.set(Number(m[1]), { ppid: Number(m[2]), name: String(m[3]).toLowerCase() });+ }+ let pid = process.ppid, hops = 0;+ while (pid && hops++ < 8) {+ const p = byPid.get(pid);+ if (!p) break;+ if (p.name.includes('msedge')) return 'edge';+ if (p.name.includes('chrome')) return 'chrome';+ pid = p.ppid;+ }+ } catch { /* fall through to default */ }+ return 'chrome';+}+ // ---- stdin (from the extension) -> bridge ---------------------------------- let bridge = null; let inbuf = Buffer.alloc(0);@@ -117,11 +151,15 @@ function pumpStdin() { // the bridge registers the connection under this profile. if (msg && msg.type === 'hello') { clearTimeout(helloFallback);- // Key the singleton by BROWSER + profile so the same account in Chrome AND Edge each get their- // own host (instead of the 2nd browser's host exiting on a shared lock — the "Native host has- // exited" collision). The bridge keys connections the same way, so all coexist in parallel.+ // BROWSER + profile keying so the same account in Chrome AND Edge each get their own host (instead+ // of the 2nd browser's host exiting on a shared lock — the "Native host has exited" collision).+ // Prefer the browser the extension reported; else detect it from THIS host's process ancestry+ // (chrome.exe vs msedge.exe) so an OLD extension that doesn't send `browser` still tags correctly.+ // TAG the hello with it so the bridge keys the connection the SAME way (all coexist in parallel).+ const browser = hostBrowser(msg);+ msg.browser = browser; const _id = (msg.profile && (msg.profile.email || msg.profile.id)) || 'default';- acquireSingleton(`${msg.browser || 'chrome'}:${_id}`);+ acquireSingleton(`${browser}:${_id}`); } sendToBridge(msg); }
package.json+1−1@@ -1,6 +1,6 @@ { "slug": "adom-browser-extension",- "version": "0.3.2",+ "version": "0.3.3", "type": "app", "title": "Adom Browser Extension (Chrome + Edge)", "description": "Drive your real, logged-in Chrome/Edge from the Adom ecosystem \u2014 the nbrowser_* native-browser bridge (counterpart to pup). Multi-profile driving, a read-only credential-library query over the browser's own saved logins (Chrome + Edge), and hands-free vendor login automation, so chip CAD / datasheets download past every login wall in your real signed-in session.",