Keyboard & mouse
Input is the one lane that works end to end today. It is CGEvent injection on
macOS — no AppleScript, no helper app, no private API — reached either as a
one-shot verb or over the input stream on port 9335.
device-bridge type <text>device-bridge key <combo>device-bridge click [--x N] [--y N] [--button left|right|middle] [--count N]device-bridge move-mouse --x N --y Ndevice-bridge scroll [--dx N] [--dy N]device-bridge drag --x1 N --y1 N --x2 N --y2 N [--button left|right|middle]Every one runs and exits. No daemon, no token, no socket.
Typing
Section titled “Typing”device-bridge type "hello world"Types the literal string into whatever is focused. It does not focus anything for you — click or chord your way there first.
Chords
Section titled “Chords”device-bridge key cmd+shift+tdevice-bridge key ctrl+cdevice-bridge key returnThe combo is split on +; everything before the last segment is a modifier, the
last segment is the key. A bare key name with no modifiers is fine.
Pointer
Section titled “Pointer”device-bridge click --x 400 --y 300 --count 2 # double-clickdevice-bridge click --button right --x 400 --y 300device-bridge scroll --dy -120 # scroll downdevice-bridge drag --x1 100 --y1 100 --x2 400 --y2 300Coordinates are global screen coordinates. --count 2 is a real double-click, not
two clicks in a row — the click count travels in the event.
Accessibility
Section titled “Accessibility”macOS gates event injection behind the Accessibility permission. Without it, every verb fails with an explicit error; nothing silently no-ops. Check with:
device-bridge devicesinput available=trueIf it reports unavailable, add the calling binary under System Settings → Privacy & Security → Accessibility. Note the grant follows the calling process — running from a terminal means the terminal needs it, and a binary launched by a CI agent needs the agent to hold it.
The input stream
Section titled “The input stream”device-bridge start input --port 9335 --token "$WINDOWCTL_TOKEN"Unlike the media lanes, input is JSON, not binary framing — it is low-rate and
ergonomics wins there. Connect to ws://127.0.0.1:9335/?token=… and send one
message per action. This is the path a long-running harness uses so it is not
paying process-spawn cost per keystroke.
Windows and Linux
Section titled “Windows and Linux”Not built. The Windows design is SendInput (ADR 0001) and nothing is
implemented; non-darwin builds compile and report input as unavailable.