On this page
Run a child process under a PTY, proxying the real terminal and capturing its output.
#claudewheel.pty_runner
#claudewheel.pty_runner
Run a child process under a PTY, proxying the real terminal and capturing its output.
#_copy_winsize
def _copy_winsize(src_fd: int, dst_fd: int) -> NoneCopy the window size from src_fd to dst_fd; ignore failures.
#run_under_pty
def run_under_pty(argv: list[str], env: dict[str, str], *, input_bytes: bytes | None=None, proxy_terminal: bool=True) -> tuple[int, bytes]Run argv with env under a fresh PTY; return (exit_code, captured_bytes).
With proxy_terminal=True (the default) the real terminal is opened via /dev/tty (stdin may be piped), put into full raw mode so every byte -- including Ctrl-C -- is forwarded to the child, and window-size changes are propagated on SIGWINCH. Child output is both written through to the real terminal and captured. Raises RuntimeError if /dev/tty cannot be opened.
With proxy_terminal=False no real terminal is touched: the child still runs under a PTY, but output is only captured. This is the headless mode used by tests and non-interactive callers.
input_bytes, if given, is scripted input written to the PTY master right after the child starts -- it lets callers (and tests) drive an interactive child without a human typing.