Repository navigation
Description
Summary
After exiting the V2 TUI on Linux, a leftover escape-sequence fragment from OpenCode's Kitty-graphics capability probe is printed at the shell prompt. It is cosmetic, but it leaves stray bytes on the readline line, which can block Ctrl+D (EOF).
Environment
- opencode version: 2.0.29
- OS: Linux x86_64, kernel
7.2.10-x64v3-xanmod1(Linux ... #0~20261011.g455a2bf SMP PREEMPT_DYNAMIC Sun Oct 11 16:57:09 UTC 2026 x86_64 GNU/Linux) - Terminal: qTerminal 2.1.0 (
TERM=xterm-256color,COLORTERM=truecolor,TERM_PROGRAMunset) - Shell: /bin/bash
- Install/channel: release (single binary at
~/.opencode/bin/opencode) - Active plugins: one TUI plugin,
file:///home/<user>/.config/opencode/plugins/orca-opencode-status-tui/tui.js. No project-local config. - Multiplexer: none (
$TMUXunset)
Reproduction
-
Open qTerminal with bash.
-
Run
opencode(v2.0.29). -
Exit the TUI normally (Ctrl+C or
/exit). -
Observe leftover bytes on the shell prompt line:
[user@host ~/AI_DEV]$ oc +q4d73ppppppGi=31337,s=1,v=1,a=q,t=d,f=24;AAAA
Reproducible on every exit.
Expected Behavior
The shell prompt is clean after OpenCode exits; terminal capability-probe replies are fully consumed before the terminal is restored to cooked mode.
Actual Behavior
A leftover fragment from the Kitty-graphics capability probe is printed at the prompt:
+..+q4d73ppppppGi=31337,s=1,v=1,a=q,t=d,f=24;AAAA
Additional Context
The leaked fragment matches, byte for byte, the Kitty-graphics capability probe OpenCode sends at startup. It is present in the shipped binary:
$ grep -a -o '.\{40\}a=q,t=d,f=24.\{20\}' ~/.opencode/bin/opencode
...\x1b_Gi=31337,s=1,v=1,a=q,t=d,f=24;AAAA\x1b\\...
So Gi=31337,s=1,v=1,a=q,t=d,f=24;AAAA is OpenCode's own startup probe (a=q = query, i=31337 = magic image id, AAAA = base64 of a 1x1 black pixel), not a terminal reply. The +q4d73pppppp prefix looks like a fragment of an adjacent probe/reply (the ppppp garble matches #15084).
This appears to be the POSIX half of the terminal-teardown bug class that was fixed for V1 in #17081 (stale stdin bytes leak to shell after exit on POSIX). Per that issue, opentui's teardown removed the stdin listener and disabled raw mode but never flushed the tty input buffer; the V1 fix added tcflush(STDIN_FILENO, TCIFLUSH). This looks like a V2 regression.
Related issues: #17081, #15084, #16547, #24475, and current V2 reports #55163 (raw mode left after /exit) and #55213.
Notes:
- Not running under tmux, so
allow-passthroughis not involved. cli.jsonalready setstheme.mode: "dark", so the OSC 10/11 theme-color probes are not the trigger; the leaked bytes are the graphics probe.- No public V2 setting exists to disable the Kitty-graphics capability probe.
Workarounds:
Ctrl+Lclears the line;reset/stty sanerecovers a jammed prompt.- Shell hook:
precmd() { stty sane; }(zsh) orPROMPT_COMMAND='stty sane'(bash).
Activity
opencode-agent commentedon Oct 15, 2026
Thanks for the detailed report. I can reproduce this on 2.0.29 in qTerminal (
TERM=xterm-256color, bash, no tmux). After exiting the TUI,…73ppppppGi=31337,s=1,v=1,a=q,t=d,f=24;AAAAis left on the screen. The recording and screenshot below show it, and the script below reproduces it under Xvfb.I think the cause is a bit different from #17081, though. A raw capture of the terminal output shows OpenCode sends its capability probes on the normal screen before it switches to the alternate screen:
ESC P +q4d73 ESC \)$pESC _ Gi=31337…;AAAA ESC \)qTerminal doesn't understand DCS/APC sequences, so it draws their contents as text:
+q4d73, then apfrom each mode query, thenGi=31337…. That text is still on the normal screen when OpenCode exits.In my test this was only on the screen. Typing a command right after exiting worked normally, so the shell's input line held no stray bytes, and I couldn't reproduce the Ctrl+D problem. If Ctrl+D is still blocked for you, it would help to know what's on the line when you press it. For example, does
echo hirun cleanly right after exiting?I couldn't run the latest
dev(4397ee4) from source here. But the latest release is still 2.0.29, and the terminal library that sends these probes (@opentui0.5.17) is the same version ondev, so it most likely still happens there.recording.mp4
Reproduction script (qterm-repro.sh)
Run it:
bash qterm-repro.shdersenok commentedon Oct 15, 2026
Reporter here — thanks for the detailed repro. Confirming from my side, with one difference from your run:
Ctrl+Ddoes not work right after exit, and unlike your test there is a stray character sitting on the readline line. PressingEnter(orCtrl+L) clears it, and thenCtrl+Dworks again. So on my machine both halves are present:+q4d73+ sixps +Gi=31337,…), andSo it looks like V2 may have regressed the #17081
tcflushfix while the screen-scrape half (probes emitted before entering the alt screen) is separate.Env: qTerminal 2.1.0,
TERM=xterm-256color,COLORTERM=truecolor,/bin/bash, no tmux, opencode 2.0.29.Happy to run a targeted diagnostic if useful — e.g. dump the readline line as octal right after exit, before touching the keyboard, to identify which byte leaks into the input buffer. Just tell me what you'd like captured.
Finn763 commentedon Oct 21, 2026
I'd like to work on this — the Kitty graphics probe leaves its response fragment unread at exit; I'll clear it in the TUI shutdown path.