Adom Browser Extension
Public Made by Adomby adom
Your AI's hands in your real, signed-in browser. The Adom Browser Extension (abe) works with both Chrome and Edge: build, drive, and test web apps, and log past vendor walls, in the browser you already use - cookies, SSO, saved logins and captcha trust intact. The nbrowser_* bridge (pup's counterpart) runs in your actual logged-in profile.
name: native-browser-recording description: "How to record full-resolution, high-framerate demo videos of a browser window in the BACKGROUND so the user keeps working. THE BEST PATH is the core adom-desktop verb desktop_record_window_start (WGC) - or nbrowser_record_start {method:"wgc"}, which delegates to it: no source picker, no banner, captures occluded windows, no focus theft. The extension's own getDisplayMedia/tabcapture recording is a LAST-RESORT FALLBACK (Chrome forces a manual share-source picker a human must click) and is refused unless you pass fallbackConfirmed:true. Use the native browser ONLY when a demo needs the user's real session/cookies/logins; otherwise record via pup or Hydrogen (see the demo-recording skill). Covers WGC vs the heinous getDisplayMedia picker, the paint-throttling problem, the occlusion/throttle-disable launch flags, the restart-native-Chrome-into-background-recording-mode flow (ask + warn + full process-tree kill + relaunch with profile + flags), and the offer-to-revert-for-battery step. Match on: record a browser window, record the native browser, record a logged-in demo, background recording of Chrome, nbrowser_record, desktop_record_window_start, WGC, source picker, share picker, full-framerate native recording. Part of the adom-browser-extension."
Part of adom-browser-extension (see driving-the-extension for the verb surface). The broad demo pipeline (Hydrogen vs pup, scripting, TTS, storyboard, mux, wiki upload) lives in the demo-recording skill - this page is ONLY the part that's unique to recording the user's real, logged-in native browser.
When to use the native browser to record (and when NOT to)
- Use it ONLY when the demo needs the user's real session - cookies, SSO, logins (e.g. a tool gated behind their account). Only the user's real Chrome has those.
- Otherwise, don't. If the app is reachable without the user's login, record via pup or Hydrogen (demo-recording skill) - those are throwaway/managed surfaces you can drive freely without disturbing the user's real browser.
⭐ FIRST: record with WGC (the core adom-desktop window recorder), NOT the extension
The single best way to record a browser window is the CORE adom-desktop verb
desktop_record_window_start (Windows Graphics Capture). You can call it directly, or call
nbrowser_record_start {method:"wgc", titleContains:"<title>"|hwnd:<n>} which delegates straight to it.
WGC records ONE window in the background, up to 60 fps, with NO source picker, NO "sharing" banner,
captures the window even when it is occluded, and never steals the user's focus. Stop with
desktop_record_window_stop (or nbrowser_record_stop {method:"wgc",recordingId}); poll
desktop_record_window_status. Reach for WGC first, every time.
⛔ The extension's OWN recording is a LAST-RESORT FALLBACK, and the bridge enforces it
method:"getdisplaymedia" / "tabcapture" record through the browser itself, and nbrowser_record_start
refuses them unless you also pass fallbackConfirmed:true (a record_start with no method just returns
the WGC hint). Why they're bad, and why being a "full browser extension" does NOT save you:
- Chrome forbids silent screen capture. Even a full extension cannot record without
getDisplayMediapopping a share-source PICKER a human must click to choose the window/screen. You do not get to override that - it is a hard browser-security gate. (This is the exact trap to avoid: an AI that blindly calls record_start lands on a picker that just sits there waiting for a human.) - It paints a persistent recording banner, and it does not reliably capture a background/occluded window. WGC has none of these problems because it captures at the OS level, below the browser.
- Use
getdisplaymediaONLY if WGC is genuinely unavailable (e.g. non-Windows with no WGC). Even then the picker can only be skipped by launching Chrome yourself with--auto-select-desktop-capture-source="<window title>".
The goal forces everything: full-resolution, HIGH FRAMERATE (20-60 fps)
Demos must look amazing. The enemy is PAINT-THROTTLING, not the codec. Chrome correctly stops painting occluded / background / static windows (it's the right battery-saving default), and capture is frame-driven, so a throttled window silently drops to ~5 fps ("frozen" / sped-up video). This bites WGC too: WGC faithfully records an occluded window, but if Chrome has stopped painting it, WGC captures a blank/frozen surface. The fix is the occlusion/throttle-disable launch flags below, NOT foregrounding the window.
Why the native path is different from pup: you must NOT foreground the user's real Chrome
pup beats paint-throttling with the foreground-rebump trick (raise the throwaway window before each action). You must NOT do that to the user's real working browser - it wrecks their flow. Instead, make the real Chrome keep painting while occluded by launching it with the occlusion/throttle-disable flags:
--disable-features=CalculateNativeWinOcclusion --disable-backgrounding-occluded-windows
--disable-renderer-backgrounding --disable-background-timer-throttling
A default Chrome does not have these (correctly - they cost battery: every occluded window keeps rendering). So enabling them is a temporary, opt-in mode we enter for recording and leave afterward.
The flow - record a logged-in demo in the background
- Confirm you actually need the real session. If not, go use pup/Hydrogen.
- Check whether native Chrome already runs with the flags - read its launch command line
(
adom-desktop process_list {nameContains:"chrome"}→ the mainchrome.exewith no--type=). pup's "Chrome for Testing" already has them; the user's real Chrome usually does not. - If the flags are missing → ASK + WARN, then fully restart Chrome into background-recording mode:
- Tell the user plainly: "To record at full framerate while you keep working, I need to fully restart your Chrome once. Your tabs and logins come back."
- Kill the ENTIRE
chrome.exeprocess tree - native Chrome spawns many helper/background processes (GPU, utility, crashpad, the--no-startup-windowbackground-mode launcher); closing the window is NOT enough and the flags won't apply until everychrome.exeis gone. Kill them all, confirm shutdown. - Relaunch with their real profile + the flags (default
--user-data-dir/--profile-directory, so logins survive and tabs return via session-restore), e.g. vialaunch_process. - Wait for the extension to reconnect (
nbrowser_status).
- Record in the background -
nbrowser_record_start {method:"wgc", hwnd:<window>}(orgetdisplaymediawith--auto-select-desktop-capture-source). Drive the app (CDP, background) +nbrowser_caption. The occluded window now paints, so the capture is full-framerate and not blank. Never foreground it. - Stop + fetch -
nbrowser_record_stop {method:"wgc", recordingId}(wgc is bridge-side; the stop needs therecordingId, not just a sessionId). The mp4 lands on the laptop under%TEMP%\adom-desktop-recordings; pull it withpull_file {filePaths:["C:\\...\\window-….mp4"]}(it saves into the container/tmp). - OFFER TO REVERT (battery): when the recording session is done, ask "Chrome's in full-background recording mode, which uses more battery - want me to put it back to normal?" → if yes, fully restart Chrome again WITHOUT the flags. Best of all worlds: real session + amazing recordings + normal battery.
The hard requirement under both transitions
A robust full-restart of native Chrome: enumerate + terminate the whole chrome.exe process tree, confirm
it's down, relaunch with the real profile (+ flags to enter, or without to revert). This is the load-bearing
primitive - get it solid and the rest is easy.
⛔ Never
- Foreground the user's real Chrome to "fix" framerate or a blank recording - use the flags instead.
- Leave the flags on globally/permanently - it drains laptop battery. Enter the mode, record, offer to revert.
- Upload a raw recording to the wiki without the
-g 30 -keyint_min 30keyframe re-encode (see demo-recording).
Pitfalls
- Blank/black frames = the recorded Chrome was NOT launched with the occlusion-disable flags
(
--disable-backgrounding-occluded-windows --disable-renderer-backgrounding --disable-background-timer-throttling --disable-features=CalculateNativeWinOcclusion). pup's Chrome has them; a default user Chrome does not - relaunch it with them (never foreground to "fix" it). method:"getdisplaymedia"/"tabcapture"are REFUSED withoutfallbackConfirmed:true- a browser extension can't silently screen-record (Chrome forces a manual share-picker + a persistent banner). Usemethod:"wgc"(delegates to coredesktop_record_window_start): background, up to 60fps, no picker.- Recording paths are on the LAPTOP, not the container -
pull_fileto fetch them. - Do NOT maximize/foreground to "frame" the recording. WGC captures a background/occluded window; a
window_state maximizethat raises the window is auto-reverted (it stays background) - size it with explicitleft/top/width/heightbounds instead if you need it bigger. - Register the window you record like any other (
sessionId+thread+purposeonopen_window) and close it when done (nbrowser_close_window {sessionId, includeSpawned:true}) - don't leave litter.
Hand-off
Post-production (speedup, voiceover, storyboard review, concat, hero, wiki upload) → Adom Video Post-Production (adom-video-post), which bundles the demo-recording skill.
Surface selection, scripting, TTS, the keyframe rule, the cross-surface mechanics → the demo-recording skill.
---
name: native-browser-recording
description: "How to record full-resolution, high-framerate demo videos of a browser window in the BACKGROUND so the user keeps working. THE BEST PATH is the core adom-desktop verb desktop_record_window_start (WGC) - or nbrowser_record_start {method:\"wgc\"}, which delegates to it: no source picker, no banner, captures occluded windows, no focus theft. The extension's own getDisplayMedia/tabcapture recording is a LAST-RESORT FALLBACK (Chrome forces a manual share-source picker a human must click) and is refused unless you pass fallbackConfirmed:true. Use the native browser ONLY when a demo needs the user's real session/cookies/logins; otherwise record via pup or Hydrogen (see the demo-recording skill). Covers WGC vs the heinous getDisplayMedia picker, the paint-throttling problem, the occlusion/throttle-disable launch flags, the restart-native-Chrome-into-background-recording-mode flow (ask + warn + full process-tree kill + relaunch with profile + flags), and the offer-to-revert-for-battery step. Match on: record a browser window, record the native browser, record a logged-in demo, background recording of Chrome, nbrowser_record, desktop_record_window_start, WGC, source picker, share picker, full-framerate native recording. Part of the adom-browser-extension."
---
Part of **adom-browser-extension** (see **driving-the-extension** for the verb surface). The broad demo
pipeline (Hydrogen vs pup, scripting, TTS, storyboard, mux, wiki upload) lives in the **demo-recording**
skill - this page is ONLY the part that's unique to recording the user's **real, logged-in native browser**.
## When to use the native browser to record (and when NOT to)
- **Use it ONLY when the demo needs the user's real session** - cookies, SSO, logins (e.g. a tool gated
behind their account). Only the user's real Chrome has those.
- **Otherwise, don't.** If the app is reachable without the user's login, record via **pup** or **Hydrogen**
(demo-recording skill) - those are throwaway/managed surfaces you can drive freely without disturbing the
user's real browser.
## ⭐ FIRST: record with WGC (the core adom-desktop window recorder), NOT the extension
**The single best way to record a browser window is the CORE adom-desktop verb
`desktop_record_window_start` (Windows Graphics Capture).** You can call it directly, or call
`nbrowser_record_start {method:"wgc", titleContains:"<title>"|hwnd:<n>}` which delegates straight to it.
WGC records ONE window in the **background, up to 60 fps, with NO source picker, NO "sharing" banner**,
captures the window **even when it is occluded**, and **never steals the user's focus**. Stop with
`desktop_record_window_stop` (or `nbrowser_record_stop {method:"wgc",recordingId}`); poll
`desktop_record_window_status`. **Reach for WGC first, every time.**
### ⛔ The extension's OWN recording is a LAST-RESORT FALLBACK, and the bridge enforces it
`method:"getdisplaymedia"` / `"tabcapture"` record through the browser itself, and `nbrowser_record_start`
**refuses them unless you also pass `fallbackConfirmed:true`** (a record_start with no method just returns
the WGC hint). Why they're bad, and why being a "full browser extension" does NOT save you:
- **Chrome forbids silent screen capture.** Even a full extension cannot record without `getDisplayMedia`
popping a **share-source PICKER a human must click** to choose the window/screen. You do **not** get to
override that - it is a hard browser-security gate. (This is the exact trap to avoid: an AI that blindly
calls record_start lands on a picker that just sits there waiting for a human.)
- It paints a **persistent recording banner**, and it does **not** reliably capture a **background/occluded**
window. WGC has none of these problems because it captures at the OS level, below the browser.
- Use `getdisplaymedia` ONLY if WGC is genuinely unavailable (e.g. non-Windows with no WGC). Even then the
picker can only be skipped by **launching Chrome yourself** with
`--auto-select-desktop-capture-source="<window title>"`.
## The goal forces everything: full-resolution, HIGH FRAMERATE (20-60 fps)
Demos must look amazing. **The enemy is PAINT-THROTTLING, not the codec.** Chrome *correctly* stops painting
occluded / background / static windows (it's the right battery-saving default), and capture is frame-driven,
so a throttled window silently drops to ~5 fps ("frozen" / sped-up video). This bites WGC too: WGC faithfully
records an occluded window, but if Chrome has stopped *painting* it, WGC captures a blank/frozen surface. The
fix is the occlusion/throttle-disable launch flags below, NOT foregrounding the window.
## Why the native path is different from pup: you must NOT foreground the user's real Chrome
pup beats paint-throttling with the **foreground-rebump** trick (raise the throwaway window before each
action). **You must NOT do that to the user's real working browser** - it wrecks their flow. Instead, make
the real Chrome **keep painting while occluded** by launching it with the occlusion/throttle-disable flags:
```
--disable-features=CalculateNativeWinOcclusion --disable-backgrounding-occluded-windows
--disable-renderer-backgrounding --disable-background-timer-throttling
```
A default Chrome does **not** have these (correctly - they cost battery: every occluded window keeps
rendering). So enabling them is a **temporary, opt-in mode** we enter for recording and **leave afterward**.
## The flow - record a logged-in demo in the background
1. **Confirm you actually need the real session.** If not, go use pup/Hydrogen.
2. **Check whether native Chrome already runs with the flags** - read its launch command line
(`adom-desktop process_list {nameContains:"chrome"}` → the main `chrome.exe` with no `--type=`). pup's
"Chrome for Testing" already has them; the user's real Chrome usually does not.
3. **If the flags are missing → ASK + WARN, then fully restart Chrome into background-recording mode:**
- Tell the user plainly: *"To record at full framerate while you keep working, I need to fully restart
your Chrome once. Your tabs and logins come back."*
- **Kill the ENTIRE `chrome.exe` process tree** - native Chrome spawns many helper/background processes
(GPU, utility, crashpad, the `--no-startup-window` background-mode launcher); closing the window is NOT
enough and the flags won't apply until *every* `chrome.exe` is gone. Kill them all, confirm shutdown.
- **Relaunch with their real profile + the flags** (default `--user-data-dir`/`--profile-directory`, so
**logins survive** and tabs return via session-restore), e.g. via `launch_process`.
- Wait for the extension to reconnect (`nbrowser_status`).
4. **Record in the background** - `nbrowser_record_start {method:"wgc", hwnd:<window>}` (or `getdisplaymedia`
with `--auto-select-desktop-capture-source`). Drive the app (CDP, background) + `nbrowser_caption`. The
occluded window now paints, so the capture is full-framerate and not blank. **Never foreground it.**
5. **Stop + fetch** - `nbrowser_record_stop {method:"wgc", recordingId}` (wgc is bridge-side; the stop needs
the `recordingId`, not just a sessionId). The mp4 lands on the laptop under `%TEMP%\adom-desktop-recordings`;
pull it with `pull_file {filePaths:["C:\\...\\window-….mp4"]}` (it saves into the container `/tmp`).
6. **OFFER TO REVERT (battery):** when the recording session is done, ask *"Chrome's in full-background
recording mode, which uses more battery - want me to put it back to normal?"* → if yes, **fully restart
Chrome again WITHOUT the flags**. Best of all worlds: real session + amazing recordings + normal battery.
## The hard requirement under both transitions
A **robust full-restart of native Chrome**: enumerate + terminate the whole `chrome.exe` process tree, confirm
it's down, relaunch with the real profile (+ flags to enter, or without to revert). This is the load-bearing
primitive - get it solid and the rest is easy.
## ⛔ Never
- Foreground the user's **real** Chrome to "fix" framerate or a blank recording - use the flags instead.
- Leave the flags on **globally/permanently** - it drains laptop battery. Enter the mode, record, offer to revert.
- Upload a raw recording to the wiki without the `-g 30 -keyint_min 30` keyframe re-encode (see demo-recording).
## Pitfalls
- **Blank/black frames** = the recorded Chrome was NOT launched with the occlusion-disable flags
(`--disable-backgrounding-occluded-windows --disable-renderer-backgrounding
--disable-background-timer-throttling --disable-features=CalculateNativeWinOcclusion`). pup's Chrome
has them; a default user Chrome does not - relaunch it with them (never foreground to "fix" it).
- **`method:"getdisplaymedia"`/`"tabcapture"` are REFUSED without `fallbackConfirmed:true`** - a browser
extension can't silently screen-record (Chrome forces a manual share-picker + a persistent banner). Use
`method:"wgc"` (delegates to core `desktop_record_window_start`): background, up to 60fps, no picker.
- **Recording paths are on the LAPTOP**, not the container - `pull_file` to fetch them.
- **Do NOT maximize/foreground to "frame" the recording.** WGC captures a background/occluded window; a
`window_state maximize` that raises the window is auto-reverted (it stays background) - size it with
explicit `left/top/width/height` bounds instead if you need it bigger.
- **Register the window you record** like any other (`sessionId`+`thread`+`purpose` on `open_window`) and
**close it when done** (`nbrowser_close_window {sessionId, includeSpawned:true}`) - don't leave litter.
## Hand-off
Post-production (speedup, voiceover, storyboard review, concat, hero, wiki upload) → **Adom Video Post-Production** (`adom-video-post`), which bundles the `demo-recording` skill.
Surface selection, scripting, TTS, the keyframe rule, the cross-surface mechanics → the **demo-recording** skill.