
Pty Capture
- 67 installs
- 101 repo stars
- Updated August 4, 2026
- factory-ai/factory-plugins
Helps with ai & agent building tasks.
About
pty-capture is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- pty-capture
- AI & Agent Building
- AI-coding skill
Pty Capture by the numbers
- 67 all-time installs (skills.sh)
- Ranked #5,935 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 pty-captureAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 67 |
|---|---|
| repo stars | ★ 101 |
| Last updated | August 4, 2026 |
| Repository | factory-ai/factory-plugins ↗ |
What it does
Helps with ai & agent building tasks.
Files
PTY Byte Capture
The orchestrator routed you here. Use these mechanics to execute your plan.
Capture the exact bytes a real terminal emits for a given keystroke. Use this when the question is "what sequence does terminal X send for key Y?" rather than "does the UI look right?"
Platform support
| Platform | Status | Read |
|---|---|---|
| Linux / Wayland | Implemented | platforms/linux.md |
| Windows (KVM) | Implemented | platforms/windows.md |
| macOS (QEMU) | Implemented | platforms/macos.md |
Read the platform file for your target OS. Each contains the capture architecture, prerequisites, usage pattern, and platform-specific notes.
Known dead ends
- Xvfb + xdotool: bypasses real keyboard processing entirely
- uinput + Xvfb: Xvfb does not consume kernel input devices
- SSH PTY for keystroke injection: distorts the input encoding; SSH is only for output capture or deployment
Follow-on
Feed captured bytes into terminal compatibility fixtures and replay tests in apps/cli.
PTY Byte Capture: Linux / Wayland
Quick start
# Full matrix across all installed terminals
${DROID_PLUGIN_ROOT}/scripts/capture-terminal-bytes.py --format table
# Single terminal + combo
${DROID_PLUGIN_ROOT}/scripts/capture-terminal-bytes.py --backend ghostty --combo shift-enter --format jsonSupported backends: ghostty, kitty, alacritty. Supported combos: enter, shift-enter, ctrl-l, escape, shift-tab.
Architecture
wtype -> cage (headless compositor) -> terminal emulator -> PTY child -> hex outputThe child process (pty-hex-dumper.py) switches stdin to raw mode, prints READY, then dumps each byte as space-separated hex pairs.
Prerequisites
sudo apt-get install -y cage wtype
ls /dev/dri/ # must be non-emptyPlus a Wayland terminal (ghostty, kitty, or alacritty).
Manual capture (escape hatch)
When the scripts are insufficient, use a zero-buffered PTY child directly:
TCTL=${DROID_PLUGIN_ROOT}/bin/tctl
$TCTL launch "${DROID_PLUGIN_ROOT}/scripts/pty-hex-dumper.py --ready" \
-s capture --backend ghostty
$TCTL -s capture wait "READY" --timeout 10000
$TCTL -s capture press shift enter
sleep 0.5
$TCTL -s capture snapshot --trim
$TCTL -s capture closeOr use a one-liner Perl child:
perl -e '$|=1; while(sysread(STDIN,$b,1)){printf "%02x ",ord($b)}'PTY Byte Capture: macOS (QEMU)
Capture terminal byte sequences from a macOS VM by running a capture script inside the guest over SSH, then injecting keystrokes via QEMU monitor sendkey.
Architecture
mac-ctl.sh press → QEMU monitor sendkey → virtual USB kbd → macOS HID → Terminal.app
|
capture script (SSH)
|
hex outputThe capture script runs inside the macOS VM via SSH. Keystrokes arrive through the real HID path (QEMU virtual keyboard), not through the SSH PTY -- so captured bytes reflect what macOS Terminal.app actually delivers.
Prerequisites
The macOS VM must have:
- SSH enabled (System Settings → General → Sharing → Remote Login)
- Python 3 installed (ships with macOS, or via
brew install python3)
Usage
MACCTL=${DROID_PLUGIN_ROOT}/scripts/macos/mac-ctl.sh
# Start a hex dumper inside the VM via SSH (runs in background)
$MACCTL ssh 'python3 -c "
import sys, tty, termios
fd = sys.stdin.fileno()
old = termios.tcgetattr(fd)
tty.setraw(fd)
sys.stdout.write(\"READY\n\")
sys.stdout.flush()
try:
while True:
b = sys.stdin.buffer.read(1)
if not b: break
sys.stdout.write(f\"{b[0]:02x} \")
sys.stdout.flush()
if b[0] == 0x11: break # Ctrl+Q exits
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old)
"' &
CAPTURE_PID=$!
sleep 2
# Now inject keystrokes via QEMU monitor (true HID path)
$MACCTL press shift ret
sleep 0.5
# Kill the capture session
kill $CAPTURE_PID 2>/dev/null
# For visual proof, take a screenshot
$MACCTL shot /tmp/macos-capture.pngImportant notes
- The SSH session provides the output channel only. The actual keystrokes travel through QEMU's virtual USB keyboard → macOS HID → Terminal.app's PTY.
- This captures what Terminal.app delivers to its PTY child, which may differ from what iTerm2 or Ghostty delivers for the same key.
- For Ghostty or iTerm2 capture, open those apps via
mac-ctl.sh spotlightinstead of using the SSH terminal.
PTY Byte Capture: Windows (KVM)
Two PowerShell scripts in ${DROID_PLUGIN_ROOT}/scripts/windows/ get deployed to the VM via vm-ctl.sh deploy:
| Script | Captures | Use when |
|---|---|---|
win-key-dumper.ps1 | Win32 ReadKey events: VirtualKeyCode, ControlKeyState, CharHex | You need lossless key metadata (e.g., Shift+Enter vs Enter) |
win-vt-dumper.ps1 | Raw VT bytes with ENABLE_VIRTUAL_TERMINAL_INPUT | You want the exact escape sequences the console delivers |
Both exit with Ctrl+Q.
Usage
VMCTL=${DROID_PLUGIN_ROOT}/scripts/windows/vm-ctl.sh
$VMCTL deploy # push scripts to VM
$VMCTL pwsh && sleep 4
$VMCTL type "powershell -ExecutionPolicy Bypass -File C:\capture\win-key-dumper.ps1"
$VMCTL press enter && sleep 3
$VMCTL press shift enter # test keystroke via virsh send-key (true HID)
sleep 0.5
$VMCTL shot /tmp/key-events.png # screenshot the captured events
$VMCTL press ctrl q # exit the dumperVT mode vs Win32 API
Important: VT mode (ENABLE_VIRTUAL_TERMINAL_INPUT) cannot distinguish Shift+Enter from Enter -- both produce 0D. Use win-key-dumper.ps1 (Win32 ReadKey API) when modifier discrimination matters.
The Win32 API preserves VirtualKeyCode + exact modifier state (left/right Ctrl/Alt/Shift). Shift+Enter shows as VKey=13 + ShiftPressed, which is distinct from plain Enter.