diff --git a/src/webterm/docker_exec_session.py b/src/webterm/docker_exec_session.py index 26fdfcb..19549b6 100644 --- a/src/webterm/docker_exec_session.py +++ b/src/webterm/docker_exec_session.py @@ -29,14 +29,17 @@ DEFAULT_SCREEN_WIDTH = 132 DEFAULT_SCREEN_HEIGHT = 45 # Pattern to filter out terminal device attribute responses that cause display issues -# These are responses to queries that shouldn't be displayed as text. -# Matches complete DA1/DA2 responses like \x1b[?1;10;0c or \x1b[?64;1;2;...c -DA_RESPONSE_PATTERN = re.compile(rb"\x1b\[\?[\d;]+c") +# These are responses to DA1/DA2/DA3 queries that shouldn't be displayed as text +# Matches complete responses like: +# \x1b[?1;10;0c (DA1 - Primary Device Attributes) +# \x1b[>1;10;0c (DA2 - Secondary Device Attributes, sent by tmux) +# \x1b[=1;0c (DA3 - Tertiary Device Attributes) +DA_RESPONSE_PATTERN = re.compile(rb"\x1b\[[?>=][\d;]*c") # Pattern to detect partial DA responses at end of data (incomplete escape sequence) -# Matches: \x1b, \x1b[, \x1b[?, \x1b[?1, \x1b[?1;, \x1b[?1;10, etc. +# Matches: \x1b, \x1b[, \x1b[?, \x1b[>, \x1b[=, \x1b[?1, \x1b[>1;10, etc. # These need to be held back until more data arrives to see if they complete -DA_PARTIAL_PATTERN = re.compile(rb"\x1b(?:\[(?:\?[\d;]*)?)?$") +DA_PARTIAL_PATTERN = re.compile(rb"\x1b(?:\[(?:[?>=][\d;]*)?)?$") @dataclass(frozen=True) diff --git a/src/webterm/local_server.py b/src/webterm/local_server.py index 6605019..57112c3 100644 --- a/src/webterm/local_server.py +++ b/src/webterm/local_server.py @@ -27,10 +27,11 @@ from .session_manager import SessionManager from .svg_exporter import render_terminal_svg from .types import Meta, RouteKey, SessionID -# Pattern to filter terminal device attribute responses (DA1/DA2) from replay buffer. +# Pattern to filter terminal device attribute responses (DA1/DA2/DA3) from replay buffer. # These responses can appear as visible text like "1;10;0c" if split across reads. +# Matches: \x1b[?...c (DA1), \x1b[>...c (DA2 from tmux), \x1b[=...c (DA3) # See docker_exec_session.py and terminal_session.py for main filtering. -DA_RESPONSE_PATTERN = re.compile(rb"\x1b\[\?[\d;]+c") +DA_RESPONSE_PATTERN = re.compile(rb"\x1b\[[?>=][\d;]*c") if TYPE_CHECKING: from .config import Config diff --git a/src/webterm/terminal_session.py b/src/webterm/terminal_session.py index 0f51f76..2429b76 100644 --- a/src/webterm/terminal_session.py +++ b/src/webterm/terminal_session.py @@ -33,13 +33,16 @@ DEFAULT_SCREEN_WIDTH = 132 DEFAULT_SCREEN_HEIGHT = 45 # Pattern to filter out terminal device attribute responses that cause display issues -# These are responses to DA1/DA2 queries that shouldn't be displayed as text -# Matches complete responses like \x1b[?1;10;0c or \x1b[?64;1;2;...c -DA_RESPONSE_PATTERN = re.compile(rb"\x1b\[\?[\d;]+c") +# These are responses to DA1/DA2/DA3 queries that shouldn't be displayed as text +# Matches complete responses like: +# \x1b[?1;10;0c (DA1 - Primary Device Attributes) +# \x1b[>1;10;0c (DA2 - Secondary Device Attributes, sent by tmux) +# \x1b[=1;0c (DA3 - Tertiary Device Attributes) +DA_RESPONSE_PATTERN = re.compile(rb"\x1b\[[?>=][\d;]*c") # Pattern to detect partial DA responses at end of data (incomplete escape sequence) -# Matches: \x1b, \x1b[, \x1b[?, \x1b[?1, \x1b[?1;, etc. -DA_PARTIAL_PATTERN = re.compile(rb"\x1b(?:\[(?:\?[\d;]*)?)?$") +# Matches: \x1b, \x1b[, \x1b[?, \x1b[>, \x1b[=, \x1b[?1, \x1b[>1;10, etc. +DA_PARTIAL_PATTERN = re.compile(rb"\x1b(?:\[(?:[?>=][\d;]*)?)?$") class TerminalSession(Session):