
True Input
- 64 installs
- 101 repo stars
- Updated August 4, 2026
- factory-ai/factory-plugins
Helps with ai & agent building tasks.
About
true-input is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- true-input
- AI & Agent Building
- AI-coding skill
True Input by the numbers
- 64 all-time installs (skills.sh)
- Ranked #6,160 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/factory-ai/factory-plugins --skill true-inputAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 64 |
|---|---|
| repo stars | ★ 101 |
| Last updated | August 4, 2026 |
| Repository | factory-ai/factory-plugins ↗ |
What it does
Helps with ai & agent building tasks.
Files
True-Input Driver
The orchestrator routed you here. Use these mechanics to execute your plan.
Drive a real terminal emulator, injecting keystrokes through the platform's native HID input path. This proves exactly what bytes the terminal emits -- no synthetic injection, no PTY distortion.
When to use
- Proving that a terminal really sends the sequence you expect (e.g., Ghostty's
Shift+Enter) - Recording demos that reflect actual terminal rendering
- Validating that Droid handles a keystroke correctly end-to-end in a specific terminal
If you don't need real terminal proof, use tuistory -- it's faster and more deterministic.
Platform support
| Platform | Status | Driver | Read |
|---|---|---|---|
| Linux / Wayland | Implemented | cage + wtype + any Wayland terminal | platforms/linux.md |
| macOS (QEMU) | Implemented | QEMU monitor sendkey to a macOS VM | platforms/macos.md |
| Windows (KVM) | Implemented | virsh send-key to a KVM/QEMU VM | platforms/windows.md |
Read the platform file for your target OS. Each contains prerequisites, core pattern, command reference, encoding reference, recording, troubleshooting, and recovery -- specific to that platform.
Key differences from tuistory
| Concern | tuistory | true-input |
|---|---|---|
| Snapshot source | Virtual screen buffer | Scrubbed PTY log (Linux) or screenshot (VM platforms) |
| Wait mechanism | Event-driven (screen redraws) | Log polling (Linux) or sleep-based (VMs) |
| Recording | Must wrap launch (--record) | Can start/stop any time |
| Keyboard encoding | Synthetic (bypasses terminal) | Real terminal encoding path |
Known dead ends
- Xvfb + xdotool: bypasses real keyboard processing entirely
- uinput + Xvfb: Xvfb does not consume kernel input devices
- SSH for TUI testing: PTY layer distorts input encoding; use SSH only for deployment
- Raw `asciinema rec`: true-input records via
wf-recorder(Wayland screen capture), not asciinema. Usetctl --recordortctl record start/stop. Callingasciinema recdirectly has no access to the compositor and produces nothing useful.
True-Input: Linux / Wayland
Prerequisites
sudo apt-get install -y cage wtype # required
sudo apt-get install -y grim wf-recorder # optional: screenshots / video
ls /dev/dri/ # must be non-emptyAt least one Wayland terminal: ghostty, kitty, or alacritty.
Architecture
tctl launches a headless Wayland compositor (cage) with an isolated per-session runtime directory, opens a real terminal emulator inside it, injects keystrokes via wtype, and monitors the PTY log stream via script. All socket/runtime management is handled by tctl.
Core pattern
TCTL=${DROID_PLUGIN_ROOT}/bin/tctl
$TCTL launch "droid-dev" -s proof --backend true-input --cols 120 --rows 36
$TCTL -s proof wait ">" --timeout 15000
$TCTL -s proof type "hello"
$TCTL -s proof press shift enter
$TCTL -s proof snapshot --trim
$TCTL -s proof screenshot -o /tmp/proof.png
$TCTL -s proof closeAuto-detection order: ghostty > kitty > alacritty. Force a specific terminal:
$TCTL launch "droid-dev" -s proof --backend ghosttyCommand reference (via tctl)
| Command | Purpose |
|---|---|
launch <cmd> -s <name> --backend true-input | Start session in headless compositor |
type <text> | Send literal text via wtype |
press <key> [keys...] | Send key chord (supports modifiers) |
wait <pattern> | Block until text or /regex/ in PTY log |
wait-idle | Block until PTY log stabilizes |
snapshot [--trim] | Print scrubbed PTY log output |
screenshot [-o <path>] | Capture compositor PNG |
record start <path> | Start wf-recorder video |
record stop | Stop video recording |
close | Tear down compositor + terminal |
Recording
Recording can start and stop independently of the session:
$TCTL -s proof record start /tmp/proof.mp4
# ... interact ...
$TCTL -s proof record stopOr record from launch via --record:
$TCTL launch "droid-dev" -s proof --backend true-input --record /tmp/proof.mp4Terminal encoding reference
Ghostty
Falls back to xterm modifyOtherKeys (Kitty keyboard protocol disabled due to arrow-key issues):
| Key | Bytes |
|---|---|
Enter | \r |
Shift+Enter | \x1b[27;2;13~ |
Kitty
CSI-u protocol by default:
| Key | Bytes |
|---|---|
Enter | \r |
Shift+Enter | \x1b[13;2u |
keypad Enter | \x1b[57414u |
VS Code / Cursor / Windsurf
Integrated terminals need explicit keybinding setup. Droid's helper writes workbench.action.terminal.sendSequence bindings that emit \\\r\n for Shift+Enter.
tmux
tmux may rewrite sequences when relaying. With extended keys enabled, Shift+Enter typically appears as \x1b[27;2;13~ regardless of the inner terminal's native encoding.
Recovery
$TCTL -s proof press esc
$TCTL -s proof snapshot --trim
$TCTL -s proof closeTrue-Input: macOS via QEMU Monitor
Drive a macOS VM's terminal through QEMU HMP sendkey -- keystrokes enter the VM's virtual USB keyboard, hitting macOS's HID subsystem the same way a physical keyboard would. No host compositor leakage, no SSH PTY distortion.
Architecture
mac-ctl.sh type / press
|
v
socat → QEMU monitor socket → sendkey → QEMU virtual USB keyboard (HID)
|
v
macOS HID subsystem → Terminal.app / iTerm2 / GhosttyPrerequisites
Host packages: qemu-system-x86_64 (or aarch64), socat, ffmpeg or ImageMagick (for PNG conversion). VM: QEMU macOS guest with UEFI, user-mode networking with SSH port forward. The VM must be started with MONITOR_SOCKET env var pointing to a unix socket so mac-ctl.sh can connect.
Required env vars:
export DROID_MAC_MONITOR="<path-to-qemu-monitor-socket>" # QEMU monitor unix socket
export DROID_MAC_SSH_HOST="<ssh-config-host-alias>" # SSH config host aliasOptional env vars:
export DROID_MAC_BOOT_SCRIPT="<path-to-qemu-boot-script>" # for `up` command
export DROID_MAC_SHOT_DIR="/tmp"Core pattern
MACCTL=${DROID_PLUGIN_ROOT}/scripts/macos/mac-ctl.sh
$MACCTL up # start VM (needs DROID_MAC_BOOT_SCRIPT)
$MACCTL wait-boot 120 # poll SSH until ready
$MACCTL terminal # open Terminal.app via Spotlight
sleep 3
$MACCTL type "echo hello world"
$MACCTL press enter
sleep 2
$MACCTL shot /tmp/result.png # screendump via QEMU monitor → PNGCommand reference (via mac-ctl.sh)
| Command | Purpose |
|---|---|
up | Start VM via boot script (requires DROID_MAC_BOOT_SCRIPT) |
down | Graceful shutdown via SSH sudo shutdown -h now |
kill | Force-quit QEMU process via monitor quit |
status | Check VM state via monitor socket |
wait-boot [timeout] | Poll SSH until macOS is ready (default 120s) |
type <text> | Type literal text, char by char via QEMU sendkey |
press <key> [key ...] | Send key or chord (e.g., press cmd c, press shift enter) |
shot [path] | Screenshot via screendump → PPM → PNG |
terminal | Open Terminal.app via Spotlight (Cmd+Space) |
iterm | Open iTerm2 via Spotlight |
spotlight [query] | Open Spotlight, optionally type + launch a query |
ssh <cmd> | Run command via SSH (deployment only -- not for TUI testing) |
macOS-specific keys
cmd / command maps to meta_l (the macOS Command key). Chords work as expected:
$MACCTL press cmd c # Copy
$MACCTL press cmd shift 3 # Screenshot (macOS native)
$MACCTL press cmd space # Spotlight
$MACCTL press cmd q # Quit foreground appKey differences from other platforms
| Concern | Linux (Wayland) | Windows (KVM/virsh) | macOS (QEMU monitor) |
|---|---|---|---|
| Input path | wtype → compositor → terminal | virsh send-key → QEMU HID | sendkey via monitor socket → QEMU HID |
| Snapshot | Scrubbed PTY log | virsh screenshot (PNG) | screendump (PPM → PNG) |
| Wait mechanism | PTY log polling | Sleep-based | SSH polling (wait-boot) + sleep-based |
| Recording | wf-recorder | Poll-based screenshot → ffmpeg | Poll-based screenshot → ffmpeg |
| Session isolation | Per-session Wayland runtime dir | Full VM isolation | Full VM isolation |
| App launcher | N/A (direct command) | Start menu (win key) | Spotlight (cmd+space) |
Recording
Poll-based recording via screendump:
MACREC=${DROID_PLUGIN_ROOT}/scripts/macos/mac-record.sh
$MACREC start /tmp/demo.mp4 5 # 5 fps
# ... interact with mac-ctl.sh ...
$MACREC stop # encodes PPM frames to MP4Troubleshooting
| Problem | Fix |
|---|---|
| Monitor socket not found | VM isn't running, or was started without MONITOR_SOCKET env var |
| SSH times out on boot | macOS VMs under QEMU take 60-120s to boot. Increase wait-boot timeout |
screendump is black | VM may be asleep. mac-ctl.sh press space to wake |
| Keystrokes not registering | Check that QEMU was started with -device usb-kbd (not evdev passthrough) |
| PPM not converting to PNG | Install ImageMagick (magick) or ffmpeg on the host |
Recovery
MACCTL=${DROID_PLUGIN_ROOT}/scripts/macos/mac-ctl.sh
$MACCTL press esc
$MACCTL shot /tmp/state.png
$MACCTL kill # hard-kill QEMU process
$MACCTL up # cold restartFuture: native macOS (no VM)
For bare-metal Macs (not VMs), the QEMU monitor approach isn't available. Potential paths:
- Wawona (native macOS Wayland compositor) +
wtype+waypipe-- would reuse Linux plumbing - AppleScript / Accessibility API injection into Terminal.app / iTerm2
- cliclick for mouse/keyboard automation
These are not yet implemented. Use this QEMU approach for VM-based macOS testing.
True-Input: Windows via KVM/QEMU
Drive a Windows VM's console through virsh send-key -- keystrokes enter the VM's virtual HID device, hitting the Windows Console Subsystem the same way a physical keyboard would. No host compositor leakage, no SSH PTY distortion.
Architecture
vm-ctl.sh type / press
|
v
virsh send-key ──> QEMU virtual keyboard (HID)
|
v
Windows Console Subsystem ──> PowerShell / TUI appPrerequisites
Host packages: qemu-full, libvirt, virt-manager, swtpm, dnsmasq. VM: KVM/QEMU with UEFI + TPM 2.0, SPICE display, NAT networking, SSH enabled.
Required env vars:
export DROID_VM_NAME="<libvirt-domain-name>" # libvirt domain name
export DROID_VM_SSH_KEY="<path-to-ssh-private-key>" # SSH key for deployment
export DROID_VM_SSH_USER="<ssh-username>" # SSH user in the VMCore pattern
VMCTL=${DROID_PLUGIN_ROOT}/scripts/windows/vm-ctl.sh
$VMCTL up # start the VM
sleep 15 # wait for boot
$VMCTL login # dismiss lock screen
sleep 5
$VMCTL pwsh # open PowerShell via Start menu
sleep 4
$VMCTL type "Get-Process | Select-Object -First 5"
$VMCTL press enter
sleep 2
$VMCTL shot /tmp/result.png # screenshot via virshCommand reference (via vm-ctl.sh)
| Command | Purpose |
|---|---|
up / down / kill / reboot / status | VM lifecycle |
type <text> | Type literal text, char by char via virsh send-key |
press <key> [keys...] | Send key or chord (e.g., press ctrl c, press shift enter) |
login [password] | Dismiss lock screen + type password |
shot [path] | Screenshot via virsh screenshot |
pwsh / wt | Open PowerShell / Windows Terminal via Start menu |
snap [name] / snaps / restore <name> | VM snapshot management |
ssh <cmd> | Run command via SSH (deployment only -- not for TUI testing) |
deploy | Push capture scripts to VM via SCP |
Key differences from Linux true-input
| Concern | Linux (Wayland) | Windows (KVM) |
|---|---|---|
| Input path | wtype → Wayland compositor → terminal | virsh send-key → QEMU HID → Windows console |
| Snapshot | Scrubbed PTY log | virsh screenshot (PNG of display) |
| Wait mechanism | PTY log polling | Sleep-based (no PTY log access) |
| Recording | wf-recorder (compositor video) | Poll-based screenshot → ffmpeg concat |
| Session isolation | Per-session Wayland runtime dir | Full VM isolation |
Recording
Poll-based recording via virsh screenshot:
VMREC=${DROID_PLUGIN_ROOT}/scripts/windows/vm-record.sh
$VMREC start /tmp/demo.mp4 5 # 5 fps
# ... interact with vm-ctl.sh ...
$VMREC stop # encodes to MP4Terminal encoding reference
VT mode (ENABLE_VIRTUAL_TERMINAL_INPUT)
| Key | Bytes | Note |
|---|---|---|
| Enter | 0D | |
| Shift+Enter | 0D | Indistinguishable from Enter in VT mode |
| Ctrl+C | 03 | With processed input off |
| Tab | 09 | |
| Shift+Tab | 1B 5B 5A | |
| Arrows | 1B 5B A/B/C/D |
Modifier codes: 2=Shift, 3=Alt, 5=Ctrl, 6=Shift+Ctrl
Win32 console API (ReadKey / ReadConsoleInput)
Lossless. Preserves VirtualKeyCode + exact modifier state (left/right Ctrl/Alt/Shift). Shift+Enter is VKey=13 + ShiftPressed (distinct from plain Enter). Use win-key-dumper.ps1 for this level of detail.
Troubleshooting
| Problem | Fix |
|---|---|
| VM won't get DHCP | Check firewall_backend = "iptables" in /etc/libvirt/network.conf, restart libvirtd |
| Keystrokes hitting host | You're using ydotool. Use vm-ctl.sh press (virsh send-key) instead |
| Screenshot is black | VM may be asleep. vm-ctl.sh press space to wake |
| SSH connection refused | sshd may have stopped. Use vm-ctl.sh type to run Start-Service sshd |
Recovery
VMCTL=${DROID_PLUGIN_ROOT}/scripts/windows/vm-ctl.sh
$VMCTL press esc
$VMCTL shot /tmp/state.png
$VMCTL restore <snapshot> # hard reset to known state