[GH-ISSUE #334] Kitty Graphics Protocol query leaks Gi=31337 response into tmux pane title #856

Closed
opened 2026-03-14 08:49:53 +03:00 by kerem · 5 comments
Owner

Originally created by @festeh on GitHub (Nov 21, 2025).
Original GitHub issue: https://github.com/anomalyco/opentui/issues/334

Describe the bug

When running an application using @opentui/core (opencode) inside tmux, a cryptic string resembling Gi=31337,s=1,v=1,a=q,t=d,f=24;AAAA appears in the tmux pane title or leaks into the shell output immediately after startup.

Root Cause

The issue stems from the queryTerminalSend function in packages/core/src/zig/terminal.zig, which sends the kittyGraphicsQuery escape sequence unconditionally during initialization.
https://github.com/sst/opentui/blob/main/packages/core/src/zig/terminal.zig#L176
// packages/core/src/zig/terminal.zig
ansi.ANSI.kittyGraphicsQuery ++
This sends \x1b_Gi=31337... to probe for Kitty graphics support. When running inside tmux, the terminal's response to this query is often not trapped correctly by the application.

To Reproduce

  1. Start tmux.
  2. Run an opentui-based application (e.g., opencode).
  3. Observe that the pane title changes to the graphics query response

Proposed Solution

  1. Conditionality: The graphics probe should not be sent unconditionally. It should check if the environment supports it or if a specific environment variable is set to disable it.
  2. Tmux Support: If the intention is to support graphics inside tmux, the query should be wrapped in the correct passthrough escape sequence when TERM=screen or TERM=tmux.
  3. Escape Hatch: Add an environment variable (e.g., OPENTUI_NO_GRAPHICS) that allows users to disable this specific probe entirely.
Originally created by @festeh on GitHub (Nov 21, 2025). Original GitHub issue: https://github.com/anomalyco/opentui/issues/334 # Describe the bug When running an application using @opentui/core (opencode) inside tmux, a cryptic string resembling `Gi=31337,s=1,v=1,a=q,t=d,f=24;AAAA` appears in the tmux pane title or leaks into the shell output immediately after startup. # Root Cause The issue stems from the queryTerminalSend function in packages/core/src/zig/terminal.zig, which sends the kittyGraphicsQuery escape sequence unconditionally during initialization. https://github.com/sst/opentui/blob/main/packages/core/src/zig/terminal.zig#L176 // packages/core/src/zig/terminal.zig ansi.ANSI.kittyGraphicsQuery ++ This sends \x1b_Gi=31337... to probe for Kitty graphics support. When running inside tmux, the terminal's response to this query is often not trapped correctly by the application. # To Reproduce 1. Start tmux. 2. Run an opentui-based application (e.g., opencode). 3. Observe that the pane title changes to the graphics query response # Proposed Solution 1. Conditionality: The graphics probe should not be sent unconditionally. It should check if the environment supports it or if a specific environment variable is set to disable it. 2. Tmux Support: If the intention is to support graphics inside tmux, the query should be wrapped in the correct passthrough escape sequence when TERM=screen or TERM=tmux. 3. Escape Hatch: Add an environment variable (e.g., OPENTUI_NO_GRAPHICS) that allows users to disable this specific probe entirely.
kerem 2026-03-14 08:49:53 +03:00
Author
Owner

@kommander commented on GitHub (Nov 22, 2025):

Yeah, that is annoying. Problem is that this is how the docs/specs suggest to detect if it is supported. I think the passthrough wrapping could work when it's local, but for remote it would have to wait and hope for xtversion and in many cases tmux rewrites to tell it's the underlying terminal and not tmux, so remote it wouldn't know. Confusing.

I'd try the passthrough wrapping if it is detected as tmux for now.

<!-- gh-comment-id:3565168104 --> @kommander commented on GitHub (Nov 22, 2025): Yeah, that is annoying. Problem is that this is how the docs/specs suggest to detect if it is supported. I think the passthrough wrapping could work when it's local, but for remote it would have to wait and hope for xtversion and in many cases tmux rewrites to tell it's the underlying terminal and not tmux, so remote it wouldn't know. Confusing. I'd try the passthrough wrapping if it is detected as tmux for now.
Author
Owner

@festeh commented on GitHub (Nov 26, 2025):

I tried to work on it and eventually decided to abandon tmux entirely, so I'm no longer looking for a fix. I still have some working code that checks if we're in tmux and not sends kitty query in this case. It's more complicated than #343, no not sure if I should open a PR.

<!-- gh-comment-id:3581206831 --> @festeh commented on GitHub (Nov 26, 2025): I tried to work on it and eventually decided to abandon tmux entirely, so I'm no longer looking for a fix. I still have some working code that checks if we're in tmux and not sends kitty query in this case. It's more complicated than #343, no not sure if I should open a PR.
Author
Owner

@kommander commented on GitHub (Nov 26, 2025):

Yeah, I hate tmux by now. There is still zellij, but has other issues. Not solving this is probably not an option as too many people are still using it.

So either:

  • there is another way to detect kitty graphics support
  • we find the root cause for tmux treating it as title replacement and work around it
  • or tmux fixes it (doubt)
<!-- gh-comment-id:3581404036 --> @kommander commented on GitHub (Nov 26, 2025): Yeah, I hate tmux by now. There is still zellij, but has other issues. Not solving this is probably not an option as too many people are still using it. So either: - there is another way to detect kitty graphics support - we find the root cause for tmux treating it as title replacement and work around it - or tmux fixes it (doubt)
Author
Owner

@festeh commented on GitHub (Nov 26, 2025):

It turned out kitty already has what I need - project-based sessions (with session files), switching between them can be done with hyprland workspaces and ssh persistence is possible with systemd daemons. So I'm living happily without tmux now.

Now, I tinkered with opencode on this issue and we came to conclusion that we don't know how to fix it when the kitty graphics query is sent, regardless of allowing passthrough or adding some weird char sequences that AI did for tmux-specific query. I think it requires some deeper tmux expertise to go with option 2.

<!-- gh-comment-id:3582061506 --> @festeh commented on GitHub (Nov 26, 2025): It turned out kitty already has what I need - project-based sessions (with session files), switching between them can be done with hyprland workspaces and ssh persistence is possible with systemd daemons. So I'm living happily without tmux now. Now, I tinkered with opencode on this issue and we came to conclusion that we don't know how to fix it when the kitty graphics query is sent, regardless of allowing passthrough or adding some weird char sequences that AI did for tmux-specific query. I think it requires some deeper tmux expertise to go with option 2.
Author
Owner

@kommander commented on GitHub (Nov 26, 2025):

Thanks for looking into it, I am currently out of ideas, will get back to it.

<!-- gh-comment-id:3582588633 --> @kommander commented on GitHub (Nov 26, 2025): Thanks for looking into it, I am currently out of ideas, will get back to it.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/opentui#856
No description provided.