---
name: adom-desktop-control
description: >
  Drive an Adom user's REAL machine from the cloud through Adom Desktop: their
  logged-in Chrome/Edge (browser extension / CDP), headless pup browsers, native
  windows (UIA + SendInput), the Hydrogen web editor, and sibling Claude tabs,
  plus a screen-recording + video post-production pipeline. Use when you need to
  click/type/upload in the user's browser, drive a native app window, log a user
  in, record the screen, or produce a demo video. Trigger words: drive the
  browser, control chrome/edge, nbrowser, pup, automate the desktop, click a
  native window, UIA, record the screen, make a demo, speed up a video, type into
  the Claude tab, drive an OAuth login, upload a file via the browser.
---

# Adom Desktop Control

Everything here is about reaching OFF the cloud container and acting on the user's
**actual desktop** through Adom Desktop (the `adom-desktop` CLI + relay). It is a
pack of tested patterns, each one distilled from a real session, each labeling
**what works, what fails, and why** so you don't relearn it the hard way.

## Pick the right surface (the #1 decision)

| You want to drive... | Use | Skill |
|---|---|---|
| The user's REAL logged-in Chrome/Edge (their cookies/sessions) | `nbrowser_*` (browser extension, CDP) | [native-browser-control](skills/native-browser-control/SKILL.md) |
| A throwaway/anonymous browser, or one you'll record clean | `browser_*` (pup / Puppeteer) | [pup-browser-control](skills/pup-browser-control/SKILL.md) |
| A native app window (Fusion, dialogs, non-web UI) | `desktop_*` (UIA + SendInput) | [desktop-ui-control](skills/desktop-ui-control/SKILL.md) |
| The Hydrogen web editor / its Claude panel | (mostly can't, read why first) | [hydrogen-web-control](skills/hydrogen-web-control/SKILL.md) |
| A sibling Claude tab to run a task | depends on where it runs | [claude-control](skills/claude-control/SKILL.md) |
| Capture a window to a video (the right way) | `desktop_record_window_start` (WGC, background) | [screen-recording](skills/screen-recording/SKILL.md) |
| Turn raw clips into a finished demo | ffmpeg + `video-post` | [video-post-production](skills/video-post-production/SKILL.md) |

## The cross-cutting rules (true on every surface)

- **Background by default. Foregrounding the user's window is RUDE, it interrupts their
  work.** There is almost always a background path, use it:
  - CAPTURE: `desktop_screenshot_window` (PrintWindow) and `desktop_record_window_start`
    (WGC) both grab a window even when it's occluded/off-screen. **NEVER** reach for
    `desktop_screenshot_screen` (fullscreen) or `desktop_bring_to_front` just to take a
    screenshot, that steals focus for zero reason. (John, repeatedly: foregrounding
    Fusion/Chrome to screenshot is "so rude... disrupt my work.")
  - INPUT: UIA verbs act in the background, `desktop_ui_click` (Invoke), `desktop_ui_set`
    (SetValue), `desktop_ui_scroll`, `desktop_ui_toggle`, `desktop_ui_select`. Drive a
    control by accessible NAME, no focus steal.
  - Only OS SendInput (`desktop_click`/`desktop_type`/`desktop_press_key`) and
    `desktop_screenshot_screen`/`desktop_bring_to_front` foreground. Reserve them for the
    rare case a control genuinely isn't in the UIA tree AND can't be reached via CDP.
    (A verb-level hint reprimanding gratuitous use of these is filed with AD/Colby.)
- **Drive it yourself, including login. Never ask the user to click or log in.** You
  can drive their real browser end to end, including OAuth, see native-browser-control.
- **Upload files via DataTransfer, not the OS file picker.** Inject the bytes into the
  page and set the `<input type=file>`, works in pup and nbrowser. The OS picker is a
  last resort (needs foreground SendInput). See native-browser-control / pup-browser-control.
- **To record, capture the WINDOW (WGC), not the whole desktop.** `desktop_record_window_start`
  records one window in the background even when it's occluded, so there is no foreground
  theft. Whole-desktop capture (`desktop_record_start`) records whatever is topmost, so a
  self-updating window (e.g. the Hydrogen panel) keeps stealing the take. See screen-recording.
- **Verify by screenshot, don't assume.** After any click/type into a webview, screenshot
  and confirm the text/state actually landed, OS input silently no-ops on many webview editors.
- **Search the verb surface before you assume a feature is missing.** `adom-desktop help
  <namespace>` / `<verb>`. Several capabilities (WGC window recording, nbrowser on Edge,
  nbrowser recording) were missed by assuming they didn't exist. Look first.

## Install

```bash
adompkg install adom/adom-desktop-control
```

Drops the pack skill plus all sub-skills into `~/.claude/skills/`. Pairs with the
`adom-desktop` app and the `adom-browser-extension`.

## Sub-skills

- **[native-browser-control](skills/native-browser-control/SKILL.md)** - drive the user's real Chrome/Edge via the extension (CDP).
- **[pup-browser-control](skills/pup-browser-control/SKILL.md)** - drive headless Puppeteer browsers.
- **[desktop-ui-control](skills/desktop-ui-control/SKILL.md)** - click/type native windows via UIA + SendInput.
- **[hydrogen-web-control](skills/hydrogen-web-control/SKILL.md)** - the Hydrogen editor's nested-webview limits.
- **[claude-control](skills/claude-control/SKILL.md)** - drive sibling Claude tabs (and when you can't).
- **[screen-recording](skills/screen-recording/SKILL.md)** - capture the desktop to video with on-screen captions.
- **[video-post-production](skills/video-post-production/SKILL.md)** - cut, speed up, caption, narrate, publish.

Narration for demos uses [`adom-tts`](https://wiki.adom.inc/adom/adom-tts) (house voice + pronunciation cache).
