# Control protocol Start the app with a control port: `wordcraft --control 7981` (or `WORDCRAFT_CONTROL_PORT=7981`). It listens on `127.0.0.1` only. Send one JSON object per line; each gets one reply line: ```json {"id": 1, "method": "engine.execute", "params": {"command": "text.insert", "params": {"text": "Hello"}}} {"id": 1, "ok": true, "result": {"anchor": {...}, "focus": {...}}} ``` Errors come back as `{"id": …, "ok": false, "error": "message"}`. A failed command leaves the document unchanged. ## Methods | Method | Params | Result | |---|---|---| | `engine.execute` | `command`, `params` | the command's result (any id from `engine.commands`, including UI commands `ui.tab`, `ui.dialog`, `ui.backstage`, `ui.language` (`{"value": "auto"|"en"|"zh-hans"|"zh-hant"|"ja"}`)…) | | `engine.commands` | — | every command: id, label, location, shortcut, params, enabled | | `document.inspect` | `text?` | blocks (text, style, runs, lists, tables), parts, sections, selection, pages | | `ui.inspect` | — | UI state, view, dialog, window size, page rects on screen, caret, perf | | `ui.click` | `x`, `y`, `button?`, `count?`, `shift?`, `cmd?`, `alt?` | real pointer input at window coordinates | | `ui.clickText` | `page` (0-based), `x`, `y` (points from the page's top-left), `count?` | click inside a page | | `ui.move` / `ui.drag` | `x`,`y` / `x`,`y`,`toX`,`toY`,`steps?` | pointer move / drag | | `ui.key` | `key` (`B`, `Enter`, `Left`…), `shift?`, `alt?`, `cmd?` | key press through egui (shortcuts apply) | | `ui.text` | `text` | typed text through egui | | `ui.screenshot` | `path?` | PNG of the window | | `ui.render` | `path`, `page?` (1-based), `scale?` | PNG of a page, rendered by the engine | | `ui.parity` | — | feature-catalog parity | | `ui.resize` / `ui.focus` / `app.quit` | | window control | Any other method name is treated as a command id: `{"method": "format.bold"}` works. Positions are `{"story": "body" | {"part": n}, "path": [block, row, cell, block, …], "off": byteOffset}`.