name: driving-the-extension-demo description: Runnable PLAYBOOK for showing off / driving the Adom native browser (the real signed-in Chrome/Edge via nbrowser_*). Match this when the user asks to "demo the native browser", "show me what the browser extension can do", "drive my real Chrome", "open my browser and …", maximize / fullscreen / un-fullscreen / move / resize / tile the browser window, put two browser windows side-by-side, open tabs, show the taskbar status (Adom overlay badge / progress bar / flash alert), click-by-text with the Adom cursor, type / hover-for-a-tooltip / right-click, check "am I logged in to " / drive a logout-and-login, or fetch a chip's CAD (chip-fetcher) through their logged-in browser. Includes the exact commands, the demo page, the foreground/screenshot gotchas, and shotlog.

Parent skill: driving-the-extension

Native-browser DEMO playbook (nbrowser_*)

This is the copy-paste recipe set for driving and demoing the user's real Chrome/Edge. Each recipe is a sequence of adom-desktop nbrowser_* / desktop_* calls proven live. For the full capability reference (CDP-vs-native, the debug bar, xy-finding, verbs), read the parent skill driving-the-extension first.

SES = a session id (a real Chrome window). HWND = the OS window handle (from desktop_find_window / captured at open_window). Examples assume one Adom Desktop; add --target <host> if more than one is connected.

⭐ The golden rules for a watchable demo (learned the hard way)

  1. Foreground the window before EVERY step, or the user can't see it and your screenshots are wrong: desktop_bring_to_front {"hwnd":<HWND>} - omit state so it just raises and preserves the current maximized/fullscreen state. (state:"restore" would un-maximize it.)
  2. Most users mean MAXIMIZED, not immersive fullscreen. Run the majority of a demo maximized (window_state {state:"maximized"}). Show true fullscreen only as a quick "it can also do this".
  3. Screenshot method matters:
    • maximized / normal window → desktop_screenshot_window {hwnd} (PrintWindow).
    • immersive fullscreen → desktop_screenshot_window returns BLANK WHITE (GPU-composited fullscreen Chrome can't be PrintWindow'd) → use desktop_screenshot_screen (full screen).
    • taskbar / two-windows side-by-side → desktop_screenshot_screen. It occasionally returns a white frame (compositor race) → retry, and if it keeps failing, capture each window with desktop_screenshot_window and montage them (see the side-by-side recipe).
  4. Caption every step so the viewer knows what's happening: desktop_caption {"text":"…","position":"bottom","id":"nbd","durationMs":120000} (bottom - top covers the URL bar + debug banner). Clear with {"text":"","id":"nbd","clear":true}.
  5. shotlog every frame AND surface the viewer (don't just paste a URL): shotlog open --channel <ch> then adom-cli hydrogen workspace active-tab --name "Shots: <ch>", then per frame shotlog paste --channel <ch> --desc "<desc>" <file>. Hand the user the phone URL https://<slug>.adom.cloud/proxy/8820/log/<ch>/.
  6. Pace it: caption → ~3s (read) → foreground → action → ~2s (settle) → screenshot → ~1s. The #1 demo failure is running so fast the caption and the on-screen action are a step out of sync.
  7. Clean up after yourself: nbrowser_flash_stop, nbrowser_taskbar {progress:{state:"none"}, overlay:{badge:"none"}}, close extra windows, clear the caption.

Recipe - guided interaction demo (the dark demo page)

A self-contained dark-mode page (good for video - not too bright) with a Pay button, a name field, a hover-tooltip, and a right-click box. Write it once to the user's box, then drive it.

# (page source is in this repo: demo/demo3.html - write it to C:\Users\john\.adom\demo3.html)
nbrowser_navigate    {"sessionId":"demo","url":"file:///C:/Users/<u>/.adom/demo3.html"}
nbrowser_window_state {"sessionId":"demo","state":"maximized"}
nbrowser_click  {"sessionId":"demo","text":"Pay","cursor":true,"intent":"Clicking the Pay button"}   # click BY TEXT + Adom cursor
nbrowser_type   {"sessionId":"demo","selector":"#name","text":"John Lauer","cursor":true,"intent":"Typing your name"}
nbrowser_hover  {"sessionId":"demo","text":"Hover me","cursor":true,"intent":"Hovering to reveal the tooltip"}   # tooltip
nbrowser_right_click {"sessionId":"demo","selector":".ctx","cursor":true,"intent":"Right-clicking the box"}

Recipe - window state: maximize / fullscreen / un-fullscreen / move / resize

Native chrome.windows - no debug bar. (A synthetic F11 does NOT work - the browser intercepts browser-chrome shortcuts before the page sees the CDP key event; use this verb instead.)

nbrowser_window_state {"sessionId":"demo","state":"maximized"}    # what users usually want
nbrowser_window_state {"sessionId":"demo","state":"fullscreen"}   # immersive: no tabs/URL bar/taskbar
nbrowser_window_state {"sessionId":"demo","state":"normal"}       # un-fullscreen / un-maximize
nbrowser_window_state {"sessionId":"demo","left":60,"top":50,"width":1050,"height":700}   # move + resize
# alias: nbrowser_fullscreen {"sessionId":"demo"}

Recipe - two browser windows tiled SIDE-BY-SIDE

# read the work area (chrome's own coordinate units, DPI-correct) from a maximized window:
nbrowser_window_state {"sessionId":"demo","state":"maximized"}
nbrowser_list_windows {}        # -> sessions[].bounds {left,top,width,height}; halve the width
# open a 2nd window and tile (work area ~1707x1020 on a 150%-scaled 2560px screen):
nbrowser_open_window  {"sessionId":"demo2","thread":"demo-thread","purpose":"UltraLibrarian walkthrough demo","url":"https://www.ultralibrarian.com"}
nbrowser_window_state {"sessionId":"demo","left":0,"top":0,"width":853,"height":1015}
nbrowser_window_state {"sessionId":"demo2","left":853,"top":0,"width":853,"height":1015}

To shotlog the side-by-side, prefer a montage of two desktop_screenshot_window {hwnd} captures (reliable) over desktop_screenshot_screen (white-frame prone). Find each hwnd with desktop_find_window {"className":"Chrome_WidgetWin_1"} and pick by rect.left.

Recipe - open tabs in a window

nbrowser_open_tab  {"sessionId":"demo","url":"https://www.mouser.com"}
nbrowser_open_tab  {"sessionId":"demo","url":"https://www.ultralibrarian.com"}
nbrowser_list_tabs {"sessionId":"demo"}                          # -> [{tabId,url}]
nbrowser_switch_tab {"sessionId":"demo","tabId":"<id>"}          # bring a tab forward

Recipe - taskbar status: Adom overlay badge, progress, flash alert

Paints on the real browser window's taskbar button (the hwnd is captured at control-start). The window must be windowed/maximized (taskbar visible) - not immersive fullscreen.

nbrowser_taskbar {"sessionId":"demo","progress":{"state":"normal","value":45},"overlay":{"badge":"adom","tooltip":"Adom is driving your browser"}}   # GREEN + Adom badge
nbrowser_taskbar {"sessionId":"demo","progress":{"state":"paused","value":70}}      # YELLOW = human-gate (captcha/2FA/login)
nbrowser_flash   {"sessionId":"demo"}                                                # orange "come look" flash
nbrowser_flash_stop {"sessionId":"demo"}

Verified to render: the badge is a composite - the profile's circle avatar with the Adom favicon in its lower-right corner - sitting in the Chrome/Edge taskbar button's overlay slot (so the user still sees whose profile it is), and a green/yellow progress bar runs along the button's bottom. The badge applies AUTOMATICALLY while driving and idle-expires (~3 min) back to the plain native avatar, so for a demo you normally just drive and point at it. To prove it in a frame, full-screen capture then crop+zoom the button (crop the bottom taskbar strip).

Recipe - "am I logged in to ?" + drive logout/login

nbrowser_login_state {"url":"https://www.mouser.com"}
# -> {loggedIn:true, confidence:"high", authCookieNames:[ASP.NET_SessionId, …]}
  • Detects a live session from the site's auth/session cookies (chrome.cookies).
  • Chrome does NOT expose saved passwords to extensions (security) - you can't read the stored credential. To re-login after a logout: drive the login form and let Chrome autofill the saved credential, then submit (Adom never sees the secret). Or snapshot the auth cookies before logout and restore them (only works if logout didn't invalidate them server-side).

Recipe - the killer use case: fetch a chip's CAD (chip-fetcher) in the REAL browser

EE CAD sources (manufacturer → SnapMagic/SnapEDA → Mouser → DigiKey → Arrow → UltraLibrarian → LCSC-last) gate downloads behind login + captcha; pup's empty profile hits the wall. The native browser uses the engineer's real signed-in session, so the STEP / KiCad / Altium / Fusion bundles just download. chip-fetcher is the Rust CLI that walks that ladder - point it at the native browser instead of pup. Demo by navigating the real sites (nbrowser_navigate https://www.mouser.com…ultralibrarian.com) and showing login_state = signed in where pup would be signed out. chip-fetcher sources prints the canonical ladder.

Screenshot/shotlog helper pattern (cloud-side)

desktop_screenshot_screen auto-pulls both PNGs to the cloud (localFullPath in the result) - shotlog that path directly. desktop_screenshot_window returns base64 in .output.data.image (decode then shotlog). Resize busy frames ≤1400px for the model.