Skip to content

Interactive TUI ignores all keyboard input written to its PTY (only Ctrl+C responds), breaking automation/orchestration tooling #4180

Open

Description

@jmirandasq

Describe the bug

When copilot runs its interactive TUI inside a programmatically-driven PTY (agent orchestrators, tmux send-keys, expect, pty.fork()), the TUI ignores every keystroke written to the PTY. Printable characters, /, Tab, arrow keys, Ctrl+L and Enter all produce no reaction: the ❯ composer stays empty and nothing is submitted.

The only key that does work is Ctrl+C, which cleanly tears down the alt-screen and exits — so the process is reading stdin, but the composer's key handling never sees the events.

Typing by hand in a regular terminal works fine. Non-interactive mode (copilot -p "...") also works fine. Only the automated interactive path is broken.

Affected version

GitHub Copilot CLI 1.0.70. (TUI banner reports v1.0.71)

Steps to reproduce the behavior

Minimal, dependency-free repro (Python stdlib only):

repro.py

import os, pty, time, select, fcntl, termios, struct, signal

pid, fd = pty.fork()
if pid == 0:
os.environ["TERM"] = "xterm-256color"
os.execvp("copilot", ["copilot"])

fcntl.ioctl(fd, termios.TIOCSWINSZ, struct.pack("HHHH", 40, 120, 0, 0))

def pump(t):
b = b""; end = time.time() + t
while time.time() < end:
r, _, _ = select.select([fd], [], [], 0.2)
if r:
try: b += os.read(fd, 65536)
except OSError: return b
return b

pump(10) # let the TUI boot

for name, seq in [("text", b"hola prueba"), ("enter", b"\r"),
("slash", b"/"), ("tab", b"\t"),
("arrow", b"\x1b[C"), ("ctrl-l", b"\x0c")]:
os.write(fd, seq)
print(f"{name:8s} -> {len(pump(2))} bytes of output")

os.write(fd, b"\x03") # Ctrl+C
print(f"ctrl-c -> {len(pump(3))} bytes of output")

Output:

text -> 0 bytes of output
enter -> 0 bytes of output
slash -> 0 bytes of output
tab -> 0 bytes of output
arrow -> 0 bytes of output
ctrl-l -> 0 bytes of output
ctrl-c -> 102 bytes of output <-- teardown sequences, process exits

Expected behavior

Bytes written to the PTY should be handled exactly as if typed: printable characters appear in the composer, Enter submits the prompt. This is what every other agent TUI I drive the same way does (Codex, for example, accepts the identical injected input).

Additional context

  • OS: macOS (Darwin 25.5.0), arm64
  • Node: v22.17.1 (installed via nvm), @github/copilot npm install
  • Shell: zsh

Things I ruled out:

  • Not a raw-mode problem. While the TUI is up, the PTY's termios is correctly in raw mode: ICANON=False, ECHO=False, ISIG=False, VMIN=1. Since ISIG is off, the working Ctrl+C must be handled by the application itself — confirming the read loop is alive.
  • Not a capability-negotiation deadlock. Copilot emits a kitty-keyboard query (CSI ? u), a theme query, alt-screen, bracketed paste (?2004h), mouse tracking and focus reporting (?1004h). Answering them (CSI ?0u, CSI ?997;1n, CSI ?62;1;6c) does not unblock input.
  • Not a focus problem. Sending focus-in (CSI I) after ?1004h changes nothing.
  • Not a paste-detection problem. Wrapping input in bracketed paste (ESC[200~…ESC[201~) changes nothing.
  • Not a "typed too fast" problem. Writing one byte at a time with 250 ms between characters changes nothing.
  • Not terminal-emulator specific. Same failure through a real terminal emulator (an Orca-managed pane) as through a bare pty.fork(). In the emulator case the injected string is even rendered appended to the footer line rather than into the ❯ composer, and Enter still submits nothing.
  • Not an injection-tooling problem. The identical injection path drives a plain shell and another agent's TUI correctly.

Debug log (copilot --log-level debug --log-dir ./logs) shows no input-related error at all. The only entries at the moment of the write are:

[INFO] Unregistering foreground session: d13a790d-…
[DEBUG] Broadcasting session lifecycle event: session.background for session d13a790d-…
[INFO] Registering foreground session: d13a790d-…
[DEBUG] Broadcasting session lifecycle event: session.foreground for session d13a790d-…

Impact: this makes the interactive TUI unusable from any agent-orchestration or automation harness. Current workaround is the non-interactive -p/--prompt mode, which loses the multi-turn session.

Activity

  1. added theissue type on Jul 19, 2026
  2. added
    area:input-keyboardKeyboard shortcuts, keybindings, copy/paste, clipboard, mouse, and text input
    and removed on Jul 20, 2026
  3. added a commit that references this issue on Oct 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:input-keyboardKeyboard shortcuts, keybindings, copy/paste, clipboard, mouse, and text input

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions