fix: revert CWD tracker from readLoop — corrupts ANSI escape sequences
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 1m4s
All checks were successful
Build & Sign Wraith / Build Windows + Sign (push) Successful in 1m4s
ProcessOutput() in the readLoop was processing every byte of SSH output, looking for OSC 7 sequences. When these sequences split across read boundaries (common with 32KB buffer), partial sequences leaked through and corrupted xterm.js parser state — producing red/green color blocks instead of text, and characters rendering at wrong widths. Reverted readLoop to direct passthrough (v0.7.3 behavior). Also removed shell integration injection (stty -echo + PROMPT_COMMAND) which caused terminal mode disruption on macOS. Also removed 4px xterm padding that could cause fitAddon cell width miscalculation. CWD tracking will be re-implemented via a separate SSH exec channel that polls pwd without touching the terminal data stream. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
bce77e0932
commit
c3beb6df6b
@ -10,7 +10,6 @@
|
||||
|
||||
.terminal-container .xterm {
|
||||
height: 100%;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.terminal-container .xterm-viewport {
|
||||
|
||||
@ -142,23 +142,10 @@ func (s *SSHService) Connect(hostname string, port int, username string, authMet
|
||||
// Launch goroutine to read stdout and forward data via the output handler
|
||||
go s.readLoop(sessionID, stdout)
|
||||
|
||||
// Inject shell integration for CWD tracking (OSC 7).
|
||||
// Uses stty -echo to suppress the command from appearing in the terminal,
|
||||
// then restores echo. A leading space keeps it out of shell history.
|
||||
go func() {
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
// Suppress echo, set PROMPT_COMMAND for bash (zsh uses precmd),
|
||||
// restore echo, then clear the current line so no visual artifact remains.
|
||||
injection := " stty -echo 2>/dev/null; " +
|
||||
ShellIntegrationCommand("bash") + "; " +
|
||||
"if [ -n \"$ZSH_VERSION\" ]; then " + ShellIntegrationCommand("zsh") + "; fi; " +
|
||||
"stty echo 2>/dev/null\n"
|
||||
sshSession.mu.Lock()
|
||||
if sshSession.Stdin != nil {
|
||||
_, _ = sshSession.Stdin.Write([]byte(injection))
|
||||
}
|
||||
sshSession.mu.Unlock()
|
||||
}()
|
||||
// CWD tracking disabled — ProcessOutput() in the readLoop was corrupting
|
||||
// ANSI escape sequences when OSC 7 sequences split across read boundaries.
|
||||
// CWD following will be re-implemented via a separate SSH exec channel
|
||||
// that doesn't touch the terminal data stream.
|
||||
|
||||
return sessionID, nil
|
||||
}
|
||||
@ -216,33 +203,14 @@ func (s *SSHService) buildHostKeyCallback(hostname string, port int) ssh.HostKey
|
||||
// (stripping OSC 7 sequences), and calls the output handler with cleaned data.
|
||||
// It stops when the reader returns an error (typically EOF when the session closes).
|
||||
func (s *SSHService) readLoop(sessionID string, reader io.Reader) {
|
||||
// Grab the CWD tracker for this session (if any)
|
||||
s.mu.RLock()
|
||||
sess := s.sessions[sessionID]
|
||||
s.mu.RUnlock()
|
||||
|
||||
buf := make([]byte, 32*1024)
|
||||
for {
|
||||
n, err := reader.Read(buf)
|
||||
if n > 0 {
|
||||
if n > 0 && s.outputHandler != nil {
|
||||
data := make([]byte, n)
|
||||
copy(data, buf[:n])
|
||||
|
||||
// Process CWD tracking — strips OSC 7 sequences from output
|
||||
if sess != nil && sess.CWDTracker != nil {
|
||||
cleaned, newCWD := sess.CWDTracker.ProcessOutput(data)
|
||||
data = cleaned
|
||||
|
||||
// Emit CWD change event if a new path was detected
|
||||
if newCWD != "" && s.cwdHandler != nil {
|
||||
s.cwdHandler(sessionID, newCWD)
|
||||
}
|
||||
}
|
||||
|
||||
if len(data) > 0 && s.outputHandler != nil {
|
||||
s.outputHandler(sessionID, data)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user