← Commit history
bridge/BRIDGE_VERSION+1−1
@@ -1 +1 @@-0.1.14\ No newline at end of file+0.1.15\ No newline at end of file
bridge/adom-favicon.pngadded
⋯ 1 unchanged line ⋯
bridge/bridge.json+1−1
@@ -2,7 +2,7 @@   "manifest_version": 1,   "name": "native-browser",   "displayName": "Adom Native Browser (Chrome + Edge)",-  "version": "0.1.14",+  "version": "0.1.15",   "expectedExtensionVersion": "0.1.2",   "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",
bridge/package.json+1−1
@@ -1,6 +1,6 @@ {   "name": "adom-native-browser-bridge",-  "version": "0.1.14",+  "version": "0.1.15",   "private": true,   "description": "adom-desktop bridge for the Adom native-browser extension (Chrome + Edge)",   "main": "server.js",
bridge/server.js+16−3
@@ -296,7 +296,7 @@ const HELP = {     'errors/events': 'errors = console/page errors for a tab. events = window/tab closes incl. byUser.',     'record_start/stop/status/list': 'method: wgc|getdisplaymedia|tabcapture. record_start is non-blocking for getdisplaymedia (poll record_status). base64 return is for SHORT clips only.',     'caption/focus': 'caption{style:subtitle|alert,position}. focus selects the tab + flashes its taskbar button (does NOT raise the window - by design, never steals the user\'s focus). Capture in place; the window is raised ONLY on explicit user request (userRequestedForeground:true, or the core desktop_bring_to_front). NEVER foreground or OS-launch a window to surface it - foregrounding is the user\'s choice alone.',-    'flash/flash_stop/flash_mode/taskbar': 'Paint glanceable status on the driven browser window\'s Windows TASKBAR button (hwnd captured at open_window; the "Adom is driving" badge goes on automatically - on opened windows at open, and on adopted SPAWNED windows when you call nbrowser_owned / nbrowser_list_windows). flash = orange "come look" cue (auto-clears on focus). flash_mode{quiet|chatty|off}: quiet(default)=auto-flash on come-look moments (page load, screenshot, an error/refusal, a human gate, and freshly SPAWNED windows) - flash manually with nbrowser_flash at task-DONE; chatty=every action (users who want to watch); off=NO auto-flash at all (the user opt-out - set this if they say the flashing is annoying). nbrowser_taskbar{progress:{state:"normal"|"paused"|"error"|"indeterminate"|"none",value?},overlay:{badge:"adom"|"none"}} = progress bar (green/YELLOW-for-gates/red/marquee) + overlay badge for long tasks. Use paused(yellow)+flash on captcha/2FA/login. Clears on close.',+    'flash/flash_stop/flash_mode/taskbar': 'Paint glanceable status on the driven browser window\'s Windows TASKBAR button (hwnd captured at open_window; the "Adom is driving" badge goes on automatically - on opened windows at open, and on adopted SPAWNED windows when you call nbrowser_owned / nbrowser_list_windows). The badge is a COMPOSITE the bridge builds: the profile\'s own circle avatar + the Adom favicon in its corner - so the user still sees WHICH profile it is. It idle-expires after ~3 min of no driving (restoring the plain native avatar - the overlay slot is never blanked), and re-appears on your next drive verb. flash = orange "come look" cue (auto-clears on focus). flash_mode{quiet|chatty|off}: quiet(default)=auto-flash on come-look moments (page load, screenshot, an error/refusal, a human gate, and freshly SPAWNED windows) - flash manually with nbrowser_flash at task-DONE; chatty=every action (users who want to watch); off=NO auto-flash at all (the user opt-out - set this if they say the flashing is annoying). nbrowser_taskbar{progress:{state:"normal"|"paused"|"error"|"indeterminate"|"none",value?},overlay:{badge:"adom"|"none"}} = progress bar (green/YELLOW-for-gates/red/marquee) + overlay badge for long tasks. Use paused(yellow)+flash on captcha/2FA/login. Clears on close.',   }, }; @@ -1019,7 +1019,7 @@ const VERB_META = {   nbrowser_flash: { hint: 'Flash the driven window\'s taskbar button - the "come look" cue (e.g. at a captcha/2FA/login human-gate).', related: ['nbrowser_flash_stop', 'nbrowser_flash_mode'], pitfalls: ['auto-clears on focus; nbrowser_flash_stop to clear early'] },   nbrowser_flash_stop: { hint: 'Stop the taskbar flash.', related: ['nbrowser_flash'], pitfalls: ['the flash already auto-clears when the user focuses the window - only stop it early if you no longer need their attention'] },   nbrowser_flash_mode: { hint: 'Set auto-flash verbosity: quiet (come-look moments: page load, screenshot, error/refusal, human-gate, spawned window) | chatty (every action) | off (no auto-flash at all). Flash manually with nbrowser_flash at task-done.', related: ['nbrowser_flash'], pitfalls: ['off is the user opt-out - if the user says the orange flashing is annoying, set flash_mode:"off" and it stops entirely', 'quiet is the default; the flash is a "come look" cue, so keep it for human-gates even if you dial the rest down'] },-  nbrowser_taskbar: { hint: 'Paint progress/overlay/flash on the window taskbar button (e.g. paused=yellow for a human gate).', related: ['nbrowser_flash'], pitfalls: ['clear everything at task end: {progress:{state:"none"},overlay:{badge:"none"},flash:"stop"}'] },+  nbrowser_taskbar: { hint: 'Paint progress/overlay/flash on the window taskbar button (e.g. paused=yellow for a human gate). The "Adom is driving" badge is AUTOMATIC: the bridge composites the profile\'s circle avatar + the Adom favicon at open/drive, and idle-expires it (~3 min) back to the plain native avatar - you rarely need to touch overlay yourself.', related: ['nbrowser_flash'], pitfalls: ['clear progress+flash at task end: {progress:{state:"none"},flash:"stop"} - the badge clears itself (idle-expiry / close)', 'overlay.badge:"none" RESTORES the native avatar look (the bridge never blanks the overlay slot - blanking would erase the user\'s profile avatar)'] },   nbrowser_describe: { hint: 'Returns per-verb schemas + hint/related/pitfalls for AD\'s Verbs tab.', related: ['nbrowser_help'], pitfalls: ['this is the catalog - a few extension-only verbs (e.g. nbrowser_login_form) are real but resolved in the extension, not listed here'] },   nbrowser_handle_dialog: { hint: 'Press OK/Cancel (or answer a prompt) on a native JS dialog (alert/confirm/prompt/beforeunload) BLOCKING the page. accept:true=OK/Yes/Leave · accept:false=Cancel/Stay · text:"…" answers a prompt.', related: ['nbrowser_screenshot', 'nbrowser_click'], next: 'nbrowser_screenshot', pitfalls: ['these dialogs are NOT in a screenshot and have NO hwnd (Chrome renders them) - you learn of them via a modal_open error or a screenshot _modal note', 'the page is FROZEN until you handle it: clicks/typing/eval return modal_open until you do', 'if the AI "keeps failing to fill a form", suspect an open dialog - handle it, then re-screenshot'] },   nbrowser_dev_reload: { hint: 'MAINTAINER-only: reload the extension to pick up on-disk code changes (2-pass, reconnects in ~10s).', related: ['nbrowser_status'], pitfalls: ['throttled to 1/90s (a reload restarts the SW + native host)', 'not for normal driving - only after editing the extension source', 'reloads ONE profile; other profiles pick up the new code on their own next reload'] },@@ -1348,7 +1348,20 @@ function dispatch(verb, args) {       if (args && args.progress) opts.progress = args.progress;       if (args && args.overlay) opts.overlay = args.overlay;       if (args && args.flash) opts.flash = args.flash;-      taskbar(hwnd, opts).then(() => resolve({ success: true, output: JSON.stringify({ ok: true, hwnd, applied: Object.keys(opts), _hint: 'progress.state: normal(green) | paused(YELLOW - use for captcha/2FA/login human-gates) | error(red) | indeterminate(marquee) | none. overlay.badge: "adom" (the driven-by-Adom badge) | "none". Clear ALL at task-end: {progress:{state:"none"},overlay:{badge:"none"},flash:"stop"}.' }) }));+      // TRAP GUARD: on a REAL browser the overlay slot is where Chrome/Edge draw the PROFILE AVATAR, so+      // literally clearing it (badge:"none") would blank the user's avatar - the destructive bug we fixed.+      // Remap: badge:"none" = "stop showing Adom" -> repaint the NATIVE look (plain circle avatar);+      // badge:"adom" -> the composite (avatar + Adom favicon) applyBadge builds. AIs keep the simple API.+      if (opts.overlay && opts.overlay.badge === 'none' && !opts.overlay.icon) {+        const pk = (args && args.sessionId && sessionProfile.get(args.sessionId)) || null;+        delete opts.overlay;+        if (args && args.sessionId) clearBadge(args.sessionId);+        nativeOverlay(hwnd, pk);+      } else if (opts.overlay && opts.overlay.badge === 'adom' && !opts.overlay.icon) {+        delete opts.overlay;+        if (args && args.sessionId) applyBadge(args.sessionId, hwnd, null); else paintBadge(hwnd, null);+      }+      taskbar(hwnd, opts).then(() => resolve({ success: true, output: JSON.stringify({ ok: true, hwnd, applied: Object.keys(opts).length ? Object.keys(opts) : ['overlay:managed'], _hint: 'progress.state: normal(green) | paused(YELLOW - use for captcha/2FA/login human-gates) | error(red) | indeterminate(marquee) | none. overlay.badge: "adom" = the driving badge (the bridge composites the profile\'s CIRCLE avatar + the Adom favicon - never a bare square) | "none" = restore the NATIVE avatar look (never blanks the slot). The badge is AUTOMATIC while driving and idle-expires after ~3 min, so you rarely need to set it. Clear progress+flash at task-end: {progress:{state:"none"},flash:"stop"}.' }) }));       return;     }     // WGC recording is handled HERE (bridge -> AD direct API, standalone - never HD), not in the
native-browser-bridge-manifest.json+5−5
@@ -1,8 +1,8 @@ {   "manifest_version": 1,-  "version": "0.1.14",-  "url": "https://wiki.adom.inc/download/adom/adom-browser-extension/0.1.14/native-browser-bridge-v0.1.14.bin",-  "sha256": "8125cc886d586e15b08f91a3c0ee7a37050c7e6e20cefa48a51799d4f32e4224",-  "size": 67556,-  "released_at": "2026-07-14T00:00:00Z"+  "version": "0.1.15",+  "url": "https://wiki.adom.inc/download/adom/adom-browser-extension/0.1.15/native-browser-bridge-v0.1.15.bin",+  "sha256": "5c061203023855078213c9adc0e7193312f9fd88c945cb1808cc356add6d9102",+  "size": 68227,+  "released_at": "2026-07-15T00:00:00Z" }
publish-skills/publishing-the-bridge/SKILL.md+10
@@ -98,3 +98,13 @@ drops the hero). Verify: `adom-wiki discover preview --json "<7 real user querie ## After ANY wiki change: show John in pup (standing rule) Open the live page in a maximized pup window + shotlog + hand him the phone URL. Never just report "published."++## After ANY release: prove the USER-VISIBLE result, unprompted (standing rule)+Verifying the pipeline is not verifying the feature. "The verb returned ok / the file exists / a test+window rendered" is engineer-proof; the user cares what THEY will see. So after landing a release,+automatically demonstrate the actual user-visible outcome on EVERY surface the change touches (e.g. a+taskbar-badge change = show every browser+profile it will decorate, not one throwaway Notepad button)+and put it in shotlog with the phone URL - before the user has to ask. If a live demo would touch+something sensitive (a banking window, a signed-in session), don't skip the demo - build the same+proof a safe way (generate from the real inputs off to the side) and say why. The user should never+have to say "prove it."