fix: redirect spinner output from stdout to stderr (#176)

The spinner goroutine was writing carriage-return + status text to
os.Stdout every 100ms. In the non-interactive TTY path, the child
process also writes directly to os.Stdout, causing both writers to
race on the same file descriptor. The \r emitted by the spinner
resets the cursor to column 0 mid-line, corrupting and truncating
the child process output.

Fix by writing all spinner/status output to os.Stderr, which is the
standard Unix convention for diagnostic and status messages. This is
also consistent with how progress.go and ShowWarning already behave.

https://claude.ai/code/session_012jMiRSS4Jx9Bs7a2F4S6KN

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Sahil Bansal
2026-03-06 08:27:11 +05:30
committed by GitHub
co-authored by Claude
parent 8cba52201c
commit 70db1b3078
2 changed files with 5 additions and 4 deletions
+4 -3
View File
@@ -2,6 +2,7 @@ package ui
import (
"fmt"
"os"
"sync"
"time"
)
@@ -44,7 +45,7 @@ func StartSpinnerWithColor(msg string, c ColorFn) {
ticker.Stop()
return
case <-ticker.C:
fmt.Printf("\r%s ... %s", c("PMG: "+msg), string(frames[pos%length]))
fmt.Fprintf(os.Stderr, "\r%s ... %s", c("PMG: "+msg), string(frames[pos%length]))
pos += 1
}
}
@@ -69,6 +70,6 @@ func StopSpinner() {
spinnerChan = nil
fmt.Printf("\r")
fmt.Println()
fmt.Fprint(os.Stderr, "\r")
fmt.Fprintln(os.Stderr)
}
+1 -1
View File
@@ -50,7 +50,7 @@ func SetVerbosityLevel(level VerbosityLevel) {
func ClearStatus() {
StopSpinner()
fmt.Print("\r")
fmt.Fprint(os.Stderr, "\r")
}
func Block(config *BlockConfig) error {