fix: revert docker exec -i change and use stty with line hiding
Reverted docker exec back to -it (required for interactive bash). Instead, sends stty command with \r to hide it from the terminal display: - \r moves cursor to start of line (overwrites prompt) - stty command executes silently (no output on success) - \r moves cursor back to start, hiding echoed command This sends stty on EVERY resize so the container shell always matches frontend dimensions.
This commit is contained in:
@@ -61,15 +61,11 @@ class TerminalSession:
|
||||
logger.info(f"Starting terminal session {self.session_id} for container {self.container_id} with initial size {self._cols}x{self._rows}")
|
||||
|
||||
# Start docker exec with the slave fd as stdin/stdout/stderr
|
||||
# Using -i (interactive) but NOT -t (tty) because:
|
||||
# 1. The slave fd IS a TTY
|
||||
# 2. docker exec -t creates its OWN PTY inside the container
|
||||
# 3. This prevents host PTY resize from propagating to the container shell
|
||||
# By using only -i, docker exec uses our PTY slave directly
|
||||
# Using -it because the slave fd IS a TTY
|
||||
self.process = await asyncio.create_subprocess_exec(
|
||||
"docker",
|
||||
"exec",
|
||||
"-i",
|
||||
"-it",
|
||||
"-e",
|
||||
"TERM=xterm",
|
||||
self.container_id,
|
||||
@@ -155,6 +151,16 @@ class TerminalSession:
|
||||
self._rows = rows
|
||||
logger.info(f"resize() called for session {self.session_id}: {cols}x{rows}")
|
||||
self._set_terminal_size(cols, rows)
|
||||
|
||||
# Docker exec -it creates its own PTY inside the container,
|
||||
# so host PTY resize doesn't propagate. We must send stty manually.
|
||||
# To hide the command from the user:
|
||||
# 1. \r moves cursor to start of current line (overwrites prompt)
|
||||
# 2. stty command executes silently (no output on success)
|
||||
# 3. \r moves cursor back to start, hiding the echoed command
|
||||
stty_cmd = f"\rstty cols {cols} rows {rows}\r".encode()
|
||||
await self.write_input(stty_cmd)
|
||||
logger.debug(f"Sent stty resize to container for session {self.session_id}: {cols}x{rows}")
|
||||
|
||||
async def reset(self) -> None:
|
||||
"""Reset the session by killing the process and clearing state."""
|
||||
|
||||
Reference in New Issue
Block a user