1!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._posthogChunkIds=e._posthogChunkIds||{},e._posthogChunkIds[n]="01a102ca-2402-7481-b63c-2a7f2c75241f")}catch(e){}}();import{j as e}from"./jsx-runtime-u17CrQMm.js";import{T as i,a as n}from"./tabs-CsV0nJHc.js";import{u as d}from"./index-DPhldNWm.js";import"./chunk-4N6VE7H7-DExpvS7J.js";const h={title:"Typing tools",description:"Type text into a field or window."};function r(s){const t={a:"a",code:"code",figure:"figure",h2:"h2",p:"p",pre:"pre",span:"span",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...d(),...s.components};return e.jsxs(e.Fragment,{children:[` 2`,` 3`,e.jsxs(t.p,{children:["Served by ",e.jsx(t.code,{children:"cua-driver mcp"}),"; see ",e.jsx(t.a,{href:"/cua-driver/reference/mcp-tools",children:"MCP tools"})," for every tool."]}),` 4`,e.jsx(t.h2,{id:"type_text",children:e.jsx(t.code,{children:"type_text"})}),` 5`,e.jsx(t.p,{children:"Effect: destructive. Platforms: macOS, Linux, Windows."}),` 6`,e.jsxs(i,{items:["macOS","Linux","Windows"],groupId:"platform",persist:!0,children:[e.jsxs(n,{value:"macOS",children:[e.jsxs(t.p,{children:["Insert text into the target pid via ",e.jsx(t.code,{children:"AXSetAttribute(kAXSelectedText)"}),". Works for standard Cocoa text fields and text views. No keystrokes are synthesized: special keys (Return / Escape / arrows) go through ",e.jsx(t.code,{children:"press_key"})," / ",e.jsx(t.code,{children:"hotkey"}),". For Chromium / Electron inputs that don't implement ",e.jsx(t.code,{children:"kAXSelectedText"}),", the tool falls back to CGEvent character synthesis automatically when the estimated route stays within the daemon transport budget. Longer synthesized routes are refused before character events and return a safe chunk size; one-call AX insertion remains uncapped."]}),e.jsxs(t.p,{children:["Optional ",e.jsx(t.code,{children:"element_token"})," (from the last ",e.jsx(t.code,{children:"get_window_state"})," snapshot) directs the write to a specific field. Without ",e.jsx(t.code,{children:"element_token"}),", the write goes to the pid's currently focused element."]}),e.jsxs(t.p,{children:[`WEB CONTENT (Chromium/WebKit/Electron: browser tabs, Slack, VS Code, X's compose box): AXValue is not independent proof that the renderer/DOM observed an AX write or synthesized keystrokes. The driver detects this at the element level (an AXWebArea ancestor) and refuses to trust AXValue-only read-back there. Electron AX targets that are web content or cannot be proven native refuse background delivery before mutation because the AX route cannot establish exact renderer focus; use the px form or explicit foreground delivery. Other web-content paths return effect:"unverifiable" + escalation, never a false "confirmed" (a browser's own native address bar/toolbar stays trusted). For a browser TAB the reliable path is the `,e.jsx(t.code,{children:"page"}),` tool (drives the DOM via CDP); for an embedded web view use this tool's px form: pass x,y (no element_token) to pixel-click the field then type, in one call. NOTE: a px focus-click won't reliably open+focus a CLOSED control; AX-press to open/activate it first (works in the background), then px-type. Always confirm via the screenshot; if px-background still drops, escalate to delivery_mode:"foreground".`]}),e.jsx(t.p,{children:e.jsx(t.strong,{children:"macOS parameters"})}),e.jsxs(t.table,{children:[e.jsx(t.thead,{children:e.jsxs(t.tr,{children:[e.jsx(t.th,{children:"Parameter"}),e.jsx(t.th,{children:"Type"}),e.jsx(t.th,{children:"Default"}),e.jsx(t.th,{children:"Description"})]})}),e.jsxs(t.tbody,{children:[e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--macos--delay_ms"}),e.jsx(t.code,{children:"delay_ms"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:"integer"})}),e.jsx(t.td,{}),e.jsx(t.td,{children:"Milliseconds between characters in the CGEvent fallback path. Default 30. Ignored when the AX path succeeds. Range: 0 to 200."})]}),e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--macos--delivery_mode"}),e.jsx(t.code,{children:"delivery_mode"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:'"background" | "foreground"'})}),e.jsx(t.td,{}),e.jsx(t.td,{children:`Best-effort-background ladder rung (default "background"). "background": AX insert, then CGEvent keystrokes if needed;
6 no focus steal; native controls can be confirmed via AXValue read-back, while web-content writes remain effect:"unverifiable". "foreground": briefly front the window, type, restore the prior frontmost; the explicit last resort for focus-sensitive surfaces (e.g. WhatsApp/Catalyst) where background keystrokes don't land. Re-call with "foreground" when a background attempt remains unverifiable and a fresh snapshot shows the text did not appear.`})]}),e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--macos--element_token"}),e.jsx(t.code,{children:"element_token"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:"string"})}),e.jsx(t.td,{}),e.jsxs(t.td,{children:["Opaque per-snapshot element handle from ",e.jsx(t.code,{children:"structuredContent.elements[].element_token"}),". Returns an explicit stale error naming the current snapshots once a newer read supersedes it."]})]}),e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--macos--pid"}),e.jsx(t.code,{children:"pid"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:"integer"})}),e.jsx(t.td,{}),e.jsx(t.td,{children:"Target process ID."})]}),e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--macos--scope"}),e.jsx(t.code,{children:"scope"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:'"window" | "desktop"'})}),e.jsx(t.td,{children:e.jsx(t.code,{children:'"window"'})}),e.jsx(t.td,{children:"Use desktop with no pid/window_id to type into the frontmost application."})]}),e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--macos--text"}),e.jsx(t.code,{children:"text"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:"string"})}),e.jsx(t.td,{children:"required"}),e.jsx(t.td,{children:"Text to insert at the target's cursor."})]}),e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--macos--window_id"}),e.jsx(t.code,{children:"window_id"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:"integer"})}),e.jsx(t.td,{}),e.jsx(t.td,{children:"CGWindowID. Omit when element_token is supplied (the token carries it)."})]}),e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--macos--x"}),e.jsx(t.code,{children:"x"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:"number"})}),e.jsx(t.td,{}),e.jsx(t.td,{children:"Screenshot-pixel X of the field to type into: the element px action form. Pass x,y (no element_token) and the tool pixel-clicks there to establish real renderer focus, then types. Use for Chromium/Electron inputs the AX path can't reach. Read straight off the get_window_state PNG, same convention as click."})]}),e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--macos--y"}),e.jsx(t.code,{children:"y"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:"number"})}),e.jsx(t.td,{}),e.jsx(t.td,{children:"Screenshot-pixel Y of the field (see x)."})]})]})]})]}),e.jsxs(n,{value:"Linux",children:[e.jsx(t.p,{children:"Type text to a window via XSendEvent (KeyPress/KeyRelease). No focus steal."}),e.jsx(t.p,{children:e.jsx(t.strong,{children:"Linux parameters"})}),e.jsxs(t.table,{children:[e.jsx(t.thead,{children:e.jsxs(t.tr,{children:[e.jsx(t.th,{children:"Parameter"}),e.jsx(t.th,{children:"Type"}),e.jsx(t.th,{children:"Default"}),e.jsx(t.th,{children:"Description"})]})}),e.jsxs(t.tbody,{children:[e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--linux--coordinate_frame"}),e.jsx(t.code,{children:"coordinate_frame"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:'"window" | "desktop"'})}),e.jsx(t.td,{}),e.jsx(t.td,{children:'Frame of x/y (and from_x/from_y/to_x/to_y). Default "window": window-local screenshot pixels as returned by get_window_state. "desktop": full-screen pixels as returned by get_desktop_state, translated to the target window. Passing scope:"desktop" together with pid/window_id means the same thing.'})]}),e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--linux--delivery_mode"}),e.jsx(t.code,{children:"delivery_mode"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:'"background" | "foreground"'})}),e.jsx(t.td,{children:e.jsx(t.code,{children:'"background"'})}),e.jsx(t.td,{children:"Input delivery mode. 'background' (default) never activates or raises the target window. On X11 it injects via XTEST / the XInput2 master pointer (no focus steal). On Wayland it goes through libei + xdg-desktop-portal, which injects to the compositor's input focus: Wayland's security model has no per-window background targeting, so a specific non-focused window cannot be aimed at; when no libei backend is available the tool returns a structured background_unavailable error. 'foreground' is the explicit escalation: activate the target (X11 _NET_ACTIVE_WINDOW; Wayland compositor activate), inject, then restore the prior active window; a brief focus swap unless the target was already active. Matches the macOS / Windows delivery_mode surface."})]}),e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--linux--element_token"}),e.jsx(t.code,{children:"element_token"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:"string"})}),e.jsx(t.td,{}),e.jsxs(t.td,{children:["Opaque per-snapshot element handle from ",e.jsx(t.code,{children:"structuredContent.elements[].element_token"}),". Returns an explicit stale error naming the current snapshots once a newer read supersedes it."]})]}),e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--linux--pid"}),e.jsx(t.code,{children:"pid"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:"integer"})}),e.jsx(t.td,{}),e.jsx(t.td,{children:'Target process ID. Omit with scope "desktop" to type into the focused application.'})]}),e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--linux--scope"}),e.jsx(t.code,{children:"scope"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:'"window" | "desktop"'})}),e.jsx(t.td,{children:e.jsx(t.code,{children:'"window"'})}),e.jsx(t.td,{children:'Use "desktop" with no pid to type into the focused application. Default "window".'})]}),e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--linux--text"}),e.jsx(t.code,{children:"text"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:"string"})}),e.jsx(t.td,{children:"required"}),e.jsx(t.td,{children:"Text to type."})]}),e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--linux--window_id"}),e.jsx(t.code,{children:"window_id"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:"integer"})}),e.jsx(t.td,{}),e.jsx(t.td,{children:"Window id from list_windows. Required with x/y; optional with element_token (the token carries it)."})]}),e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--linux--x"}),e.jsx(t.code,{children:"x"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:"number"})}),e.jsx(t.td,{}),e.jsx(t.td,{children:`Pixel X of the field to type into: the element px action form. Pass x,y (no element_token) and the tool pixel-clicks there to establish real renderer focus, then types. Use for Chromium/Electron inputs the AX path can't reach. Window-local pixels of the target window's own get_window_state screenshot by default (same convention as click); for get_desktop_state pixels pass scope:"desktop" (or coordinate_frame:"desktop"): a bare pid+x/y is otherwise misinterpreted as window-local and can focus the wrong widget.`})]}),e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--linux--y"}),e.jsx(t.code,{children:"y"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:"number"})}),e.jsx(t.td,{}),e.jsx(t.td,{children:"Pixel Y of the field (see x)."})]})]})]})]}),e.jsxs(n,{value:"Windows",children:[e.jsx(t.p,{children:"Insert text into the target pid via character-by-character PostMessage(WM_CHAR) to the focused window. No focu
6s steal."}),e.jsxs(t.p,{children:["Special keys (Return, Escape, arrows, Tab) go through ",e.jsx(t.code,{children:"press_key"})," / ",e.jsx(t.code,{children:"hotkey"}),": they are not text."]}),e.jsxs(t.p,{children:[e.jsx(t.strong,{children:"Routing on Windows."})," When the target's owning EXE or top-level window class identifies it as a XAML / WinUI3 / UWP host (modern Notepad, Calculator, Photos, Settings, etc.), the tool requires ",e.jsx(t.code,{children:"element_token"})," and routes through UI Automation's ",e.jsx(t.code,{children:"ValuePattern.SetValue"}),": same backend as the ",e.jsx(t.code,{children:"set_value"})," tool. PostMessage WM_CHAR doesn't reach those hosts (their CoreInput dispatcher only consumes events from the system input queue), so the fallback path silently dropped chars. If you call ",e.jsx(t.code,{children:"type_text(pid, text)"})," on a XAML host without ",e.jsx(t.code,{children:"element_token"}),", the tool returns an actionable error pointing you at ",e.jsx(t.code,{children:"get_window_state"})," first. Native ConsoleHost on Windows ARM64 is hard-refused because it can accept synthesized Unicode events without delivering them; use a process or PTY setup channel instead. Legacy Win32 apps still use the PostMessage path, preserving the no-focus-steal property."]}),e.jsxs(t.p,{children:[e.jsx(t.code,{children:"delay_ms"})," (0â200, default 30) spaces successive characters on the PostMessage path so autocomplete and IME can keep up. Ignored on the UIA path (SetValue is atomic)."]}),e.jsx(t.p,{children:e.jsx(t.strong,{children:"Windows parameters"})}),e.jsxs(t.table,{children:[e.jsx(t.thead,{children:e.jsxs(t.tr,{children:[e.jsx(t.th,{children:"Parameter"}),e.jsx(t.th,{children:"Type"}),e.jsx(t.th,{children:"Default"}),e.jsx(t.th,{children:"Description"})]})}),e.jsxs(t.tbody,{children:[e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--windows--delay_ms"}),e.jsx(t.code,{children:"delay_ms"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:"integer"})}),e.jsx(t.td,{}),e.jsx(t.td,{children:"Milliseconds between characters. Default 30. Range: 0 to 200."})]}),e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--windows--delivery_mode"}),e.jsx(t.code,{children:"delivery_mode"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:'"background" | "foreground"'})}),e.jsx(t.td,{}),e.jsx(t.td,{children:"Input delivery mode. 'background' (default) never swaps foreground: it routes through UIA Invoke / PostMessage and the window is never raised. For targets whose input stack silently drops posted events (Chromium/Electron content, GTK buttons, VCL/LibreOffice accelerators) the tool returns a structured background_unavailable error rather than fronting. 'foreground' is the explicit escalation: a brief SetForegroundWindow swap + SendInput, restoring the prior foreground afterward. IMPORTANT: 'background' is not a hint to weigh; it is the mandatory first attempt. Do NOT pass 'foreground' preemptively because a target 'looks like' GTK/Chromium/Electron; the DRIVER decides when background is impossible and tells you so via a background_unavailable error (or a verified no-op). Only THEN re-issue the same action with 'foreground'. The lists above are the driver's detectors, not a checklist for you to front on a guess: fronting up-front needlessly steals the user's focus and is a bug, not a shortcut. Matches the macOS delivery_mode surface."})]}),e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--windows--element_token"}),e.jsx(t.code,{children:"element_token"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:"string"})}),e.jsx(t.td,{}),e.jsx(t.td,{children:"Opaque element handle from get_window_state. When supplied, type_text writes through UIA ValuePattern and reads that exact element back by handle. The shared ActionResult is confirmed only when the complete expected value is synchronously visible. If SetValue succeeds but read-back is stale or unavailable, the result is unverifiable with no escalation; take a fresh snapshot before retrying because deferred providers may publish only after this call returns."})]}),e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--windows--pid"}),e.jsx(t.code,{children:"pid"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:"integer"})}),e.jsx(t.td,{}),e.jsx(t.td,{children:"Target process ID."})]}),e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--windows--scope"}),e.jsx(t.code,{children:"scope"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:'"window" | "desktop"'})}),e.jsx(t.td,{}),e.jsx(t.td,{children:"Use desktop with no pid/window_id to type into the current foreground application."})]}),e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--windows--text"}),e.jsx(t.code,{children:"text"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:"string"})}),e.jsx(t.td,{children:"required"}),e.jsx(t.td,{children:"Text to insert at the focused element's cursor."})]}),e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--windows--window_id"}),e.jsx(t.code,{children:"window_id"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:"integer"})}),e.jsx(t.td,{}),e.jsx(t.td,{children:"HWND of the target window. Omit when element_token is supplied (the token carries it)."})]}),e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--windows--x"}),e.jsx(t.code,{children:"x"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:"number"})}),e.jsx(t.td,{}),e.jsx(t.td,{children:"Window-local screenshot-pixel X of the field to type into: the element px action form. Pass x,y (no element_token) and the tool pixel-clicks there to establish real renderer focus, then types. Use for Chromium/Electron inputs the UIA/WM_CHAR path can't reach. Read straight off the get_window_state PNG, same convention as click."})]}),e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--windows--y"}),e.jsx(t.code,{children:"y"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:"number"})}),e.jsx(t.td,{}),e.jsx(t.td,{children:"Window-local screenshot-pixel Y of the field (see x)."})]})]})]})]})]}),` 7`,e.jsx(t.p,{children:e.jsx(t.strong,{children:"Parameters on every platform"})}),` 8`,e.jsxs(t.table,{children:[e.jsx(t.thead,{children:e.jsxs(t.tr,{children:[e.jsx(t.th,{children:"Parameter"}),e.jsx(t.th,{children:"Type"}),e.jsx(t.th,{children:"Default"}),e.jsx(t.th,{children:"Description"})]})}),e.jsxs(t.tbody,{children:[e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--session"}),e.jsx(t.code,{children:"session"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:"string"})}),e.jsx(t.td,{}),e.jsx(t.td,{children:"For multi-call work, prefer a short public session label and repeat it on every call that accepts it. Omit it to use the authenticated transport's implicit lifecycle session."})]}),e.jsxs(t.tr,{children:[e.jsxs(t.td,{children:[e.jsx("span",{id:"type_text--target"}),e.jsx(t.code,{children:"target"})]}),e.jsx(t.td,{children:e.jsx(t.code,{children:"window target | desktop target"})}),e.jsx(t.td,{}),e.jsxs(t.td,{children:["Preferred per-call target: an exact window (",e.jsx(t.code,{children:'kind="window"'}),", ",e.jsx(t.code,{children:"pid"}),", ",e.jsx(t.code,{children:"window_id"}),") or the primary desktop (",e.jsx(t.code,{children:'kind="desktop"'}),", ",e.jsx(t.code,{children:'display_id="primary"'}),")."]})]})]})]}),` 9`,e.jsx(t.p,{children:e.jsx(t.strong,{children:"Example arguments"})}),` 10`,e.jsx(t.figure,{"data-rehype-pretty-code-figure":"",children:e.jsx(t.pre,{tabIndex:"0","data-language":"json","data-theme":"github-dark-default",children:e.jsx(t.code,{"data-language":"json","data-theme":"github-dark-default",style:{display:"grid"},children:e.jsx(t.span,{dangerouslySetInnerHTML:{__html:'<span data-line=""><span style="color:#E6EDF3">
10{</span><span style="color:#7EE787">"text"</span><span style="color:#E6EDF3">:</span><span style="color:#A5D6FF">"<text>"</span><span style="color:#E6EDF3">}</span></span>'}})})})})]})}function x(s={}){const{wrapper:t}={...d(),...s.components};return t?e.jsx(t,{...s,children:e.jsx(r,{...s})}):r(s)}export{x as default,h as frontmatter}; 11//# sourceMappingURL=keyboard-DmwWREJJ.js.map 12 13//# chunkId=01a102ca-2402-7481-b63c-2a7f2c75241f
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.