--- name: "windows-cli" description: "Guidance for driving Windows desktop automation from the wincli command-line tool - the token-efficient entry point that mirrors the Windows MCP server. Use when a coding agent has shell access and wants one compact command surface instead of many MCP tool schemas." domain: "windows-automation" confidence: "high" source: "plugin" --- ## Context `wincli` is the command-line twin of the Windows MCP server. Every command calls the exact same underlying tool through a persistent user-owned CLI daemon. When you already have a shell, discover only the commands you need instead of loading every MCP tool schema. The context saving depends on the host's tool-loading behavior. IDs from CLI discovery can be reused across commands against that daemon. MCP instances have separate owners; never transfer their IDs to the CLI. ## Discovery (do this first) - `wincli --help` - the command map and a common workflow. - `wincli tools` - every command with its options. - `wincli tools --json` - machine-readable tool manifest (names, descriptions, JSON input schemas); the same surface the MCP server exposes via `tools/list`, **not a CLI flag schema**. Use `tools` for kebab-case CLI spellings. - `wincli guidance` - CLI lifetime limitations followed by the shared semantic-automation guide. ## Preferred workflow 1. Observe existing windows with `wincli window find --title ` or launch with `wincli app --path `. Inspect `launchStatus` and `window`/`windows`: the handle may be missing or ambiguous. Inspect candidates or rediscover with `window find`; do not continue with handle-based commands until the intended target is identified. `possibleHandoff` does not confirm delivery or loaded content; verify the intended page/document before acting. 2. `wincli ui snapshot --window --mode auto` to see controls and establish a baseline for repeated observations. 3. `wincli ui find|click|type|select|read --window ...` for normal controls. 4. `wincli ui read-table --window --element-id ` to pull an observed grid/table into structured rows + headers. For a web page, add `--format article` to `wincli ui read` to get clean main-content text (nav/breadcrumb chrome and inline link URLs stripped, headings/lists as markdown). 5. `wincli file-save --window --path ` for supported Save / Save As dialogs. Use `wincli file-open --window --path ` for Open flows. Inspect remaining dialogs after failure or `confirmation_required`. Choose any confirmation, cancellation, or correction explicitly; do not automatically repeat the helper. 6. `wincli clipboard get|set|clear` for fast bulk text IO; keep reusable `ui batch` steps in project JSON files and run them with `--steps-file`. 7. Fall back to `wincli screenshot`, `wincli mouse`, or `wincli keyboard` only for custom-drawn UI. ## Patterns ### Semantic-first automation - Discover elements with `ui find` using `--name`, `--control-type`, or `--automation-id`. Pass the returned `--element-id` to click/type/select/read/read-table; action selectors are rejected. Omit the ID only for an intentional whole-window `ui read --window `. - Add `--with-snapshot` to `ui click`/`ui type`/`ui select` to get the updated tree back in the same call (perceive + act fused - avoids a second round trip). - Use `ui batch --window --steps ''` to run an ordered sequence (e.g. `[{"action":"find","automationId":"UsernameInput","requireUnique":true},{"action":"type","elementId":"$prev","text":"me"}]`) in a single invocation. ### Waiting - Use `ui wait --window --name ` (or `--mode disappear`) instead of sleeping, so automation checks an observable condition within a bounded timeout after dialogs, navigation, or tab switches. - Use `ui wait --mode state --element-id --desired-state enabled`, or a batch discovery then `{"action":"wait","mode":"state","elementId":"$prev","desiredState":"enabled"}`, `$prev` must refer to one unambiguous immediately preceding result. ### Element-ID lifetime - Reuse CLI IDs while their observed controls and daemon owner remain alive. - Replacement, eviction, or daemon restart invalidates old IDs. Rediscover; stale IDs never retarget by name. - Discovery supports `--parent-element-id` and `--near-element` from the same owner. - Reusable batches should discover controls afresh and consume same-run `$prev`, never persisted literal IDs. - CLI `ui snapshot --mode auto` returns a full baseline without `--since `. Supply that token for checked diffs; interleaved callers may safely receive a full snapshot. - Combine `--with-snapshot --snapshot-mode auto --since ` for a post-action comparison. A full fallback is normal when a diff is unsafe or too large. ### Outcome verification - A successful click means input was dispatched, not that the requested application outcome completed. - Use a read, snapshot, or bounded wait to check the expected result. - Do not repeat a click solely because its target disappeared or its label changed. - If the response is lost after sending an action, inspect the current state before deciding what to do. ### Application arguments - `--args` and `--arguments` are aliases. For child arguments beginning with `--`, use equals: `wincli app --path C:\Tools\local-app.exe --args="--new-window target"`. - Separate `--args "--new-window target"` is deliberately rejected, even when quoted as one value. Missing values are also usage errors (exit `2`); no application launches. The equals form preserves the complete argument string. Ordinary values work as `--args "local document.txt"`. ### Reusable batches - Keep a proven steps JSON array in your project. - Run it with `wincli ui batch --window --steps-file workflow.json`. - Discover fresh targets on every run; do not store literal element IDs. ### Clipboard - `wincli clipboard set --text ""` then paste with `wincli keyboard press --key v --modifiers ctrl`. - Copy in the app (`wincli keyboard press --key c --modifiers ctrl`) then `wincli clipboard get` to read it. ### Exit codes (script on these) - `0` success, `1` tool error (inspect the JSON `error` field), `2` usage error (bad arguments). ### Output - stdout is the tool's JSON payload - parse it directly. Use `--include-diagnostics` (alias `--diagnostics`) on `ui` operations, `file-open`, or `file-save` for available diagnostic detail. Their command aliases have the same support; other command groups reject these flags. Diagnostics are not a global option. ## Anti-patterns - Do not start with `mouse`/`screenshot` clicks when the app exposes accessible controls. - Do not save files with raw `keyboard press --key s --modifiers ctrl` when a Save As dialog may appear; use `file-save`. - Do not assume coordinates are stable across machines, themes, or display scaling. - Do not keep re-launching an app to "retry" - inspect existing windows and identify the intended target instead.