@@ -154,6 +154,14 @@ async def _interactive_session(ws_url, token):
154154 old_settings = termios .tcgetattr (fd )
155155 try :
156156 tty .setraw (fd )
157+ # Re-enable output post-processing so the local terminal converts
158+ # bare \n to \r\n. The remote PTY may send lone \n (Kubernetes
159+ # exec PTY behavior). xterm.js handles this with convertEol;
160+ # for a raw CLI terminal we need OPOST. Extra \r before \n from
161+ # a remote that already sends \r\n is harmless.
162+ attrs = termios .tcgetattr (fd )
163+ attrs [1 ] |= termios .OPOST
164+ termios .tcsetattr (fd , termios .TCSANOW , attrs )
157165 rows , cols = shutil .get_terminal_size ()
158166
159167 headers = {"Authorization" : f"Bearer { token } " }
@@ -173,26 +181,26 @@ def _send_resize():
173181 )
174182
175183 async def _force_initial_redraw ():
176- """Set PTY dimensions from inside the shell and clear screen.
177-
178- The WebSocket resize message may not reliably update the
179- remote PTY size (race with shell startup, ArgoCD buffering).
180- Sending ``stty rows R cols C`` directly through stdin is
181- authoritative -- it always works because the shell itself
182- calls the TIOCSWINSZ ioctl. The leading space keeps the
183- command out of bash history when HISTCONTROL=ignorespace.
184+ """Toggle PTY width to force SIGWINCH, then Ctrl+L to redraw.
185+
186+ The initial resize may arrive before the remote shell
187+ starts, so the shell never sees a SIGWINCH. Toggling
188+ cols by +1/-1 guarantees a size change and SIGWINCH.
189+ Ctrl+L then clears the screen so the prompt redraws at
190+ the correct width.
184191 """
185192 try :
186193 await asyncio .sleep (0.5 )
187194 r , c = shutil .get_terminal_size ()
188195 await ws .send (
189- json .dumps (
190- {
191- "operation" : "stdin" ,
192- "data" : f" stty rows { r } cols { c } ; clear\n " ,
193- }
194- )
196+ json .dumps ({"operation" : "resize" , "rows" : r , "cols" : c + 1 })
197+ )
198+ await asyncio .sleep (0.05 )
199+ await ws .send (
200+ json .dumps ({"operation" : "resize" , "rows" : r , "cols" : c })
195201 )
202+ await asyncio .sleep (0.1 )
203+ await ws .send (json .dumps ({"operation" : "stdin" , "data" : "\x0c " }))
196204 except Exception :
197205 pass
198206
0 commit comments