github / github/copilot-cli

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

Offen
#4,180 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

area:input-keyboard
Vorherrschende Sprache
Shell
Sterne
11.2k
Forks
1.9k
Ø Merge
14 Std. 16 Min.
Gemergte PRs (30 T.)
6

Beschreibung

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.

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginne damit, die dependency-free repro.py gegen den interaktiven copilot-Einstiegspunkt auszuführen, und vergleiche automatisierte PTY-Eingaben mit manuellen Terminal-Eingaben. Verfolge anschließend die Behandlung von stdin und Tastaturereignissen im TUI und stelle dann sicher, dass druckbare Tasten, Tab, Pfeiltasten, Ctrl+L und Enter den Composer erreichen, während Ctrl+C weiterhin sauber beendet.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
node.js, python, shell
Bereich
cli
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Ruhig
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
38/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.