[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-browser-use-windows-harness":3,"mdc--ag7z8r-key":35,"related-repo-browser-use-windows-harness":2469,"related-org-browser-use-windows-harness":2478},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":25,"repoUrl":26,"updatedAt":27,"license":28,"forks":29,"topics":30,"repo":31,"sourceUrl":33,"mdContent":34},"windows-harness","control Windows desktop applications","Control a whole Windows desktop from one persistent Python session with foreground-first input (focus holding, SendInput with pen\u002Fmessage fallbacks), background screenshots, UI Automation, Browser Harness, clipboard paste, PowerShell, and filesystem access. Use for native, Electron, browser, dialog, file, or cross-app tasks.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"browser-use","Browser-use","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Fbrowser-use.png",[12,16,19,22],{"name":13,"slug":14,"type":15},"Automation","automation","tag",{"name":17,"slug":18,"type":15},"Windows","windows",{"name":20,"slug":21,"type":15},"Desktop","desktop",{"name":23,"slug":24,"type":15},"Browser Automation","browser-automation",51,"https:\u002F\u002Fgithub.com\u002Fbrowser-use\u002Fwindows-harness","2026-08-26T04:12:24.233955",null,3,[],{"repoUrl":26,"stars":25,"forks":29,"topics":32,"description":28},[],"https:\u002F\u002Fgithub.com\u002Fbrowser-use\u002Fwindows-harness\u002Ftree\u002FHEAD\u002Fsrc\u002Fwindows_harness","---\nname: windows-harness\ndescription: Control a whole Windows desktop from one persistent Python session with foreground-first input (focus holding, SendInput with pen\u002Fmessage fallbacks), background screenshots, UI Automation, Browser Harness, clipboard paste, PowerShell, and filesystem access. Use for native, Electron, browser, dialog, file, or cross-app tasks.\n---\n\n# Windows Harness\n\nUse one CLI call per decision point, not per primitive:\n\n```bash\nwindows-harness \u003C\u003C'PY'\napp = \"Notepad\"\nwin.see(app)\nwin.type(\"hello\", app=app)\nprint(win.see(app))\nPY\n```\n\nThe CLI preloads `win`, lazy `browser`, `Path`, and `subprocess`. Prefer bounded\nstdin programs; reserve `windows-harness repl` for manual exploration and always\nexit it.\n\n## How to invoke: exactly two forms\n\nOne-off questions — use a subcommand (identical in PowerShell, cmd, and bash):\n\n```bash\nwindows-harness apps                 # app inventory, compact JSON (--all adds system windows)\nwindows-harness see \"CC Switch\"      # one screenshot -> JSON with its \"path\"\nwindows-harness state \"Notepad\"      # UIA tree as JSON (--screenshot adds image)\n```\n\nAnything multi-step — write a `.py` file, then run it. No quoting or encoding\ntraps in any shell; this is always the most reliable channel:\n\n```bash\nwindows-harness run task.py          # win, browser, Path, subprocess preloaded\n```\n\nWrite generated task scripts to the harness scripts dir (printed by\n`windows-harness doctor` as `scripts_dir`, default\n`%USERPROFILE%\\.windows-harness\\scripts`); `run` resolves bare filenames\nthere. Never write task scripts into the caller's working directory or\ninvent ad-hoc folders like `.windows-harness-temp\u002F` — they pollute the\nuser's repo and show up as untracked files. Never run them via\n`python script.py` \u002F `python -c` either: bypassing `windows-harness run`\nalso bypasses the preloaded `win` session, so every call pays a fresh\ninterpreter start and loses the element table behind `element_index`.\n\nNever use `\u003C\u003C'PY'` heredocs outside bash; never enumerate windows through\nhand-rolled C#\u002FPowerShell — `win.list_apps()` already did it. Screenshots\nland in `%TEMP%\\windows-harness-*.png` and persist: the returned `\"path\"`\nstays readable after the CLI exits, so just open it. Set\n`WINDOWS_HARNESS_OVERLAY=off` to skip the pointer renderer for minimum\nlatency.\n\n## Delivery: foreground first\n\nEvery input primitive takes `delivery=\"foreground\"` (default) or\n`delivery=\"background\"`.\n\n| mode | transports | disturbance |\n|---|---|---|\n| `foreground` (default) | front the target + SendInput; pen\u002Fmessage fallback when hook software swallows SendInput | the target comes to the front and STAYS (`hold=True`) until `win.release()` |\n| `background` | synthetic-pen injection, PostMessage, UIA patterns | none — never fronts, never moves the cursor |\n\nWhy foreground is the default: focus-driven UI (search boxes with suggestion\npopups, context menus, IME candidate windows) closes the instant its window\nloses the foreground, and CEF off-screen \u002F XAML input stacks only accept\nmessage input while truly foreground and focused. Holding the foreground\nacross a burst turns \"sometimes works\" into a procedure.\n\n- `win.release()` hands the foreground back to the user's previous window.\n  Call it when a task burst is done.\n- For one quick invisible action use `delivery=\"foreground\", hold=False`\n  (cloaked ~150 ms takeover, restored after) or `delivery=\"background\"`.\n- Foreground clicks use SendInput mouse events and do NOT summon the Windows\n  touch keyboard; synthetic pen\u002Ftouch injection (background clicks) can pop\n  it up and wreck the focus chain — avoid pen taps into text fields.\n- `background` results carry `\"mode\": \"pen\" | \"message\"` plus\n  `\"verified\": false` when the effect cannot be confirmed. When a framework's\n  input stack silently drops background events the call raises\n  `BackgroundUnavailable` with a structured `code`; redo the SAME action with\n  default foreground delivery — do not probe more background transports.\n- `windows-harness doctor` reports `input_health.sendinput`: `ok`,\n  `swallowed` (hook software such as audio enhancers or overlay recorders is\n  eating injected events — suspects under `possible_injectors`), or\n  `unknown`. When SendInput is swallowed, foreground actions automatically\n  fall back to pen\u002Fmessage transports against the now-foreground target.\n\n## Use the small surface\n\nThink in seven verbs: `see`, `key`, `type`, `click`, `paste`, `ax`, `script`\n— plus two inventory calls: `win.list_apps()` (processes with their window\ntitles) and `win.windows(app)` (one app's windows).\n\n```python\nframe = win.see(\"Notepad\")\nwin.key(\"ctrl+s\", app=\"Notepad\")\nwin.type(\"Alessia Cara\", app=\"Notepad\")                    # type at the focused field\nwin.type(\"Alessia Cara\", app=\"Notepad\", x=640, y=420)      # click the field, then type\nwin.click(640, 420, app=\"Notepad\")\nwin.click(640, 420, app=\"Notepad\", clicks=2)               # double click\nwin.click(640, 420, app=\"Notepad\", button=\"right\")         # context menu\nwin.drag(200, 300, 500, 600, app=\"Notepad\")                # press, glide, release\nwin.scroll(-720, app=\"Notepad\")                            # wheel at window center (or x\u002Fy)\nwin.hover(640, 420, app=\"Notepad\")                         # really hover -> tooltip appears\nwin.paste(\"Alessia Cara\", app=\"Notepad\")                   # clipboard paste (see ladder)\nwin.release()                                              # hand the foreground back\n\nitem = win.ax.at(640, 420, app=\"Notepad\")\nwin.ax.perform(item[\"element_index\"], \"invoke\")\nwin.ax.click(item[\"element_index\"])      # click the element's center — no coordinates\nwin.ax.hover(item[\"element_index\"])      # hover it so its tooltip fires\n\nwin.script(\"Get-Process | Select-Object -First 3 Name\")\n```\n\n`win.click()` is raw coordinate input; it never guesses a UIA action. For\nsemantic actions use `win.ax.at()` + `win.ax.perform()`, and fill text fields\nwith `win.ax.set_value()` (verified by read-back) when an element exposes a\nValuePattern — no keystrokes at all. `win.ax.click()` \u002F `win.ax.hover()` act\non the element's own BoundingRectangle center: coordinates never leave the\nharness, so no coordinate-space mismatch is possible — prefer them over\ncopying frame values into `win.click()` yourself.\n\n`win.hover(x, y)` delivers a real hover (physical cursor, or pen hover when\nSendInput is filtered) so tooltips and hover-only UI appear; `win.move(x, y)`\nonly animates the virtual pointer and delivers no input. Hover is\ncoordinate-routed — the target needs to be unoccluded, not foreground — and\nthe cursor stays put so the tooltip survives long enough for a `win.see()`.\n\n## Modal dialogs and overlays\n\n`win.see(app)` is **window-scoped**: it captures only that one window's client\narea, so an overlay sitting on top (a Save As \u002F Open \u002F Print dialog, a\nconfirm prompt) is **not** in the shot even though it is on screen. To see a\npopup that just appeared, do not guess its title:\n\n```python\nwin.key(\"ctrl+s\", app=\"Notepad\")        # an untitled doc opens Save As\nfg = win.foreground_window()            # the dialog's title\u002Fhwnd\nframe = win.see(fg[\"hwnd\"])             # capture the dialog itself\n# or grab the whole desktop, which sees every window at once:\ndesktop = win.capture_screen()\n```\n\n`win.capture_screen()` captures the entire virtual desktop (all monitors) and\nits screenshot-space coordinates pair with `coordinate_space=\"screen\"`. A bare\n`win.see()` with no app now targets the foreground window, so it also catches a\nmodal that is currently in front.\n\n`win.see(app, bring_to_front=True)` fronts the target and keeps it fronted\n(restoring it if minimized) until `win.release()`; the default is a quiet\nbackground grab that never raises or activates the window, so `see` stays\nnon-intrusive unless you opt in.\n\n## Text input ladder\n\n1. `win.ax.set_value()` when the element exposes a ValuePattern — verified by\n   read-back and works fully in the background.\n2. `win.type(text, x=..., y=...)` — focuses the field and types in one call.\n3. `win.paste(text)` — the clipboard route. Setting the clipboard is a plain\n   data handoff no hook software can filter; only the paste trigger needs\n   input (SendInput Ctrl+V, or a posted WM_PASTE when SendInput is filtered —\n   never a posted Ctrl+V, whose modifier never reaches GetKeyState). Focus\n   the target field first (a click, or `win.type` with x\u002Fy).\n4. If the paste trigger also fails: right-click the field and click the\n   context menu's Paste item (pen injection can drive the menu).\n5. When `doctor` reports `input_health.sendinput == \"swallowed\"`, tell the\n   user which processes (`possible_injectors`) are eating injected input —\n   removing the hook software is the real fix.\n\n`win.type()` reports what actually landed, not just that keystrokes were sent.\nXAML\u002FWinUI text boxes (Win11 Notepad, Settings) and CEF editors drop much of a\n`KEYEVENTF_UNICODE` burst while claiming `verified: True`; the harness reads\nthe field back and, on a mismatch, retries via `win.ax.set_value()` (verified)\nor `win.paste()`. If the result carries `\"retried_via\"`, the keyboard route\ndropped characters and the retry landed them. The result's `verified_via`\nsays how `verified` was established: `\"value_pattern\"`\u002F`\"clipboard\"` mean a\nread-back confirmed the text, `\"transport\"` means the target exposes no\nreadable text state and only delivery was confirmed. A `verified: false` with\na `read_back` field means the window accepted the keystrokes but the text did\nnot appear (e.g. an app-launch\u002Fsession-restore race) — click the field and\nretry, or switch to `win.paste()`.\n\nReplacing a field's existing text: there is no reliable select-all keystroke\non hook-filtered machines (Ctrl+A is a combo and refuses; CEF ignores a\nposted Backspace). The dependable sequence is a triple click —\n`win.click(x, y, clicks=3)` selects the field's text — then `win.type` or\n`win.paste`, which replaces the selection. On machines with healthy\nSendInput, `win.key(\"ctrl+a\")` first is fine too.\n\nBare keys vs combos: when SendInput is swallowed, `win.key(\"enter\")` and\nother modifier-less keys still work (posted to the foreground target); only\ncombos like `ctrl+a` refuse, honestly.\n\n## Coordinates\n\n`coordinate_space` accepts:\n\n- `'screenshot'` (default) — pixels of the latest `win.see()` image; the\n  returned `scale_x`\u002F`scale_y` map them to the window.\n- `'normalized'` — a 0..1000 grid over the client area of the window from the\n  latest `win.see()`, independent of screenshot resolution and DPI; use\n  directly when the model outputs normalized coordinates:\n\n  ```python\n  frame = win.see(\"Notepad\")                          # anchors the window\n  win.click(500, 48, app=\"Notepad\", coordinate_space=\"normalized\")\n  ```\n\n  The window's origin is resolved live at click time, so the window may move\n  between `see()` and `click()`; only a resize invalidates the grid — take a\n  fresh `see()` after any resize.\n- `'client'` \u002F `'screen'` — raw window-client or physical screen pixels.\n\nEvery positional primitive (`click`, `double\u002Fright click`, `drag`, `scroll`\nwith x\u002Fy, `type` with x\u002Fy, `hover`) accepts `coordinate_space`; the\nnormalized grid works for all of them.\n\nDefault to vision + normalized coordinates; only fall back to element centers\nfrom the ax tree when you need semantic identity or a layout shift makes a\ncoordinate fragile. ax output reports frames in the pixel space of your latest\n`win.see()` screenshot of that window (the `frame` key, alongside\n`\"frame_space\": \"screenshot\"` in `state`), so they drop straight into the\ndefault coordinate space. Without a matching screenshot the raw physical\nscreen pixels are reported under `frame_screen` instead — those only pair\nwith `coordinate_space=\"screen\"`, never the default. Cleanest of all is\nkeeping numbers out of the loop: `win.ax.click(element_index)` \u002F\n`win.ax.hover(element_index)`.\n\nTarget apps by exe name when titles can collide — resolution prefers an\nexact process-name match (`\"Discord.exe\"`, or bare `\"Discord\"`), then an\nexact title, and only then substrings, so a window whose title merely\nmentions the name (a VS Code tab titled \"… Discord …\") never hijacks the\nquery.\n\n## Action proof: look only when it misfires\n\nEvery coordinate primitive (`click`, `drag`, `scroll`, `hover`, `type` with\nx\u002Fy) stamps the intended point back onto the screenshot it was anchored to and\nreturns the path under `result[\"proof\"][\"path\"]`. The `proof` key is optional:\nit is present only when annotation is on (the default) and the proof was\nactually generated, so read it through `result.get(\"proof\")` before using it.\n\n```python\nout = win.click(640, 420, app=\"Notepad\")\nproof = out.get(\"proof\")\nprint(proof[\"path\"] if proof else \"no proof\")   # annotated PNG you can open\n```\n\nIt stays absent for non-coordinate primitives (`key`, `paste`, `move`,\n`ax.click`, `see`) and for any call given `annotate=False`, or when\n`WINDOWS_HARNESS_PROOF=off`.\n\n* `click` \u002F double \u002F right \u002F `hover` \u002F click-to-`type` draw a red reticle\n  (circle-cross) at the point, labelled with the button and count.\n* `scroll` draws an arrow from the anchor point (the window centre whenever\n  `x`\u002F`y` are omitted) in the direction of the wheel delta.\n* `drag` draws the glide as a blue line with a reticle at the start and a\n  square at the end.\n\nDo NOT open the proof on every action — the input already ran. Open it only\nto decide WHY a coordinate action mis-landed: you aimed at the wrong spot, the\neffect did not happen, or you need to nudge a coordinate before retrying. A\nnormal `win.see()` on the finished step is the usual confirmation.\n\nThe concrete trigger: an action reports success (or `verified: true`) but\n`win.verify_change(app)` says nothing changed, or a `win.see()` shows the page\nchanged in a way you did not expect. In that case open\n`result[\"proof\"][\"path\"]` FIRST — before retrying, nudging, or switching\ntransports. The reticle on the anchored screenshot tells you at a glance\nwhether the input even landed where you intended; guessing from coordinates\nalone just burns rounds.\n\nForgot to print the proof path, or need an earlier one? Every proof is\njournaled to `proofs.jsonl` under the harness config dir (default\n`%USERPROFILE%\\.windows-harness`) as it is written, so history survives\nacross CLI invocations:\n\n```python\nwin.last_proof()                      # newest proof whose PNG still exists\nwin.proofs(limit=5)                   # recent proofs, newest first\nwin.proofs(app=\"Notepad\", kind=\"click\")   # filter by process\u002Ftitle and kind\n```\n\nEach entry carries the same fields as `result[\"proof\"]` plus `ts` and the\ntarget `app` (process\u002Ftitle); entries whose PNG was cleaned up are skipped. Pass\n`annotate=False` to any primitive (or set `WINDOWS_HARNESS_PROOF=off`) to turn\nthe proof off for a coordinate you already know is good.\n\n## Minimize round trips\n\n- Bundle deterministic, reversible steps into one program, then verify once.\n- Stop at a genuine decision boundary: ambiguous identity, new coordinates, an\n  irreversible action, or unexpected state.\n- Do not screenshot merely to confirm a known shortcut opened a field before\n  typing; let the final screenshot verify the whole sequence.\n- Poll exact UIA state inside the same Python program when possible.\n- Use the cheapest strong end-state check: one screenshot for visible state,\n  one exact UIA query for semantic state.\n\n## Choose the lowest useful mode\n\nVision-first: if you can read a screenshot, lead with `win.see(app)` +\nnormalized coordinates (a 0..1000 grid) instead of the UIA tree. Many apps\n(Electron\u002Fcustom-drawn UI, game launchers, some frameless and webview\nwindows) expose no usable UIA tree, and even when they do, screenshot +\ncoordinates need no per-app support. Reach for `win.ax` only when you need\nsemantic identity or state.\n\n1. Use `win.script()` for a known exact command (Get-Process, registry reads).\n2. Otherwise use `win.see(app)` and vision: locate the target in the\n   screenshot, then act with `coordinate_space=\"normalized\"` (0..1000) so the\n   numbers are resolution\u002FDPI independent.\n3. Prefer a known keyboard route; use a verified coordinate for a visible,\n   low-risk target.\n4. Use targeted `win.ax` only when semantic identity or state matters. For\n   CEF\u002FElectron custom-drawn UI (chat apps, music players, game launchers)\n   the tree fills lazily: `state`\u002F`ax.query`\u002F`ax.at` automatically warm a\n   near-empty CEF tree with a brief (usually invisible, cloaked) foreground\n   round, so warm it once if you truly need a semantic handle. Icon-only\n   controls (server\u002Favatar images) often expose only generic names — hover\n   them (`win.ax.hover`) and read the tooltip from a `win.see()`. If a dump\n   still comes back near-empty with a `note`, go straight to screenshot +\n   normalized coordinate clicks instead of spending more rounds on UIA.\n5. Use `delivery=\"background\"` only for apps already proven to accept it on\n   this machine (classic Win32 controls, UIA patterns) — it is the quiet\n   opt-in, not the default to probe with.\n\nAfter a failed verified burst, switch mode or stop. Never repair uncertainty\nwith repeated keys, clicks, deletion loops, or bulk input.\n\n## Verify, then teach the matrix\n\n- After a `\"verified\": false` action, confirm the effect with\n  `win.verify_change(app)` — a background pixel diff that costs no focus and\n  no vision round trip. Use a full `win.see()` only when you need to know\n  WHAT changed, not THAT it changed. Animated windows (video, games) report\n  change on their own; verify those semantically through `win.ax` instead.\n- When a background action provably had no effect (verify_change negative AND\n  the task did not advance), record it once with `win.note_drop(kind)` — e.g.\n  `win.note_drop(\"text_input\", app=\"...\")`. Future background calls against\n  that window class refuse honestly instead of repeating a dead transport.\n\n## Keep the invariants\n\n- Foreground `hold=True` keeps the target fronted across the whole burst;\n  always end a task with `win.release()` (or leave the window fronted\n  deliberately and say so).\n- Background delivery NEVER activates, raises, or moves the cursor. Occluded\n  targets refuse with `background_occluded` rather than being raised.\n- ax queries against CEF\u002FElectron windows (`Chrome_WidgetWin*`) whose tree is\n  near-empty auto-warm it with a brief cloaked foreground takeover; the\n  previous foreground is restored when the warm-up round ends.\n- Elevated (Administrator) targets are detected up front (UIPI preflight) and\n  refused with `background_uipi_blocked`; run the harness elevated to drive them.\n- The animated pointer is click-through and never moves the physical cursor;\n  non-held foreground rungs move it briefly and put it back.\n- Minimized windows are restored before foreground input and stay restored\n  under `hold=True`; non-held foreground rungs re-minimize afterwards.\n- Prefer semantic UIA patterns over simulated window chrome: frameworks that\n  draw their own titlebar (WinUI3, Electron) may ignore posted WM_CLOSE and\n  caption-button Invoke. The framework-neutral close is the WindowPattern —\n  `win.ax.raw(i).GetWindowPattern().Close()` — then answer the app's own\n  confirmation through `ax.perform(..., \"invoke\")`.\n- XAML apps (Win11 Notepad, Settings, UWP frames) refuse background typing —\n  use `win.ax.set_value()` there; WPF refuses background drag and scroll —\n  use default foreground delivery.\n\n## Browser tasks\n\nUse the preloaded lazy `browser` object whenever the task lives inside a web\npage. It exposes Browser Harness helpers and connects to the real browser on\nfirst use:\n\n```python\nprint(browser.page_info())\nbrowser.new_tab(\"https:\u002F\u002Fexample.com\")\n```\n\nDo not substitute OS input for CDP inside web content; keep Windows primitives\nfor browser chrome, native dialogs, downloads, and everything outside the page.\n\nRun `windows-harness doctor` to inspect the runtime without changing anything.\n",{"data":36,"body":37},{"name":4,"description":6},{"type":38,"children":39},"root",[40,48,54,133,178,185,190,277,290,319,403,448,454,474,567,572,702,708,778,952,1009,1035,1041,1067,1114,1140,1165,1171,1247,1359,1395,1416,1422,1433,1557,1612,1678,1699,1705,1765,1796,1849,1911,1923,1958,1979,2010,2053,2059,2087,2093,2113,2221,2226,2232,2289,2295,2405,2411,2423,2446,2451,2463],{"type":41,"tag":42,"props":43,"children":44},"element","h1",{"id":4},[45],{"type":46,"value":47},"text","Windows Harness",{"type":41,"tag":49,"props":50,"children":51},"p",{},[52],{"type":46,"value":53},"Use one CLI call per decision point, not per primitive:",{"type":41,"tag":55,"props":56,"children":61},"pre",{"className":57,"code":58,"language":59,"meta":60,"style":60},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","windows-harness \u003C\u003C'PY'\napp = \"Notepad\"\nwin.see(app)\nwin.type(\"hello\", app=app)\nprint(win.see(app))\nPY\n","bash","",[62],{"type":41,"tag":63,"props":64,"children":65},"code",{"__ignoreMap":60},[66,88,98,106,115,124],{"type":41,"tag":67,"props":68,"children":71},"span",{"class":69,"line":70},"line",1,[72,77,83],{"type":41,"tag":67,"props":73,"children":75},{"style":74},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[76],{"type":46,"value":4},{"type":41,"tag":67,"props":78,"children":80},{"style":79},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[81],{"type":46,"value":82}," \u003C\u003C",{"type":41,"tag":67,"props":84,"children":85},{"style":79},[86],{"type":46,"value":87},"'PY'\n",{"type":41,"tag":67,"props":89,"children":91},{"class":69,"line":90},2,[92],{"type":41,"tag":67,"props":93,"children":95},{"style":94},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[96],{"type":46,"value":97},"app = \"Notepad\"\n",{"type":41,"tag":67,"props":99,"children":100},{"class":69,"line":29},[101],{"type":41,"tag":67,"props":102,"children":103},{"style":94},[104],{"type":46,"value":105},"win.see(app)\n",{"type":41,"tag":67,"props":107,"children":109},{"class":69,"line":108},4,[110],{"type":41,"tag":67,"props":111,"children":112},{"style":94},[113],{"type":46,"value":114},"win.type(\"hello\", app=app)\n",{"type":41,"tag":67,"props":116,"children":118},{"class":69,"line":117},5,[119],{"type":41,"tag":67,"props":120,"children":121},{"style":94},[122],{"type":46,"value":123},"print(win.see(app))\n",{"type":41,"tag":67,"props":125,"children":127},{"class":69,"line":126},6,[128],{"type":41,"tag":67,"props":129,"children":130},{"style":79},[131],{"type":46,"value":132},"PY\n",{"type":41,"tag":49,"props":134,"children":135},{},[136,138,144,146,152,154,160,162,168,170,176],{"type":46,"value":137},"The CLI preloads ",{"type":41,"tag":63,"props":139,"children":141},{"className":140},[],[142],{"type":46,"value":143},"win",{"type":46,"value":145},", lazy ",{"type":41,"tag":63,"props":147,"children":149},{"className":148},[],[150],{"type":46,"value":151},"browser",{"type":46,"value":153},", ",{"type":41,"tag":63,"props":155,"children":157},{"className":156},[],[158],{"type":46,"value":159},"Path",{"type":46,"value":161},", and ",{"type":41,"tag":63,"props":163,"children":165},{"className":164},[],[166],{"type":46,"value":167},"subprocess",{"type":46,"value":169},". Prefer bounded\nstdin programs; reserve ",{"type":41,"tag":63,"props":171,"children":173},{"className":172},[],[174],{"type":46,"value":175},"windows-harness repl",{"type":46,"value":177}," for manual exploration and always\nexit it.",{"type":41,"tag":179,"props":180,"children":182},"h2",{"id":181},"how-to-invoke-exactly-two-forms",[183],{"type":46,"value":184},"How to invoke: exactly two forms",{"type":41,"tag":49,"props":186,"children":187},{},[188],{"type":46,"value":189},"One-off questions — use a subcommand (identical in PowerShell, cmd, and bash):",{"type":41,"tag":55,"props":191,"children":193},{"className":57,"code":192,"language":59,"meta":60,"style":60},"windows-harness apps                 # app inventory, compact JSON (--all adds system windows)\nwindows-harness see \"CC Switch\"      # one screenshot -> JSON with its \"path\"\nwindows-harness state \"Notepad\"      # UIA tree as JSON (--screenshot adds image)\n",[194],{"type":41,"tag":63,"props":195,"children":196},{"__ignoreMap":60},[197,215,247],{"type":41,"tag":67,"props":198,"children":199},{"class":69,"line":70},[200,204,209],{"type":41,"tag":67,"props":201,"children":202},{"style":74},[203],{"type":46,"value":4},{"type":41,"tag":67,"props":205,"children":206},{"style":94},[207],{"type":46,"value":208}," apps",{"type":41,"tag":67,"props":210,"children":212},{"style":211},"--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic",[213],{"type":46,"value":214},"                 # app inventory, compact JSON (--all adds system windows)\n",{"type":41,"tag":67,"props":216,"children":217},{"class":69,"line":90},[218,222,227,232,237,242],{"type":41,"tag":67,"props":219,"children":220},{"style":74},[221],{"type":46,"value":4},{"type":41,"tag":67,"props":223,"children":224},{"style":94},[225],{"type":46,"value":226}," see",{"type":41,"tag":67,"props":228,"children":229},{"style":79},[230],{"type":46,"value":231}," \"",{"type":41,"tag":67,"props":233,"children":234},{"style":94},[235],{"type":46,"value":236},"CC Switch",{"type":41,"tag":67,"props":238,"children":239},{"style":79},[240],{"type":46,"value":241},"\"",{"type":41,"tag":67,"props":243,"children":244},{"style":211},[245],{"type":46,"value":246},"      # one screenshot -> JSON with its \"path\"\n",{"type":41,"tag":67,"props":248,"children":249},{"class":69,"line":29},[250,254,259,263,268,272],{"type":41,"tag":67,"props":251,"children":252},{"style":74},[253],{"type":46,"value":4},{"type":41,"tag":67,"props":255,"children":256},{"style":94},[257],{"type":46,"value":258}," state",{"type":41,"tag":67,"props":260,"children":261},{"style":79},[262],{"type":46,"value":231},{"type":41,"tag":67,"props":264,"children":265},{"style":94},[266],{"type":46,"value":267},"Notepad",{"type":41,"tag":67,"props":269,"children":270},{"style":79},[271],{"type":46,"value":241},{"type":41,"tag":67,"props":273,"children":274},{"style":211},[275],{"type":46,"value":276},"      # UIA tree as JSON (--screenshot adds image)\n",{"type":41,"tag":49,"props":278,"children":279},{},[280,282,288],{"type":46,"value":281},"Anything multi-step — write a ",{"type":41,"tag":63,"props":283,"children":285},{"className":284},[],[286],{"type":46,"value":287},".py",{"type":46,"value":289}," file, then run it. No quoting or encoding\ntraps in any shell; this is always the most reliable channel:",{"type":41,"tag":55,"props":291,"children":293},{"className":57,"code":292,"language":59,"meta":60,"style":60},"windows-harness run task.py          # win, browser, Path, subprocess preloaded\n",[294],{"type":41,"tag":63,"props":295,"children":296},{"__ignoreMap":60},[297],{"type":41,"tag":67,"props":298,"children":299},{"class":69,"line":70},[300,304,309,314],{"type":41,"tag":67,"props":301,"children":302},{"style":74},[303],{"type":46,"value":4},{"type":41,"tag":67,"props":305,"children":306},{"style":94},[307],{"type":46,"value":308}," run",{"type":41,"tag":67,"props":310,"children":311},{"style":94},[312],{"type":46,"value":313}," task.py",{"type":41,"tag":67,"props":315,"children":316},{"style":211},[317],{"type":46,"value":318},"          # win, browser, Path, subprocess preloaded\n",{"type":41,"tag":49,"props":320,"children":321},{},[322,324,330,332,338,340,346,348,354,356,362,364,370,372,378,380,386,388,393,395,401],{"type":46,"value":323},"Write generated task scripts to the harness scripts dir (printed by\n",{"type":41,"tag":63,"props":325,"children":327},{"className":326},[],[328],{"type":46,"value":329},"windows-harness doctor",{"type":46,"value":331}," as ",{"type":41,"tag":63,"props":333,"children":335},{"className":334},[],[336],{"type":46,"value":337},"scripts_dir",{"type":46,"value":339},", default\n",{"type":41,"tag":63,"props":341,"children":343},{"className":342},[],[344],{"type":46,"value":345},"%USERPROFILE%\\.windows-harness\\scripts",{"type":46,"value":347},"); ",{"type":41,"tag":63,"props":349,"children":351},{"className":350},[],[352],{"type":46,"value":353},"run",{"type":46,"value":355}," resolves bare filenames\nthere. Never write task scripts into the caller's working directory or\ninvent ad-hoc folders like ",{"type":41,"tag":63,"props":357,"children":359},{"className":358},[],[360],{"type":46,"value":361},".windows-harness-temp\u002F",{"type":46,"value":363}," — they pollute the\nuser's repo and show up as untracked files. Never run them via\n",{"type":41,"tag":63,"props":365,"children":367},{"className":366},[],[368],{"type":46,"value":369},"python script.py",{"type":46,"value":371}," \u002F ",{"type":41,"tag":63,"props":373,"children":375},{"className":374},[],[376],{"type":46,"value":377},"python -c",{"type":46,"value":379}," either: bypassing ",{"type":41,"tag":63,"props":381,"children":383},{"className":382},[],[384],{"type":46,"value":385},"windows-harness run",{"type":46,"value":387},"\nalso bypasses the preloaded ",{"type":41,"tag":63,"props":389,"children":391},{"className":390},[],[392],{"type":46,"value":143},{"type":46,"value":394}," session, so every call pays a fresh\ninterpreter start and loses the element table behind ",{"type":41,"tag":63,"props":396,"children":398},{"className":397},[],[399],{"type":46,"value":400},"element_index",{"type":46,"value":402},".",{"type":41,"tag":49,"props":404,"children":405},{},[406,408,414,416,422,424,430,432,438,440,446],{"type":46,"value":407},"Never use ",{"type":41,"tag":63,"props":409,"children":411},{"className":410},[],[412],{"type":46,"value":413},"\u003C\u003C'PY'",{"type":46,"value":415}," heredocs outside bash; never enumerate windows through\nhand-rolled C#\u002FPowerShell — ",{"type":41,"tag":63,"props":417,"children":419},{"className":418},[],[420],{"type":46,"value":421},"win.list_apps()",{"type":46,"value":423}," already did it. Screenshots\nland in ",{"type":41,"tag":63,"props":425,"children":427},{"className":426},[],[428],{"type":46,"value":429},"%TEMP%\\windows-harness-*.png",{"type":46,"value":431}," and persist: the returned ",{"type":41,"tag":63,"props":433,"children":435},{"className":434},[],[436],{"type":46,"value":437},"\"path\"",{"type":46,"value":439},"\nstays readable after the CLI exits, so just open it. Set\n",{"type":41,"tag":63,"props":441,"children":443},{"className":442},[],[444],{"type":46,"value":445},"WINDOWS_HARNESS_OVERLAY=off",{"type":46,"value":447}," to skip the pointer renderer for minimum\nlatency.",{"type":41,"tag":179,"props":449,"children":451},{"id":450},"delivery-foreground-first",[452],{"type":46,"value":453},"Delivery: foreground first",{"type":41,"tag":49,"props":455,"children":456},{},[457,459,465,467,473],{"type":46,"value":458},"Every input primitive takes ",{"type":41,"tag":63,"props":460,"children":462},{"className":461},[],[463],{"type":46,"value":464},"delivery=\"foreground\"",{"type":46,"value":466}," (default) or\n",{"type":41,"tag":63,"props":468,"children":470},{"className":469},[],[471],{"type":46,"value":472},"delivery=\"background\"",{"type":46,"value":402},{"type":41,"tag":475,"props":476,"children":477},"table",{},[478,502],{"type":41,"tag":479,"props":480,"children":481},"thead",{},[482],{"type":41,"tag":483,"props":484,"children":485},"tr",{},[486,492,497],{"type":41,"tag":487,"props":488,"children":489},"th",{},[490],{"type":46,"value":491},"mode",{"type":41,"tag":487,"props":493,"children":494},{},[495],{"type":46,"value":496},"transports",{"type":41,"tag":487,"props":498,"children":499},{},[500],{"type":46,"value":501},"disturbance",{"type":41,"tag":503,"props":504,"children":505},"tbody",{},[506,545],{"type":41,"tag":483,"props":507,"children":508},{},[509,521,526],{"type":41,"tag":510,"props":511,"children":512},"td",{},[513,519],{"type":41,"tag":63,"props":514,"children":516},{"className":515},[],[517],{"type":46,"value":518},"foreground",{"type":46,"value":520}," (default)",{"type":41,"tag":510,"props":522,"children":523},{},[524],{"type":46,"value":525},"front the target + SendInput; pen\u002Fmessage fallback when hook software swallows SendInput",{"type":41,"tag":510,"props":527,"children":528},{},[529,531,537,539],{"type":46,"value":530},"the target comes to the front and STAYS (",{"type":41,"tag":63,"props":532,"children":534},{"className":533},[],[535],{"type":46,"value":536},"hold=True",{"type":46,"value":538},") until ",{"type":41,"tag":63,"props":540,"children":542},{"className":541},[],[543],{"type":46,"value":544},"win.release()",{"type":41,"tag":483,"props":546,"children":547},{},[548,557,562],{"type":41,"tag":510,"props":549,"children":550},{},[551],{"type":41,"tag":63,"props":552,"children":554},{"className":553},[],[555],{"type":46,"value":556},"background",{"type":41,"tag":510,"props":558,"children":559},{},[560],{"type":46,"value":561},"synthetic-pen injection, PostMessage, UIA patterns",{"type":41,"tag":510,"props":563,"children":564},{},[565],{"type":46,"value":566},"none — never fronts, never moves the cursor",{"type":41,"tag":49,"props":568,"children":569},{},[570],{"type":46,"value":571},"Why foreground is the default: focus-driven UI (search boxes with suggestion\npopups, context menus, IME candidate windows) closes the instant its window\nloses the foreground, and CEF off-screen \u002F XAML input stacks only accept\nmessage input while truly foreground and focused. Holding the foreground\nacross a burst turns \"sometimes works\" into a procedure.",{"type":41,"tag":573,"props":574,"children":575},"ul",{},[576,587,606,611,652],{"type":41,"tag":577,"props":578,"children":579},"li",{},[580,585],{"type":41,"tag":63,"props":581,"children":583},{"className":582},[],[584],{"type":46,"value":544},{"type":46,"value":586}," hands the foreground back to the user's previous window.\nCall it when a task burst is done.",{"type":41,"tag":577,"props":588,"children":589},{},[590,592,598,600,605],{"type":46,"value":591},"For one quick invisible action use ",{"type":41,"tag":63,"props":593,"children":595},{"className":594},[],[596],{"type":46,"value":597},"delivery=\"foreground\", hold=False",{"type":46,"value":599},"\n(cloaked ~150 ms takeover, restored after) or ",{"type":41,"tag":63,"props":601,"children":603},{"className":602},[],[604],{"type":46,"value":472},{"type":46,"value":402},{"type":41,"tag":577,"props":607,"children":608},{},[609],{"type":46,"value":610},"Foreground clicks use SendInput mouse events and do NOT summon the Windows\ntouch keyboard; synthetic pen\u002Ftouch injection (background clicks) can pop\nit up and wreck the focus chain — avoid pen taps into text fields.",{"type":41,"tag":577,"props":612,"children":613},{},[614,619,621,627,629,635,637,643,645,650],{"type":41,"tag":63,"props":615,"children":617},{"className":616},[],[618],{"type":46,"value":556},{"type":46,"value":620}," results carry ",{"type":41,"tag":63,"props":622,"children":624},{"className":623},[],[625],{"type":46,"value":626},"\"mode\": \"pen\" | \"message\"",{"type":46,"value":628}," plus\n",{"type":41,"tag":63,"props":630,"children":632},{"className":631},[],[633],{"type":46,"value":634},"\"verified\": false",{"type":46,"value":636}," when the effect cannot be confirmed. When a framework's\ninput stack silently drops background events the call raises\n",{"type":41,"tag":63,"props":638,"children":640},{"className":639},[],[641],{"type":46,"value":642},"BackgroundUnavailable",{"type":46,"value":644}," with a structured ",{"type":41,"tag":63,"props":646,"children":648},{"className":647},[],[649],{"type":46,"value":63},{"type":46,"value":651},"; redo the SAME action with\ndefault foreground delivery — do not probe more background transports.",{"type":41,"tag":577,"props":653,"children":654},{},[655,660,662,668,670,676,678,684,686,692,694,700],{"type":41,"tag":63,"props":656,"children":658},{"className":657},[],[659],{"type":46,"value":329},{"type":46,"value":661}," reports ",{"type":41,"tag":63,"props":663,"children":665},{"className":664},[],[666],{"type":46,"value":667},"input_health.sendinput",{"type":46,"value":669},": ",{"type":41,"tag":63,"props":671,"children":673},{"className":672},[],[674],{"type":46,"value":675},"ok",{"type":46,"value":677},",\n",{"type":41,"tag":63,"props":679,"children":681},{"className":680},[],[682],{"type":46,"value":683},"swallowed",{"type":46,"value":685}," (hook software such as audio enhancers or overlay recorders is\neating injected events — suspects under ",{"type":41,"tag":63,"props":687,"children":689},{"className":688},[],[690],{"type":46,"value":691},"possible_injectors",{"type":46,"value":693},"), or\n",{"type":41,"tag":63,"props":695,"children":697},{"className":696},[],[698],{"type":46,"value":699},"unknown",{"type":46,"value":701},". When SendInput is swallowed, foreground actions automatically\nfall back to pen\u002Fmessage transports against the now-foreground target.",{"type":41,"tag":179,"props":703,"children":705},{"id":704},"use-the-small-surface",[706],{"type":46,"value":707},"Use the small surface",{"type":41,"tag":49,"props":709,"children":710},{},[711,713,719,720,726,727,733,734,740,741,747,748,754,755,761,763,768,770,776],{"type":46,"value":712},"Think in seven verbs: ",{"type":41,"tag":63,"props":714,"children":716},{"className":715},[],[717],{"type":46,"value":718},"see",{"type":46,"value":153},{"type":41,"tag":63,"props":721,"children":723},{"className":722},[],[724],{"type":46,"value":725},"key",{"type":46,"value":153},{"type":41,"tag":63,"props":728,"children":730},{"className":729},[],[731],{"type":46,"value":732},"type",{"type":46,"value":153},{"type":41,"tag":63,"props":735,"children":737},{"className":736},[],[738],{"type":46,"value":739},"click",{"type":46,"value":153},{"type":41,"tag":63,"props":742,"children":744},{"className":743},[],[745],{"type":46,"value":746},"paste",{"type":46,"value":153},{"type":41,"tag":63,"props":749,"children":751},{"className":750},[],[752],{"type":46,"value":753},"ax",{"type":46,"value":153},{"type":41,"tag":63,"props":756,"children":758},{"className":757},[],[759],{"type":46,"value":760},"script",{"type":46,"value":762},"\n— plus two inventory calls: ",{"type":41,"tag":63,"props":764,"children":766},{"className":765},[],[767],{"type":46,"value":421},{"type":46,"value":769}," (processes with their window\ntitles) and ",{"type":41,"tag":63,"props":771,"children":773},{"className":772},[],[774],{"type":46,"value":775},"win.windows(app)",{"type":46,"value":777}," (one app's windows).",{"type":41,"tag":55,"props":779,"children":783},{"className":780,"code":781,"language":782,"meta":60,"style":60},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","frame = win.see(\"Notepad\")\nwin.key(\"ctrl+s\", app=\"Notepad\")\nwin.type(\"Alessia Cara\", app=\"Notepad\")                    # type at the focused field\nwin.type(\"Alessia Cara\", app=\"Notepad\", x=640, y=420)      # click the field, then type\nwin.click(640, 420, app=\"Notepad\")\nwin.click(640, 420, app=\"Notepad\", clicks=2)               # double click\nwin.click(640, 420, app=\"Notepad\", button=\"right\")         # context menu\nwin.drag(200, 300, 500, 600, app=\"Notepad\")                # press, glide, release\nwin.scroll(-720, app=\"Notepad\")                            # wheel at window center (or x\u002Fy)\nwin.hover(640, 420, app=\"Notepad\")                         # really hover -> tooltip appears\nwin.paste(\"Alessia Cara\", app=\"Notepad\")                   # clipboard paste (see ladder)\nwin.release()                                              # hand the foreground back\n\nitem = win.ax.at(640, 420, app=\"Notepad\")\nwin.ax.perform(item[\"element_index\"], \"invoke\")\nwin.ax.click(item[\"element_index\"])      # click the element's center — no coordinates\nwin.ax.hover(item[\"element_index\"])      # hover it so its tooltip fires\n\nwin.script(\"Get-Process | Select-Object -First 3 Name\")\n","python",[784],{"type":41,"tag":63,"props":785,"children":786},{"__ignoreMap":60},[787,795,803,811,819,827,835,844,853,862,871,880,889,899,908,917,926,935,943],{"type":41,"tag":67,"props":788,"children":789},{"class":69,"line":70},[790],{"type":41,"tag":67,"props":791,"children":792},{},[793],{"type":46,"value":794},"frame = win.see(\"Notepad\")\n",{"type":41,"tag":67,"props":796,"children":797},{"class":69,"line":90},[798],{"type":41,"tag":67,"props":799,"children":800},{},[801],{"type":46,"value":802},"win.key(\"ctrl+s\", app=\"Notepad\")\n",{"type":41,"tag":67,"props":804,"children":805},{"class":69,"line":29},[806],{"type":41,"tag":67,"props":807,"children":808},{},[809],{"type":46,"value":810},"win.type(\"Alessia Cara\", app=\"Notepad\")                    # type at the focused field\n",{"type":41,"tag":67,"props":812,"children":813},{"class":69,"line":108},[814],{"type":41,"tag":67,"props":815,"children":816},{},[817],{"type":46,"value":818},"win.type(\"Alessia Cara\", app=\"Notepad\", x=640, y=420)      # click the field, then type\n",{"type":41,"tag":67,"props":820,"children":821},{"class":69,"line":117},[822],{"type":41,"tag":67,"props":823,"children":824},{},[825],{"type":46,"value":826},"win.click(640, 420, app=\"Notepad\")\n",{"type":41,"tag":67,"props":828,"children":829},{"class":69,"line":126},[830],{"type":41,"tag":67,"props":831,"children":832},{},[833],{"type":46,"value":834},"win.click(640, 420, app=\"Notepad\", clicks=2)               # double click\n",{"type":41,"tag":67,"props":836,"children":838},{"class":69,"line":837},7,[839],{"type":41,"tag":67,"props":840,"children":841},{},[842],{"type":46,"value":843},"win.click(640, 420, app=\"Notepad\", button=\"right\")         # context menu\n",{"type":41,"tag":67,"props":845,"children":847},{"class":69,"line":846},8,[848],{"type":41,"tag":67,"props":849,"children":850},{},[851],{"type":46,"value":852},"win.drag(200, 300, 500, 600, app=\"Notepad\")                # press, glide, release\n",{"type":41,"tag":67,"props":854,"children":856},{"class":69,"line":855},9,[857],{"type":41,"tag":67,"props":858,"children":859},{},[860],{"type":46,"value":861},"win.scroll(-720, app=\"Notepad\")                            # wheel at window center (or x\u002Fy)\n",{"type":41,"tag":67,"props":863,"children":865},{"class":69,"line":864},10,[866],{"type":41,"tag":67,"props":867,"children":868},{},[869],{"type":46,"value":870},"win.hover(640, 420, app=\"Notepad\")                         # really hover -> tooltip appears\n",{"type":41,"tag":67,"props":872,"children":874},{"class":69,"line":873},11,[875],{"type":41,"tag":67,"props":876,"children":877},{},[878],{"type":46,"value":879},"win.paste(\"Alessia Cara\", app=\"Notepad\")                   # clipboard paste (see ladder)\n",{"type":41,"tag":67,"props":881,"children":883},{"class":69,"line":882},12,[884],{"type":41,"tag":67,"props":885,"children":886},{},[887],{"type":46,"value":888},"win.release()                                              # hand the foreground back\n",{"type":41,"tag":67,"props":890,"children":892},{"class":69,"line":891},13,[893],{"type":41,"tag":67,"props":894,"children":896},{"emptyLinePlaceholder":895},true,[897],{"type":46,"value":898},"\n",{"type":41,"tag":67,"props":900,"children":902},{"class":69,"line":901},14,[903],{"type":41,"tag":67,"props":904,"children":905},{},[906],{"type":46,"value":907},"item = win.ax.at(640, 420, app=\"Notepad\")\n",{"type":41,"tag":67,"props":909,"children":911},{"class":69,"line":910},15,[912],{"type":41,"tag":67,"props":913,"children":914},{},[915],{"type":46,"value":916},"win.ax.perform(item[\"element_index\"], \"invoke\")\n",{"type":41,"tag":67,"props":918,"children":920},{"class":69,"line":919},16,[921],{"type":41,"tag":67,"props":922,"children":923},{},[924],{"type":46,"value":925},"win.ax.click(item[\"element_index\"])      # click the element's center — no coordinates\n",{"type":41,"tag":67,"props":927,"children":929},{"class":69,"line":928},17,[930],{"type":41,"tag":67,"props":931,"children":932},{},[933],{"type":46,"value":934},"win.ax.hover(item[\"element_index\"])      # hover it so its tooltip fires\n",{"type":41,"tag":67,"props":936,"children":938},{"class":69,"line":937},18,[939],{"type":41,"tag":67,"props":940,"children":941},{"emptyLinePlaceholder":895},[942],{"type":46,"value":898},{"type":41,"tag":67,"props":944,"children":946},{"class":69,"line":945},19,[947],{"type":41,"tag":67,"props":948,"children":949},{},[950],{"type":46,"value":951},"win.script(\"Get-Process | Select-Object -First 3 Name\")\n",{"type":41,"tag":49,"props":953,"children":954},{},[955,961,963,969,971,977,979,985,987,993,994,1000,1002,1007],{"type":41,"tag":63,"props":956,"children":958},{"className":957},[],[959],{"type":46,"value":960},"win.click()",{"type":46,"value":962}," is raw coordinate input; it never guesses a UIA action. For\nsemantic actions use ",{"type":41,"tag":63,"props":964,"children":966},{"className":965},[],[967],{"type":46,"value":968},"win.ax.at()",{"type":46,"value":970}," + ",{"type":41,"tag":63,"props":972,"children":974},{"className":973},[],[975],{"type":46,"value":976},"win.ax.perform()",{"type":46,"value":978},", and fill text fields\nwith ",{"type":41,"tag":63,"props":980,"children":982},{"className":981},[],[983],{"type":46,"value":984},"win.ax.set_value()",{"type":46,"value":986}," (verified by read-back) when an element exposes a\nValuePattern — no keystrokes at all. ",{"type":41,"tag":63,"props":988,"children":990},{"className":989},[],[991],{"type":46,"value":992},"win.ax.click()",{"type":46,"value":371},{"type":41,"tag":63,"props":995,"children":997},{"className":996},[],[998],{"type":46,"value":999},"win.ax.hover()",{"type":46,"value":1001}," act\non the element's own BoundingRectangle center: coordinates never leave the\nharness, so no coordinate-space mismatch is possible — prefer them over\ncopying frame values into ",{"type":41,"tag":63,"props":1003,"children":1005},{"className":1004},[],[1006],{"type":46,"value":960},{"type":46,"value":1008}," yourself.",{"type":41,"tag":49,"props":1010,"children":1011},{},[1012,1018,1020,1026,1028,1034],{"type":41,"tag":63,"props":1013,"children":1015},{"className":1014},[],[1016],{"type":46,"value":1017},"win.hover(x, y)",{"type":46,"value":1019}," delivers a real hover (physical cursor, or pen hover when\nSendInput is filtered) so tooltips and hover-only UI appear; ",{"type":41,"tag":63,"props":1021,"children":1023},{"className":1022},[],[1024],{"type":46,"value":1025},"win.move(x, y)",{"type":46,"value":1027},"\nonly animates the virtual pointer and delivers no input. Hover is\ncoordinate-routed — the target needs to be unoccluded, not foreground — and\nthe cursor stays put so the tooltip survives long enough for a ",{"type":41,"tag":63,"props":1029,"children":1031},{"className":1030},[],[1032],{"type":46,"value":1033},"win.see()",{"type":46,"value":402},{"type":41,"tag":179,"props":1036,"children":1038},{"id":1037},"modal-dialogs-and-overlays",[1039],{"type":46,"value":1040},"Modal dialogs and overlays",{"type":41,"tag":49,"props":1042,"children":1043},{},[1044,1050,1052,1058,1060,1065],{"type":41,"tag":63,"props":1045,"children":1047},{"className":1046},[],[1048],{"type":46,"value":1049},"win.see(app)",{"type":46,"value":1051}," is ",{"type":41,"tag":1053,"props":1054,"children":1055},"strong",{},[1056],{"type":46,"value":1057},"window-scoped",{"type":46,"value":1059},": it captures only that one window's client\narea, so an overlay sitting on top (a Save As \u002F Open \u002F Print dialog, a\nconfirm prompt) is ",{"type":41,"tag":1053,"props":1061,"children":1062},{},[1063],{"type":46,"value":1064},"not",{"type":46,"value":1066}," in the shot even though it is on screen. To see a\npopup that just appeared, do not guess its title:",{"type":41,"tag":55,"props":1068,"children":1070},{"className":780,"code":1069,"language":782,"meta":60,"style":60},"win.key(\"ctrl+s\", app=\"Notepad\")        # an untitled doc opens Save As\nfg = win.foreground_window()            # the dialog's title\u002Fhwnd\nframe = win.see(fg[\"hwnd\"])             # capture the dialog itself\n# or grab the whole desktop, which sees every window at once:\ndesktop = win.capture_screen()\n",[1071],{"type":41,"tag":63,"props":1072,"children":1073},{"__ignoreMap":60},[1074,1082,1090,1098,1106],{"type":41,"tag":67,"props":1075,"children":1076},{"class":69,"line":70},[1077],{"type":41,"tag":67,"props":1078,"children":1079},{},[1080],{"type":46,"value":1081},"win.key(\"ctrl+s\", app=\"Notepad\")        # an untitled doc opens Save As\n",{"type":41,"tag":67,"props":1083,"children":1084},{"class":69,"line":90},[1085],{"type":41,"tag":67,"props":1086,"children":1087},{},[1088],{"type":46,"value":1089},"fg = win.foreground_window()            # the dialog's title\u002Fhwnd\n",{"type":41,"tag":67,"props":1091,"children":1092},{"class":69,"line":29},[1093],{"type":41,"tag":67,"props":1094,"children":1095},{},[1096],{"type":46,"value":1097},"frame = win.see(fg[\"hwnd\"])             # capture the dialog itself\n",{"type":41,"tag":67,"props":1099,"children":1100},{"class":69,"line":108},[1101],{"type":41,"tag":67,"props":1102,"children":1103},{},[1104],{"type":46,"value":1105},"# or grab the whole desktop, which sees every window at once:\n",{"type":41,"tag":67,"props":1107,"children":1108},{"class":69,"line":117},[1109],{"type":41,"tag":67,"props":1110,"children":1111},{},[1112],{"type":46,"value":1113},"desktop = win.capture_screen()\n",{"type":41,"tag":49,"props":1115,"children":1116},{},[1117,1123,1125,1131,1133,1138],{"type":41,"tag":63,"props":1118,"children":1120},{"className":1119},[],[1121],{"type":46,"value":1122},"win.capture_screen()",{"type":46,"value":1124}," captures the entire virtual desktop (all monitors) and\nits screenshot-space coordinates pair with ",{"type":41,"tag":63,"props":1126,"children":1128},{"className":1127},[],[1129],{"type":46,"value":1130},"coordinate_space=\"screen\"",{"type":46,"value":1132},". A bare\n",{"type":41,"tag":63,"props":1134,"children":1136},{"className":1135},[],[1137],{"type":46,"value":1033},{"type":46,"value":1139}," with no app now targets the foreground window, so it also catches a\nmodal that is currently in front.",{"type":41,"tag":49,"props":1141,"children":1142},{},[1143,1149,1151,1156,1158,1163],{"type":41,"tag":63,"props":1144,"children":1146},{"className":1145},[],[1147],{"type":46,"value":1148},"win.see(app, bring_to_front=True)",{"type":46,"value":1150}," fronts the target and keeps it fronted\n(restoring it if minimized) until ",{"type":41,"tag":63,"props":1152,"children":1154},{"className":1153},[],[1155],{"type":46,"value":544},{"type":46,"value":1157},"; the default is a quiet\nbackground grab that never raises or activates the window, so ",{"type":41,"tag":63,"props":1159,"children":1161},{"className":1160},[],[1162],{"type":46,"value":718},{"type":46,"value":1164}," stays\nnon-intrusive unless you opt in.",{"type":41,"tag":179,"props":1166,"children":1168},{"id":1167},"text-input-ladder",[1169],{"type":46,"value":1170},"Text input ladder",{"type":41,"tag":1172,"props":1173,"children":1174},"ol",{},[1175,1185,1196,1215,1220],{"type":41,"tag":577,"props":1176,"children":1177},{},[1178,1183],{"type":41,"tag":63,"props":1179,"children":1181},{"className":1180},[],[1182],{"type":46,"value":984},{"type":46,"value":1184}," when the element exposes a ValuePattern — verified by\nread-back and works fully in the background.",{"type":41,"tag":577,"props":1186,"children":1187},{},[1188,1194],{"type":41,"tag":63,"props":1189,"children":1191},{"className":1190},[],[1192],{"type":46,"value":1193},"win.type(text, x=..., y=...)",{"type":46,"value":1195}," — focuses the field and types in one call.",{"type":41,"tag":577,"props":1197,"children":1198},{},[1199,1205,1207,1213],{"type":41,"tag":63,"props":1200,"children":1202},{"className":1201},[],[1203],{"type":46,"value":1204},"win.paste(text)",{"type":46,"value":1206}," — the clipboard route. Setting the clipboard is a plain\ndata handoff no hook software can filter; only the paste trigger needs\ninput (SendInput Ctrl+V, or a posted WM_PASTE when SendInput is filtered —\nnever a posted Ctrl+V, whose modifier never reaches GetKeyState). Focus\nthe target field first (a click, or ",{"type":41,"tag":63,"props":1208,"children":1210},{"className":1209},[],[1211],{"type":46,"value":1212},"win.type",{"type":46,"value":1214}," with x\u002Fy).",{"type":41,"tag":577,"props":1216,"children":1217},{},[1218],{"type":46,"value":1219},"If the paste trigger also fails: right-click the field and click the\ncontext menu's Paste item (pen injection can drive the menu).",{"type":41,"tag":577,"props":1221,"children":1222},{},[1223,1225,1231,1232,1238,1240,1245],{"type":46,"value":1224},"When ",{"type":41,"tag":63,"props":1226,"children":1228},{"className":1227},[],[1229],{"type":46,"value":1230},"doctor",{"type":46,"value":661},{"type":41,"tag":63,"props":1233,"children":1235},{"className":1234},[],[1236],{"type":46,"value":1237},"input_health.sendinput == \"swallowed\"",{"type":46,"value":1239},", tell the\nuser which processes (",{"type":41,"tag":63,"props":1241,"children":1243},{"className":1242},[],[1244],{"type":46,"value":691},{"type":46,"value":1246},") are eating injected input —\nremoving the hook software is the real fix.",{"type":41,"tag":49,"props":1248,"children":1249},{},[1250,1256,1258,1264,1266,1272,1274,1279,1281,1287,1289,1295,1297,1303,1305,1311,1313,1319,1321,1327,1329,1335,1337,1343,1345,1351,1353,1358],{"type":41,"tag":63,"props":1251,"children":1253},{"className":1252},[],[1254],{"type":46,"value":1255},"win.type()",{"type":46,"value":1257}," reports what actually landed, not just that keystrokes were sent.\nXAML\u002FWinUI text boxes (Win11 Notepad, Settings) and CEF editors drop much of a\n",{"type":41,"tag":63,"props":1259,"children":1261},{"className":1260},[],[1262],{"type":46,"value":1263},"KEYEVENTF_UNICODE",{"type":46,"value":1265}," burst while claiming ",{"type":41,"tag":63,"props":1267,"children":1269},{"className":1268},[],[1270],{"type":46,"value":1271},"verified: True",{"type":46,"value":1273},"; the harness reads\nthe field back and, on a mismatch, retries via ",{"type":41,"tag":63,"props":1275,"children":1277},{"className":1276},[],[1278],{"type":46,"value":984},{"type":46,"value":1280}," (verified)\nor ",{"type":41,"tag":63,"props":1282,"children":1284},{"className":1283},[],[1285],{"type":46,"value":1286},"win.paste()",{"type":46,"value":1288},". If the result carries ",{"type":41,"tag":63,"props":1290,"children":1292},{"className":1291},[],[1293],{"type":46,"value":1294},"\"retried_via\"",{"type":46,"value":1296},", the keyboard route\ndropped characters and the retry landed them. The result's ",{"type":41,"tag":63,"props":1298,"children":1300},{"className":1299},[],[1301],{"type":46,"value":1302},"verified_via",{"type":46,"value":1304},"\nsays how ",{"type":41,"tag":63,"props":1306,"children":1308},{"className":1307},[],[1309],{"type":46,"value":1310},"verified",{"type":46,"value":1312}," was established: ",{"type":41,"tag":63,"props":1314,"children":1316},{"className":1315},[],[1317],{"type":46,"value":1318},"\"value_pattern\"",{"type":46,"value":1320},"\u002F",{"type":41,"tag":63,"props":1322,"children":1324},{"className":1323},[],[1325],{"type":46,"value":1326},"\"clipboard\"",{"type":46,"value":1328}," mean a\nread-back confirmed the text, ",{"type":41,"tag":63,"props":1330,"children":1332},{"className":1331},[],[1333],{"type":46,"value":1334},"\"transport\"",{"type":46,"value":1336}," means the target exposes no\nreadable text state and only delivery was confirmed. A ",{"type":41,"tag":63,"props":1338,"children":1340},{"className":1339},[],[1341],{"type":46,"value":1342},"verified: false",{"type":46,"value":1344}," with\na ",{"type":41,"tag":63,"props":1346,"children":1348},{"className":1347},[],[1349],{"type":46,"value":1350},"read_back",{"type":46,"value":1352}," field means the window accepted the keystrokes but the text did\nnot appear (e.g. an app-launch\u002Fsession-restore race) — click the field and\nretry, or switch to ",{"type":41,"tag":63,"props":1354,"children":1356},{"className":1355},[],[1357],{"type":46,"value":1286},{"type":46,"value":402},{"type":41,"tag":49,"props":1360,"children":1361},{},[1362,1364,1370,1372,1377,1379,1385,1387,1393],{"type":46,"value":1363},"Replacing a field's existing text: there is no reliable select-all keystroke\non hook-filtered machines (Ctrl+A is a combo and refuses; CEF ignores a\nposted Backspace). The dependable sequence is a triple click —\n",{"type":41,"tag":63,"props":1365,"children":1367},{"className":1366},[],[1368],{"type":46,"value":1369},"win.click(x, y, clicks=3)",{"type":46,"value":1371}," selects the field's text — then ",{"type":41,"tag":63,"props":1373,"children":1375},{"className":1374},[],[1376],{"type":46,"value":1212},{"type":46,"value":1378}," or\n",{"type":41,"tag":63,"props":1380,"children":1382},{"className":1381},[],[1383],{"type":46,"value":1384},"win.paste",{"type":46,"value":1386},", which replaces the selection. On machines with healthy\nSendInput, ",{"type":41,"tag":63,"props":1388,"children":1390},{"className":1389},[],[1391],{"type":46,"value":1392},"win.key(\"ctrl+a\")",{"type":46,"value":1394}," first is fine too.",{"type":41,"tag":49,"props":1396,"children":1397},{},[1398,1400,1406,1408,1414],{"type":46,"value":1399},"Bare keys vs combos: when SendInput is swallowed, ",{"type":41,"tag":63,"props":1401,"children":1403},{"className":1402},[],[1404],{"type":46,"value":1405},"win.key(\"enter\")",{"type":46,"value":1407}," and\nother modifier-less keys still work (posted to the foreground target); only\ncombos like ",{"type":41,"tag":63,"props":1409,"children":1411},{"className":1410},[],[1412],{"type":46,"value":1413},"ctrl+a",{"type":46,"value":1415}," refuse, honestly.",{"type":41,"tag":179,"props":1417,"children":1419},{"id":1418},"coordinates",[1420],{"type":46,"value":1421},"Coordinates",{"type":41,"tag":49,"props":1423,"children":1424},{},[1425,1431],{"type":41,"tag":63,"props":1426,"children":1428},{"className":1427},[],[1429],{"type":46,"value":1430},"coordinate_space",{"type":46,"value":1432}," accepts:",{"type":41,"tag":573,"props":1434,"children":1435},{},[1436,1469,1539],{"type":41,"tag":577,"props":1437,"children":1438},{},[1439,1445,1447,1452,1454,1460,1461,1467],{"type":41,"tag":63,"props":1440,"children":1442},{"className":1441},[],[1443],{"type":46,"value":1444},"'screenshot'",{"type":46,"value":1446}," (default) — pixels of the latest ",{"type":41,"tag":63,"props":1448,"children":1450},{"className":1449},[],[1451],{"type":46,"value":1033},{"type":46,"value":1453}," image; the\nreturned ",{"type":41,"tag":63,"props":1455,"children":1457},{"className":1456},[],[1458],{"type":46,"value":1459},"scale_x",{"type":46,"value":1320},{"type":41,"tag":63,"props":1462,"children":1464},{"className":1463},[],[1465],{"type":46,"value":1466},"scale_y",{"type":46,"value":1468}," map them to the window.",{"type":41,"tag":577,"props":1470,"children":1471},{},[1472,1478,1480,1485,1487,1510,1514,1516,1522,1524,1530,1532,1537],{"type":41,"tag":63,"props":1473,"children":1475},{"className":1474},[],[1476],{"type":46,"value":1477},"'normalized'",{"type":46,"value":1479}," — a 0..1000 grid over the client area of the window from the\nlatest ",{"type":41,"tag":63,"props":1481,"children":1483},{"className":1482},[],[1484],{"type":46,"value":1033},{"type":46,"value":1486},", independent of screenshot resolution and DPI; use\ndirectly when the model outputs normalized coordinates:",{"type":41,"tag":55,"props":1488,"children":1490},{"className":780,"code":1489,"language":782,"meta":60,"style":60},"frame = win.see(\"Notepad\")                          # anchors the window\nwin.click(500, 48, app=\"Notepad\", coordinate_space=\"normalized\")\n",[1491],{"type":41,"tag":63,"props":1492,"children":1493},{"__ignoreMap":60},[1494,1502],{"type":41,"tag":67,"props":1495,"children":1496},{"class":69,"line":70},[1497],{"type":41,"tag":67,"props":1498,"children":1499},{},[1500],{"type":46,"value":1501},"frame = win.see(\"Notepad\")                          # anchors the window\n",{"type":41,"tag":67,"props":1503,"children":1504},{"class":69,"line":90},[1505],{"type":41,"tag":67,"props":1506,"children":1507},{},[1508],{"type":46,"value":1509},"win.click(500, 48, app=\"Notepad\", coordinate_space=\"normalized\")\n",{"type":41,"tag":1511,"props":1512,"children":1513},"br",{},[],{"type":46,"value":1515},"The window's origin is resolved live at click time, so the window may move\nbetween ",{"type":41,"tag":63,"props":1517,"children":1519},{"className":1518},[],[1520],{"type":46,"value":1521},"see()",{"type":46,"value":1523}," and ",{"type":41,"tag":63,"props":1525,"children":1527},{"className":1526},[],[1528],{"type":46,"value":1529},"click()",{"type":46,"value":1531},"; only a resize invalidates the grid — take a\nfresh ",{"type":41,"tag":63,"props":1533,"children":1535},{"className":1534},[],[1536],{"type":46,"value":1521},{"type":46,"value":1538}," after any resize.",{"type":41,"tag":577,"props":1540,"children":1541},{},[1542,1548,1549,1555],{"type":41,"tag":63,"props":1543,"children":1545},{"className":1544},[],[1546],{"type":46,"value":1547},"'client'",{"type":46,"value":371},{"type":41,"tag":63,"props":1550,"children":1552},{"className":1551},[],[1553],{"type":46,"value":1554},"'screen'",{"type":46,"value":1556}," — raw window-client or physical screen pixels.",{"type":41,"tag":49,"props":1558,"children":1559},{},[1560,1562,1567,1568,1574,1575,1581,1582,1588,1590,1595,1597,1603,1605,1610],{"type":46,"value":1561},"Every positional primitive (",{"type":41,"tag":63,"props":1563,"children":1565},{"className":1564},[],[1566],{"type":46,"value":739},{"type":46,"value":153},{"type":41,"tag":63,"props":1569,"children":1571},{"className":1570},[],[1572],{"type":46,"value":1573},"double\u002Fright click",{"type":46,"value":153},{"type":41,"tag":63,"props":1576,"children":1578},{"className":1577},[],[1579],{"type":46,"value":1580},"drag",{"type":46,"value":153},{"type":41,"tag":63,"props":1583,"children":1585},{"className":1584},[],[1586],{"type":46,"value":1587},"scroll",{"type":46,"value":1589},"\nwith x\u002Fy, ",{"type":41,"tag":63,"props":1591,"children":1593},{"className":1592},[],[1594],{"type":46,"value":732},{"type":46,"value":1596}," with x\u002Fy, ",{"type":41,"tag":63,"props":1598,"children":1600},{"className":1599},[],[1601],{"type":46,"value":1602},"hover",{"type":46,"value":1604},") accepts ",{"type":41,"tag":63,"props":1606,"children":1608},{"className":1607},[],[1609],{"type":46,"value":1430},{"type":46,"value":1611},"; the\nnormalized grid works for all of them.",{"type":41,"tag":49,"props":1613,"children":1614},{},[1615,1617,1622,1624,1630,1632,1638,1640,1646,1648,1654,1656,1661,1663,1669,1671,1677],{"type":46,"value":1616},"Default to vision + normalized coordinates; only fall back to element centers\nfrom the ax tree when you need semantic identity or a layout shift makes a\ncoordinate fragile. ax output reports frames in the pixel space of your latest\n",{"type":41,"tag":63,"props":1618,"children":1620},{"className":1619},[],[1621],{"type":46,"value":1033},{"type":46,"value":1623}," screenshot of that window (the ",{"type":41,"tag":63,"props":1625,"children":1627},{"className":1626},[],[1628],{"type":46,"value":1629},"frame",{"type":46,"value":1631}," key, alongside\n",{"type":41,"tag":63,"props":1633,"children":1635},{"className":1634},[],[1636],{"type":46,"value":1637},"\"frame_space\": \"screenshot\"",{"type":46,"value":1639}," in ",{"type":41,"tag":63,"props":1641,"children":1643},{"className":1642},[],[1644],{"type":46,"value":1645},"state",{"type":46,"value":1647},"), so they drop straight into the\ndefault coordinate space. Without a matching screenshot the raw physical\nscreen pixels are reported under ",{"type":41,"tag":63,"props":1649,"children":1651},{"className":1650},[],[1652],{"type":46,"value":1653},"frame_screen",{"type":46,"value":1655}," instead — those only pair\nwith ",{"type":41,"tag":63,"props":1657,"children":1659},{"className":1658},[],[1660],{"type":46,"value":1130},{"type":46,"value":1662},", never the default. Cleanest of all is\nkeeping numbers out of the loop: ",{"type":41,"tag":63,"props":1664,"children":1666},{"className":1665},[],[1667],{"type":46,"value":1668},"win.ax.click(element_index)",{"type":46,"value":1670}," \u002F\n",{"type":41,"tag":63,"props":1672,"children":1674},{"className":1673},[],[1675],{"type":46,"value":1676},"win.ax.hover(element_index)",{"type":46,"value":402},{"type":41,"tag":49,"props":1679,"children":1680},{},[1681,1683,1689,1691,1697],{"type":46,"value":1682},"Target apps by exe name when titles can collide — resolution prefers an\nexact process-name match (",{"type":41,"tag":63,"props":1684,"children":1686},{"className":1685},[],[1687],{"type":46,"value":1688},"\"Discord.exe\"",{"type":46,"value":1690},", or bare ",{"type":41,"tag":63,"props":1692,"children":1694},{"className":1693},[],[1695],{"type":46,"value":1696},"\"Discord\"",{"type":46,"value":1698},"), then an\nexact title, and only then substrings, so a window whose title merely\nmentions the name (a VS Code tab titled \"… Discord …\") never hijacks the\nquery.",{"type":41,"tag":179,"props":1700,"children":1702},{"id":1701},"action-proof-look-only-when-it-misfires",[1703],{"type":46,"value":1704},"Action proof: look only when it misfires",{"type":41,"tag":49,"props":1706,"children":1707},{},[1708,1710,1715,1716,1721,1722,1727,1728,1733,1734,1739,1741,1747,1749,1755,1757,1763],{"type":46,"value":1709},"Every coordinate primitive (",{"type":41,"tag":63,"props":1711,"children":1713},{"className":1712},[],[1714],{"type":46,"value":739},{"type":46,"value":153},{"type":41,"tag":63,"props":1717,"children":1719},{"className":1718},[],[1720],{"type":46,"value":1580},{"type":46,"value":153},{"type":41,"tag":63,"props":1723,"children":1725},{"className":1724},[],[1726],{"type":46,"value":1587},{"type":46,"value":153},{"type":41,"tag":63,"props":1729,"children":1731},{"className":1730},[],[1732],{"type":46,"value":1602},{"type":46,"value":153},{"type":41,"tag":63,"props":1735,"children":1737},{"className":1736},[],[1738],{"type":46,"value":732},{"type":46,"value":1740}," with\nx\u002Fy) stamps the intended point back onto the screenshot it was anchored to and\nreturns the path under ",{"type":41,"tag":63,"props":1742,"children":1744},{"className":1743},[],[1745],{"type":46,"value":1746},"result[\"proof\"][\"path\"]",{"type":46,"value":1748},". The ",{"type":41,"tag":63,"props":1750,"children":1752},{"className":1751},[],[1753],{"type":46,"value":1754},"proof",{"type":46,"value":1756}," key is optional:\nit is present only when annotation is on (the default) and the proof was\nactually generated, so read it through ",{"type":41,"tag":63,"props":1758,"children":1760},{"className":1759},[],[1761],{"type":46,"value":1762},"result.get(\"proof\")",{"type":46,"value":1764}," before using it.",{"type":41,"tag":55,"props":1766,"children":1768},{"className":780,"code":1767,"language":782,"meta":60,"style":60},"out = win.click(640, 420, app=\"Notepad\")\nproof = out.get(\"proof\")\nprint(proof[\"path\"] if proof else \"no proof\")   # annotated PNG you can open\n",[1769],{"type":41,"tag":63,"props":1770,"children":1771},{"__ignoreMap":60},[1772,1780,1788],{"type":41,"tag":67,"props":1773,"children":1774},{"class":69,"line":70},[1775],{"type":41,"tag":67,"props":1776,"children":1777},{},[1778],{"type":46,"value":1779},"out = win.click(640, 420, app=\"Notepad\")\n",{"type":41,"tag":67,"props":1781,"children":1782},{"class":69,"line":90},[1783],{"type":41,"tag":67,"props":1784,"children":1785},{},[1786],{"type":46,"value":1787},"proof = out.get(\"proof\")\n",{"type":41,"tag":67,"props":1789,"children":1790},{"class":69,"line":29},[1791],{"type":41,"tag":67,"props":1792,"children":1793},{},[1794],{"type":46,"value":1795},"print(proof[\"path\"] if proof else \"no proof\")   # annotated PNG you can open\n",{"type":41,"tag":49,"props":1797,"children":1798},{},[1799,1801,1806,1807,1812,1813,1819,1820,1826,1827,1832,1834,1840,1842,1848],{"type":46,"value":1800},"It stays absent for non-coordinate primitives (",{"type":41,"tag":63,"props":1802,"children":1804},{"className":1803},[],[1805],{"type":46,"value":725},{"type":46,"value":153},{"type":41,"tag":63,"props":1808,"children":1810},{"className":1809},[],[1811],{"type":46,"value":746},{"type":46,"value":153},{"type":41,"tag":63,"props":1814,"children":1816},{"className":1815},[],[1817],{"type":46,"value":1818},"move",{"type":46,"value":677},{"type":41,"tag":63,"props":1821,"children":1823},{"className":1822},[],[1824],{"type":46,"value":1825},"ax.click",{"type":46,"value":153},{"type":41,"tag":63,"props":1828,"children":1830},{"className":1829},[],[1831],{"type":46,"value":718},{"type":46,"value":1833},") and for any call given ",{"type":41,"tag":63,"props":1835,"children":1837},{"className":1836},[],[1838],{"type":46,"value":1839},"annotate=False",{"type":46,"value":1841},", or when\n",{"type":41,"tag":63,"props":1843,"children":1845},{"className":1844},[],[1846],{"type":46,"value":1847},"WINDOWS_HARNESS_PROOF=off",{"type":46,"value":402},{"type":41,"tag":573,"props":1850,"children":1851},{},[1852,1876,1901],{"type":41,"tag":577,"props":1853,"children":1854},{},[1855,1860,1862,1867,1869,1874],{"type":41,"tag":63,"props":1856,"children":1858},{"className":1857},[],[1859],{"type":46,"value":739},{"type":46,"value":1861}," \u002F double \u002F right \u002F ",{"type":41,"tag":63,"props":1863,"children":1865},{"className":1864},[],[1866],{"type":46,"value":1602},{"type":46,"value":1868}," \u002F click-to-",{"type":41,"tag":63,"props":1870,"children":1872},{"className":1871},[],[1873],{"type":46,"value":732},{"type":46,"value":1875}," draw a red reticle\n(circle-cross) at the point, labelled with the button and count.",{"type":41,"tag":577,"props":1877,"children":1878},{},[1879,1884,1886,1892,1893,1899],{"type":41,"tag":63,"props":1880,"children":1882},{"className":1881},[],[1883],{"type":46,"value":1587},{"type":46,"value":1885}," draws an arrow from the anchor point (the window centre whenever\n",{"type":41,"tag":63,"props":1887,"children":1889},{"className":1888},[],[1890],{"type":46,"value":1891},"x",{"type":46,"value":1320},{"type":41,"tag":63,"props":1894,"children":1896},{"className":1895},[],[1897],{"type":46,"value":1898},"y",{"type":46,"value":1900}," are omitted) in the direction of the wheel delta.",{"type":41,"tag":577,"props":1902,"children":1903},{},[1904,1909],{"type":41,"tag":63,"props":1905,"children":1907},{"className":1906},[],[1908],{"type":46,"value":1580},{"type":46,"value":1910}," draws the glide as a blue line with a reticle at the start and a\nsquare at the end.",{"type":41,"tag":49,"props":1912,"children":1913},{},[1914,1916,1921],{"type":46,"value":1915},"Do NOT open the proof on every action — the input already ran. Open it only\nto decide WHY a coordinate action mis-landed: you aimed at the wrong spot, the\neffect did not happen, or you need to nudge a coordinate before retrying. A\nnormal ",{"type":41,"tag":63,"props":1917,"children":1919},{"className":1918},[],[1920],{"type":46,"value":1033},{"type":46,"value":1922}," on the finished step is the usual confirmation.",{"type":41,"tag":49,"props":1924,"children":1925},{},[1926,1928,1934,1936,1942,1944,1949,1951,1956],{"type":46,"value":1927},"The concrete trigger: an action reports success (or ",{"type":41,"tag":63,"props":1929,"children":1931},{"className":1930},[],[1932],{"type":46,"value":1933},"verified: true",{"type":46,"value":1935},") but\n",{"type":41,"tag":63,"props":1937,"children":1939},{"className":1938},[],[1940],{"type":46,"value":1941},"win.verify_change(app)",{"type":46,"value":1943}," says nothing changed, or a ",{"type":41,"tag":63,"props":1945,"children":1947},{"className":1946},[],[1948],{"type":46,"value":1033},{"type":46,"value":1950}," shows the page\nchanged in a way you did not expect. In that case open\n",{"type":41,"tag":63,"props":1952,"children":1954},{"className":1953},[],[1955],{"type":46,"value":1746},{"type":46,"value":1957}," FIRST — before retrying, nudging, or switching\ntransports. The reticle on the anchored screenshot tells you at a glance\nwhether the input even landed where you intended; guessing from coordinates\nalone just burns rounds.",{"type":41,"tag":49,"props":1959,"children":1960},{},[1961,1963,1969,1971,1977],{"type":46,"value":1962},"Forgot to print the proof path, or need an earlier one? Every proof is\njournaled to ",{"type":41,"tag":63,"props":1964,"children":1966},{"className":1965},[],[1967],{"type":46,"value":1968},"proofs.jsonl",{"type":46,"value":1970}," under the harness config dir (default\n",{"type":41,"tag":63,"props":1972,"children":1974},{"className":1973},[],[1975],{"type":46,"value":1976},"%USERPROFILE%\\.windows-harness",{"type":46,"value":1978},") as it is written, so history survives\nacross CLI invocations:",{"type":41,"tag":55,"props":1980,"children":1982},{"className":780,"code":1981,"language":782,"meta":60,"style":60},"win.last_proof()                      # newest proof whose PNG still exists\nwin.proofs(limit=5)                   # recent proofs, newest first\nwin.proofs(app=\"Notepad\", kind=\"click\")   # filter by process\u002Ftitle and kind\n",[1983],{"type":41,"tag":63,"props":1984,"children":1985},{"__ignoreMap":60},[1986,1994,2002],{"type":41,"tag":67,"props":1987,"children":1988},{"class":69,"line":70},[1989],{"type":41,"tag":67,"props":1990,"children":1991},{},[1992],{"type":46,"value":1993},"win.last_proof()                      # newest proof whose PNG still exists\n",{"type":41,"tag":67,"props":1995,"children":1996},{"class":69,"line":90},[1997],{"type":41,"tag":67,"props":1998,"children":1999},{},[2000],{"type":46,"value":2001},"win.proofs(limit=5)                   # recent proofs, newest first\n",{"type":41,"tag":67,"props":2003,"children":2004},{"class":69,"line":29},[2005],{"type":41,"tag":67,"props":2006,"children":2007},{},[2008],{"type":46,"value":2009},"win.proofs(app=\"Notepad\", kind=\"click\")   # filter by process\u002Ftitle and kind\n",{"type":41,"tag":49,"props":2011,"children":2012},{},[2013,2015,2021,2023,2029,2031,2037,2039,2044,2046,2051],{"type":46,"value":2014},"Each entry carries the same fields as ",{"type":41,"tag":63,"props":2016,"children":2018},{"className":2017},[],[2019],{"type":46,"value":2020},"result[\"proof\"]",{"type":46,"value":2022}," plus ",{"type":41,"tag":63,"props":2024,"children":2026},{"className":2025},[],[2027],{"type":46,"value":2028},"ts",{"type":46,"value":2030}," and the\ntarget ",{"type":41,"tag":63,"props":2032,"children":2034},{"className":2033},[],[2035],{"type":46,"value":2036},"app",{"type":46,"value":2038}," (process\u002Ftitle); entries whose PNG was cleaned up are skipped. Pass\n",{"type":41,"tag":63,"props":2040,"children":2042},{"className":2041},[],[2043],{"type":46,"value":1839},{"type":46,"value":2045}," to any primitive (or set ",{"type":41,"tag":63,"props":2047,"children":2049},{"className":2048},[],[2050],{"type":46,"value":1847},{"type":46,"value":2052},") to turn\nthe proof off for a coordinate you already know is good.",{"type":41,"tag":179,"props":2054,"children":2056},{"id":2055},"minimize-round-trips",[2057],{"type":46,"value":2058},"Minimize round trips",{"type":41,"tag":573,"props":2060,"children":2061},{},[2062,2067,2072,2077,2082],{"type":41,"tag":577,"props":2063,"children":2064},{},[2065],{"type":46,"value":2066},"Bundle deterministic, reversible steps into one program, then verify once.",{"type":41,"tag":577,"props":2068,"children":2069},{},[2070],{"type":46,"value":2071},"Stop at a genuine decision boundary: ambiguous identity, new coordinates, an\nirreversible action, or unexpected state.",{"type":41,"tag":577,"props":2073,"children":2074},{},[2075],{"type":46,"value":2076},"Do not screenshot merely to confirm a known shortcut opened a field before\ntyping; let the final screenshot verify the whole sequence.",{"type":41,"tag":577,"props":2078,"children":2079},{},[2080],{"type":46,"value":2081},"Poll exact UIA state inside the same Python program when possible.",{"type":41,"tag":577,"props":2083,"children":2084},{},[2085],{"type":46,"value":2086},"Use the cheapest strong end-state check: one screenshot for visible state,\none exact UIA query for semantic state.",{"type":41,"tag":179,"props":2088,"children":2090},{"id":2089},"choose-the-lowest-useful-mode",[2091],{"type":46,"value":2092},"Choose the lowest useful mode",{"type":41,"tag":49,"props":2094,"children":2095},{},[2096,2098,2103,2105,2111],{"type":46,"value":2097},"Vision-first: if you can read a screenshot, lead with ",{"type":41,"tag":63,"props":2099,"children":2101},{"className":2100},[],[2102],{"type":46,"value":1049},{"type":46,"value":2104}," +\nnormalized coordinates (a 0..1000 grid) instead of the UIA tree. Many apps\n(Electron\u002Fcustom-drawn UI, game launchers, some frameless and webview\nwindows) expose no usable UIA tree, and even when they do, screenshot +\ncoordinates need no per-app support. Reach for ",{"type":41,"tag":63,"props":2106,"children":2108},{"className":2107},[],[2109],{"type":46,"value":2110},"win.ax",{"type":46,"value":2112}," only when you need\nsemantic identity or state.",{"type":41,"tag":1172,"props":2114,"children":2115},{},[2116,2129,2149,2154,2210],{"type":41,"tag":577,"props":2117,"children":2118},{},[2119,2121,2127],{"type":46,"value":2120},"Use ",{"type":41,"tag":63,"props":2122,"children":2124},{"className":2123},[],[2125],{"type":46,"value":2126},"win.script()",{"type":46,"value":2128}," for a known exact command (Get-Process, registry reads).",{"type":41,"tag":577,"props":2130,"children":2131},{},[2132,2134,2139,2141,2147],{"type":46,"value":2133},"Otherwise use ",{"type":41,"tag":63,"props":2135,"children":2137},{"className":2136},[],[2138],{"type":46,"value":1049},{"type":46,"value":2140}," and vision: locate the target in the\nscreenshot, then act with ",{"type":41,"tag":63,"props":2142,"children":2144},{"className":2143},[],[2145],{"type":46,"value":2146},"coordinate_space=\"normalized\"",{"type":46,"value":2148}," (0..1000) so the\nnumbers are resolution\u002FDPI independent.",{"type":41,"tag":577,"props":2150,"children":2151},{},[2152],{"type":46,"value":2153},"Prefer a known keyboard route; use a verified coordinate for a visible,\nlow-risk target.",{"type":41,"tag":577,"props":2155,"children":2156},{},[2157,2159,2164,2166,2171,2172,2178,2179,2185,2187,2193,2195,2200,2202,2208],{"type":46,"value":2158},"Use targeted ",{"type":41,"tag":63,"props":2160,"children":2162},{"className":2161},[],[2163],{"type":46,"value":2110},{"type":46,"value":2165}," only when semantic identity or state matters. For\nCEF\u002FElectron custom-drawn UI (chat apps, music players, game launchers)\nthe tree fills lazily: ",{"type":41,"tag":63,"props":2167,"children":2169},{"className":2168},[],[2170],{"type":46,"value":1645},{"type":46,"value":1320},{"type":41,"tag":63,"props":2173,"children":2175},{"className":2174},[],[2176],{"type":46,"value":2177},"ax.query",{"type":46,"value":1320},{"type":41,"tag":63,"props":2180,"children":2182},{"className":2181},[],[2183],{"type":46,"value":2184},"ax.at",{"type":46,"value":2186}," automatically warm a\nnear-empty CEF tree with a brief (usually invisible, cloaked) foreground\nround, so warm it once if you truly need a semantic handle. Icon-only\ncontrols (server\u002Favatar images) often expose only generic names — hover\nthem (",{"type":41,"tag":63,"props":2188,"children":2190},{"className":2189},[],[2191],{"type":46,"value":2192},"win.ax.hover",{"type":46,"value":2194},") and read the tooltip from a ",{"type":41,"tag":63,"props":2196,"children":2198},{"className":2197},[],[2199],{"type":46,"value":1033},{"type":46,"value":2201},". If a dump\nstill comes back near-empty with a ",{"type":41,"tag":63,"props":2203,"children":2205},{"className":2204},[],[2206],{"type":46,"value":2207},"note",{"type":46,"value":2209},", go straight to screenshot +\nnormalized coordinate clicks instead of spending more rounds on UIA.",{"type":41,"tag":577,"props":2211,"children":2212},{},[2213,2214,2219],{"type":46,"value":2120},{"type":41,"tag":63,"props":2215,"children":2217},{"className":2216},[],[2218],{"type":46,"value":472},{"type":46,"value":2220}," only for apps already proven to accept it on\nthis machine (classic Win32 controls, UIA patterns) — it is the quiet\nopt-in, not the default to probe with.",{"type":41,"tag":49,"props":2222,"children":2223},{},[2224],{"type":46,"value":2225},"After a failed verified burst, switch mode or stop. Never repair uncertainty\nwith repeated keys, clicks, deletion loops, or bulk input.",{"type":41,"tag":179,"props":2227,"children":2229},{"id":2228},"verify-then-teach-the-matrix",[2230],{"type":46,"value":2231},"Verify, then teach the matrix",{"type":41,"tag":573,"props":2233,"children":2234},{},[2235,2268],{"type":41,"tag":577,"props":2236,"children":2237},{},[2238,2240,2245,2247,2252,2254,2259,2261,2266],{"type":46,"value":2239},"After a ",{"type":41,"tag":63,"props":2241,"children":2243},{"className":2242},[],[2244],{"type":46,"value":634},{"type":46,"value":2246}," action, confirm the effect with\n",{"type":41,"tag":63,"props":2248,"children":2250},{"className":2249},[],[2251],{"type":46,"value":1941},{"type":46,"value":2253}," — a background pixel diff that costs no focus and\nno vision round trip. Use a full ",{"type":41,"tag":63,"props":2255,"children":2257},{"className":2256},[],[2258],{"type":46,"value":1033},{"type":46,"value":2260}," only when you need to know\nWHAT changed, not THAT it changed. Animated windows (video, games) report\nchange on their own; verify those semantically through ",{"type":41,"tag":63,"props":2262,"children":2264},{"className":2263},[],[2265],{"type":46,"value":2110},{"type":46,"value":2267}," instead.",{"type":41,"tag":577,"props":2269,"children":2270},{},[2271,2273,2279,2281,2287],{"type":46,"value":2272},"When a background action provably had no effect (verify_change negative AND\nthe task did not advance), record it once with ",{"type":41,"tag":63,"props":2274,"children":2276},{"className":2275},[],[2277],{"type":46,"value":2278},"win.note_drop(kind)",{"type":46,"value":2280}," — e.g.\n",{"type":41,"tag":63,"props":2282,"children":2284},{"className":2283},[],[2285],{"type":46,"value":2286},"win.note_drop(\"text_input\", app=\"...\")",{"type":46,"value":2288},". Future background calls against\nthat window class refuse honestly instead of repeating a dead transport.",{"type":41,"tag":179,"props":2290,"children":2292},{"id":2291},"keep-the-invariants",[2293],{"type":46,"value":2294},"Keep the invariants",{"type":41,"tag":573,"props":2296,"children":2297},{},[2298,2317,2330,2343,2356,2361,2373,2393],{"type":41,"tag":577,"props":2299,"children":2300},{},[2301,2303,2308,2310,2315],{"type":46,"value":2302},"Foreground ",{"type":41,"tag":63,"props":2304,"children":2306},{"className":2305},[],[2307],{"type":46,"value":536},{"type":46,"value":2309}," keeps the target fronted across the whole burst;\nalways end a task with ",{"type":41,"tag":63,"props":2311,"children":2313},{"className":2312},[],[2314],{"type":46,"value":544},{"type":46,"value":2316}," (or leave the window fronted\ndeliberately and say so).",{"type":41,"tag":577,"props":2318,"children":2319},{},[2320,2322,2328],{"type":46,"value":2321},"Background delivery NEVER activates, raises, or moves the cursor. Occluded\ntargets refuse with ",{"type":41,"tag":63,"props":2323,"children":2325},{"className":2324},[],[2326],{"type":46,"value":2327},"background_occluded",{"type":46,"value":2329}," rather than being raised.",{"type":41,"tag":577,"props":2331,"children":2332},{},[2333,2335,2341],{"type":46,"value":2334},"ax queries against CEF\u002FElectron windows (",{"type":41,"tag":63,"props":2336,"children":2338},{"className":2337},[],[2339],{"type":46,"value":2340},"Chrome_WidgetWin*",{"type":46,"value":2342},") whose tree is\nnear-empty auto-warm it with a brief cloaked foreground takeover; the\nprevious foreground is restored when the warm-up round ends.",{"type":41,"tag":577,"props":2344,"children":2345},{},[2346,2348,2354],{"type":46,"value":2347},"Elevated (Administrator) targets are detected up front (UIPI preflight) and\nrefused with ",{"type":41,"tag":63,"props":2349,"children":2351},{"className":2350},[],[2352],{"type":46,"value":2353},"background_uipi_blocked",{"type":46,"value":2355},"; run the harness elevated to drive them.",{"type":41,"tag":577,"props":2357,"children":2358},{},[2359],{"type":46,"value":2360},"The animated pointer is click-through and never moves the physical cursor;\nnon-held foreground rungs move it briefly and put it back.",{"type":41,"tag":577,"props":2362,"children":2363},{},[2364,2366,2371],{"type":46,"value":2365},"Minimized windows are restored before foreground input and stay restored\nunder ",{"type":41,"tag":63,"props":2367,"children":2369},{"className":2368},[],[2370],{"type":46,"value":536},{"type":46,"value":2372},"; non-held foreground rungs re-minimize afterwards.",{"type":41,"tag":577,"props":2374,"children":2375},{},[2376,2378,2384,2386,2392],{"type":46,"value":2377},"Prefer semantic UIA patterns over simulated window chrome: frameworks that\ndraw their own titlebar (WinUI3, Electron) may ignore posted WM_CLOSE and\ncaption-button Invoke. The framework-neutral close is the WindowPattern —\n",{"type":41,"tag":63,"props":2379,"children":2381},{"className":2380},[],[2382],{"type":46,"value":2383},"win.ax.raw(i).GetWindowPattern().Close()",{"type":46,"value":2385}," — then answer the app's own\nconfirmation through ",{"type":41,"tag":63,"props":2387,"children":2389},{"className":2388},[],[2390],{"type":46,"value":2391},"ax.perform(..., \"invoke\")",{"type":46,"value":402},{"type":41,"tag":577,"props":2394,"children":2395},{},[2396,2398,2403],{"type":46,"value":2397},"XAML apps (Win11 Notepad, Settings, UWP frames) refuse background typing —\nuse ",{"type":41,"tag":63,"props":2399,"children":2401},{"className":2400},[],[2402],{"type":46,"value":984},{"type":46,"value":2404}," there; WPF refuses background drag and scroll —\nuse default foreground delivery.",{"type":41,"tag":179,"props":2406,"children":2408},{"id":2407},"browser-tasks",[2409],{"type":46,"value":2410},"Browser tasks",{"type":41,"tag":49,"props":2412,"children":2413},{},[2414,2416,2421],{"type":46,"value":2415},"Use the preloaded lazy ",{"type":41,"tag":63,"props":2417,"children":2419},{"className":2418},[],[2420],{"type":46,"value":151},{"type":46,"value":2422}," object whenever the task lives inside a web\npage. It exposes Browser Harness helpers and connects to the real browser on\nfirst use:",{"type":41,"tag":55,"props":2424,"children":2426},{"className":780,"code":2425,"language":782,"meta":60,"style":60},"print(browser.page_info())\nbrowser.new_tab(\"https:\u002F\u002Fexample.com\")\n",[2427],{"type":41,"tag":63,"props":2428,"children":2429},{"__ignoreMap":60},[2430,2438],{"type":41,"tag":67,"props":2431,"children":2432},{"class":69,"line":70},[2433],{"type":41,"tag":67,"props":2434,"children":2435},{},[2436],{"type":46,"value":2437},"print(browser.page_info())\n",{"type":41,"tag":67,"props":2439,"children":2440},{"class":69,"line":90},[2441],{"type":41,"tag":67,"props":2442,"children":2443},{},[2444],{"type":46,"value":2445},"browser.new_tab(\"https:\u002F\u002Fexample.com\")\n",{"type":41,"tag":49,"props":2447,"children":2448},{},[2449],{"type":46,"value":2450},"Do not substitute OS input for CDP inside web content; keep Windows primitives\nfor browser chrome, native dialogs, downloads, and everything outside the page.",{"type":41,"tag":49,"props":2452,"children":2453},{},[2454,2456,2461],{"type":46,"value":2455},"Run ",{"type":41,"tag":63,"props":2457,"children":2459},{"className":2458},[],[2460],{"type":46,"value":329},{"type":46,"value":2462}," to inspect the runtime without changing anything.",{"type":41,"tag":2464,"props":2465,"children":2466},"style",{},[2467],{"type":46,"value":2468},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":2470,"total":70},[2471],{"slug":4,"name":4,"fn":5,"description":6,"org":2472,"tags":2473,"stars":25,"repoUrl":26,"updatedAt":27},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2474,2475,2476,2477],{"name":13,"slug":14,"type":15},{"name":23,"slug":24,"type":15},{"name":20,"slug":21,"type":15},{"name":17,"slug":18,"type":15},{"items":2479,"total":919},[2480,2493,2506,2516,2527,2546,2567,2580,2597,2613,2631,2655],{"slug":8,"name":8,"fn":2481,"description":2482,"org":2483,"tags":2484,"stars":2490,"repoUrl":2491,"updatedAt":2492},"automate browser interactions","Direct browser control via CDP for web interaction: automation, scraping, testing, screenshots, and site\u002Fapp work.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2485,2486,2487],{"name":13,"slug":14,"type":15},{"name":23,"slug":24,"type":15},{"name":2488,"slug":2489,"type":15},"Web Scraping","web-scraping",106789,"https:\u002F\u002Fgithub.com\u002Fbrowser-use\u002Fbrowser-use","2026-08-19T03:33:11.866098",{"slug":2494,"name":2494,"fn":2495,"description":2496,"org":2497,"tags":2498,"stars":2490,"repoUrl":2491,"updatedAt":2505},"cloud","use Browser Use Cloud API","Documentation reference for using Browser Use Cloud — the hosted API and SDK for browser automation. Use this skill whenever the user needs help with the Cloud REST API (v2 or v3), browser-use-sdk (Python or TypeScript), X-Browser-Use-API-Key authentication, cloud sessions, browser profiles, profile sync, CDP WebSocket connections, stealth browsers, residential proxies, CAPTCHA handling, webhooks, workspaces, skills marketplace, liveUrl streaming, pricing, or integration patterns (chat UI, subagent, adding browser tools to existing agents). Also trigger for questions about n8n\u002FMake\u002FZapier integration, Playwright\u002F Puppeteer\u002FSelenium on cloud infrastructure, or 1Password vault integration. Do NOT use this for the open-source Python library (Agent, Browser, Tools config) — use the open-source skill instead.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2499,2500,2502],{"name":23,"slug":24,"type":15},{"name":2501,"slug":782,"type":15},"Python",{"name":2503,"slug":2504,"type":15},"REST API","rest-api","2026-04-06T18:06:10.225871",{"slug":2507,"name":2507,"fn":2508,"description":2509,"org":2510,"tags":2511,"stars":2490,"repoUrl":2491,"updatedAt":2515},"open-source","write browser-use Python code","Documentation reference for writing Python code using the browser-use open-source library. Use this skill whenever the user needs help with Agent, Browser, or Tools configuration, is writing code that imports from browser_use, asks about @sandbox deployment, supported LLM models, Actor API, custom tools, lifecycle hooks, MCP server setup, or monitoring\u002Fobservability with Laminar or OpenLIT. Also trigger for questions about browser-use installation, prompting strategies, or sensitive data handling. Do NOT use this for Cloud API\u002FSDK usage or pricing — use the cloud skill instead. Do NOT use this for directly automating a browser via CLI commands — use the browser-use skill instead.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2512,2513,2514],{"name":13,"slug":14,"type":15},{"name":23,"slug":24,"type":15},{"name":2501,"slug":782,"type":15},"2026-04-06T18:06:14.102374",{"slug":2517,"name":2517,"fn":2518,"description":2519,"org":2520,"tags":2521,"stars":2490,"repoUrl":2491,"updatedAt":2526},"remote-browser","control a local browser from a sandbox","Controls a local browser from a sandboxed remote machine. Use when the agent is running in a sandbox (no GUI) and needs to navigate websites, interact with web pages, fill forms, take screenshots, or expose local dev servers via tunnels.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2522,2523],{"name":23,"slug":24,"type":15},{"name":2524,"slug":2525,"type":15},"Sandboxing","sandboxing","2026-04-06T18:06:12.842351",{"slug":2528,"name":2528,"fn":2529,"description":2530,"org":2531,"tags":2532,"stars":2490,"repoUrl":2491,"updatedAt":2545},"x402","configure x402 payments for Browser Use Cloud","Set up Browser Use Cloud payments with x402 — pay per request from a crypto wallet (USDC on Base mainnet), no signup or API key. Two setups it works out up front — \"just use it\" (set up a wallet so you or Claude Code can run cloud browser tasks paid from the wallet — Claude writes and runs throwaway scripts, nothing touches your codebase) or \"build it in\" (install the SDK and write the key + code into your project). Walks through wallet setup, funding, .env, and a ~$1 test run. Use when the user asks about x402, pay-per-use, USDC payments, or wants Browser Use Cloud without an API key. For the free-tier signup (reverse-CAPTCHA → API key), use `browser-use cloud signup` or the `cloud` skill instead.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2533,2534,2537,2538,2541,2544],{"name":13,"slug":14,"type":15},{"name":2535,"slug":2536,"type":15},"Base","base",{"name":23,"slug":24,"type":15},{"name":2539,"slug":2540,"type":15},"Payments","payments",{"name":2542,"slug":2543,"type":15},"Web3","web3",{"name":2528,"slug":2528,"type":15},"2026-06-02T07:51:20.889935",{"slug":2547,"name":2547,"fn":2548,"description":2549,"org":2550,"tags":2551,"stars":2564,"repoUrl":2565,"updatedAt":2566},"manim-video","create technical animations with Manim","Production pipeline for mathematical and technical animations using Manim Community Edition. Creates 3Blue1Brown-style explainer videos, algorithm visualizations, equation derivations, architecture diagrams, and data stories. Use when users request: animated explanations, math animations, concept visualizations, algorithm walkthroughs, technical explainers, 3Blue1Brown style videos, or any programmatic animation with geometric\u002Fmathematical content.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2552,2555,2558,2561],{"name":2553,"slug":2554,"type":15},"Animation","animation",{"name":2556,"slug":2557,"type":15},"Creative","creative",{"name":2559,"slug":2560,"type":15},"Mathematics","mathematics",{"name":2562,"slug":2563,"type":15},"Video","video",17171,"https:\u002F\u002Fgithub.com\u002Fbrowser-use\u002Fvideo-use","2026-04-16T05:01:44.229054",{"slug":2568,"name":2568,"fn":2569,"description":2570,"org":2571,"tags":2572,"stars":2564,"repoUrl":2565,"updatedAt":2579},"video-use","edit and process videos via conversation","Edit any video by conversation. Transcribe, cut, color grade, generate overlay animations, burn subtitles — for talking heads, montages, tutorials, travel, interviews. No presets, no menus. Ask questions, confirm the plan, execute, iterate, persist. Production-correctness rules are hard; everything else is artistic freedom.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2573,2574,2575,2578],{"name":2553,"slug":2554,"type":15},{"name":2556,"slug":2557,"type":15},{"name":2576,"slug":2577,"type":15},"Transcription","transcription",{"name":2562,"slug":2563,"type":15},"2026-04-16T12:17:10.522375",{"slug":2581,"name":2581,"fn":2582,"description":2583,"org":2584,"tags":2585,"stars":2594,"repoUrl":2595,"updatedAt":2596},"browser-use-terminal","automate web interactions via CLI","Direct browser control via the Browser Use Terminal CLI. Use when the user wants to automate, scrape, test, or interact with web pages — you drive the browser yourself with Python helpers.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2586,2587,2590,2591],{"name":23,"slug":24,"type":15},{"name":2588,"slug":2589,"type":15},"CLI","cli",{"name":2501,"slug":782,"type":15},{"name":2592,"slug":2593,"type":15},"Web Development","web-development",607,"https:\u002F\u002Fgithub.com\u002Fbrowser-use\u002Fterminal","2026-06-12T08:15:38.34797",{"slug":2598,"name":2598,"fn":2599,"description":2600,"org":2601,"tags":2602,"stars":2610,"repoUrl":2611,"updatedAt":2612},"cdp","drive Chrome via DevTools Protocol","Drive Chrome via the DevTools Protocol from JavaScript. Run JS snippets through the `browser-harness-js` CLI — it auto-spawns a long-lived bun HTTP server holding a fully-typed CDP `Session`, and every call (`browser-harness-js 'await session.Page.navigate(...)'`) executes against the same persistent connection. Session, active target, and globals survive across calls. Use when the user wants to automate, script, or inspect a Chrome browser via CDP — single tab or multi-tab, attach to existing Chrome or to a new one launched with --remote-debugging-port.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2603,2604,2607],{"name":23,"slug":24,"type":15},{"name":2605,"slug":2606,"type":15},"JavaScript","javascript",{"name":2608,"slug":2609,"type":15},"Testing","testing",473,"https:\u002F\u002Fgithub.com\u002Fbrowser-use\u002Fbrowser-harness-js","2026-04-21T04:55:40.331082",{"slug":2614,"name":2614,"fn":2615,"description":2616,"org":2617,"tags":2618,"stars":2628,"repoUrl":2629,"updatedAt":2630},"macos-harness","control macOS desktop applications","Control a whole Mac from one persistent Python session with screenshots, PID-targeted input, an animated virtual pointer, targeted Apple Accessibility, Apple Events, Browser Harness CDP, and filesystem access. Use for native, Electron, browser, dialog, file, or cross-app tasks without moving the physical cursor or forcing apps into the foreground.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2619,2622,2623,2624,2625],{"name":2620,"slug":2621,"type":15},"Accessibility","accessibility",{"name":13,"slug":14,"type":15},{"name":23,"slug":24,"type":15},{"name":20,"slug":21,"type":15},{"name":2626,"slug":2627,"type":15},"macOS","macos",424,"https:\u002F\u002Fgithub.com\u002Fbrowser-use\u002Fmacos-harness","2026-08-19T03:59:26.404323",{"slug":2632,"name":2632,"fn":2633,"description":2634,"org":2635,"tags":2636,"stars":2652,"repoUrl":2653,"updatedAt":2654},"agents-sdk","build AI agents on Cloudflare Workers","Build AI agents on Cloudflare Workers using the Agents SDK. Load when creating stateful agents, durable workflows, real-time WebSocket apps, scheduled tasks, MCP servers, or chat applications. Covers Agent class, state management, callable RPC, Workflows integration, and React hooks.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2637,2640,2643,2646,2649],{"name":2638,"slug":2639,"type":15},"Agents","agents",{"name":2641,"slug":2642,"type":15},"AI Infrastructure","ai-infrastructure",{"name":2644,"slug":2645,"type":15},"Cloudflare Workers","cloudflare-workers",{"name":2647,"slug":2648,"type":15},"SDK","sdk",{"name":2650,"slug":2651,"type":15},"Serverless","serverless",255,"https:\u002F\u002Fgithub.com\u002Fbrowser-use\u002Fbrowsercode","2026-04-27T05:34:19.800431",{"slug":2656,"name":2656,"fn":2657,"description":2658,"org":2659,"tags":2660,"stars":2652,"repoUrl":2653,"updatedAt":2665},"browser-execute","execute browser automation tasks","Use ONLY when calling the `browser_execute` tool or driving a real browser via the Chrome DevTools Protocol. Required reading before the first `browser_execute` call in a session. Covers the three connection methods (local Chrome with remote debugging, isolated debug-port profile, Browser Use cloud), the in-process `session` \u002F `console` snippet model, attaching to a page target, common CDP commands, the per-project `.bcode\u002Fagent-workspace\u002F` for reusable scripts, and screenshot auto-attachment.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[2661,2662],{"name":23,"slug":24,"type":15},{"name":2663,"slug":2664,"type":15},"Debugging","debugging","2026-08-03T06:02:09.917194"]