---
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 <site>" / 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.
```bash
# (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.)
```bash
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
```bash
# 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
```bash
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.
```bash
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 <site>?" + drive logout/login
```bash
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.
