From 764cde5ad60de842be7935a937d451ebcb299f14 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 8 Jun 2026 13:52:52 +0000 Subject: [PATCH 1/5] Initial plan From 0f71a7ee55df4d767ff123d33eaaae9e851d4c19 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 8 Jun 2026 14:07:33 +0000 Subject: [PATCH 2/5] Avoid Windows startup terminal probe on redirected stderr Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/styles/theme.go | 23 +++++++++++++++++++- pkg/styles/theme_test.go | 45 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/pkg/styles/theme.go b/pkg/styles/theme.go index 504db7475fd..e46742e70df 100644 --- a/pkg/styles/theme.go +++ b/pkg/styles/theme.go @@ -48,6 +48,7 @@ package styles import ( "os" + "runtime" lipgloss "charm.land/lipgloss/v2" "charm.land/lipgloss/v2/compat" @@ -59,8 +60,28 @@ func configureLipglossCompat() { compat.Profile = colorprofile.Detect(os.Stderr, os.Environ()) } +func shouldConfigureLipglossCompat(goos string, stderrMode os.FileMode, statErr error) bool { + // On Windows, querying terminal capabilities against redirected/pipe handles + // can hang under some wrapper environments. Skip startup probing unless stderr + // is attached to a character device. + if goos == "windows" { + if statErr != nil { + return false + } + return stderrMode&os.ModeCharDevice != 0 + } + return true +} + func init() { - configureLipglossCompat() + stderrInfo, statErr := os.Stderr.Stat() + stderrMode := os.FileMode(0) + if stderrInfo != nil { + stderrMode = stderrInfo.Mode() + } + if shouldConfigureLipglossCompat(runtime.GOOS, stderrMode, statErr) { + configureLipglossCompat() + } } // Hex color constants for light and dark variants. diff --git a/pkg/styles/theme_test.go b/pkg/styles/theme_test.go index d797cb6e8a2..b7bcb330838 100644 --- a/pkg/styles/theme_test.go +++ b/pkg/styles/theme_test.go @@ -280,6 +280,51 @@ func TestConfigureLipglossCompatUsesStderr(t *testing.T) { } } +func TestShouldConfigureLipglossCompat(t *testing.T) { + tests := []struct { + name string + goos string + stderrMode os.FileMode + statErr error + want bool + }{ + { + name: "windows character device", + goos: "windows", + stderrMode: os.ModeCharDevice, + want: true, + }, + { + name: "windows redirected pipe", + goos: "windows", + stderrMode: os.ModeNamedPipe, + want: false, + }, + { + name: "windows stat error", + goos: "windows", + statErr: os.ErrPermission, + want: false, + }, + { + name: "non-windows still configures", + goos: "linux", + stderrMode: os.ModeNamedPipe, + statErr: os.ErrPermission, + want: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := shouldConfigureLipglossCompat(tt.goos, tt.stderrMode, tt.statErr) + if got != tt.want { + t.Fatalf("shouldConfigureLipglossCompat(%q, %v, %v) = %v, want %v", tt.goos, tt.stderrMode, tt.statErr, got, tt.want) + } + }) + } +} + // TestBordersExist verifies that all expected border definitions are defined func TestBordersExist(t *testing.T) { borders := map[string]lipgloss.Border{ From fbed8bca08cdd8cebedb42b9e36e6e06c7f8fe86 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 8 Jun 2026 14:08:28 +0000 Subject: [PATCH 3/5] Harden stderr stat guard in style probe init Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/styles/theme.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/styles/theme.go b/pkg/styles/theme.go index e46742e70df..d30ee7e9fbb 100644 --- a/pkg/styles/theme.go +++ b/pkg/styles/theme.go @@ -75,6 +75,9 @@ func shouldConfigureLipglossCompat(goos string, stderrMode os.FileMode, statErr func init() { stderrInfo, statErr := os.Stderr.Stat() + if stderrInfo == nil && statErr == nil { + statErr = os.ErrInvalid + } stderrMode := os.FileMode(0) if stderrInfo != nil { stderrMode = stderrInfo.Mode() From 103f7be463b63a334099d82209c76fc20879e9c2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 8 Jun 2026 14:09:13 +0000 Subject: [PATCH 4/5] Clarify defensive stderr probe handling comments Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/styles/theme.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pkg/styles/theme.go b/pkg/styles/theme.go index d30ee7e9fbb..f9017021d28 100644 --- a/pkg/styles/theme.go +++ b/pkg/styles/theme.go @@ -75,9 +75,14 @@ func shouldConfigureLipglossCompat(goos string, stderrMode os.FileMode, statErr func init() { stderrInfo, statErr := os.Stderr.Stat() - if stderrInfo == nil && statErr == nil { + // Defensive fallback: Stat should not normally return (nil, nil). Treat that + // impossible state as an invalid stderr handle so Windows startup probing is + // safely skipped. + if statErr == nil && stderrInfo == nil { statErr = os.ErrInvalid } + // Zero mode means "unknown/unset"; on Windows this keeps the startup probe + // disabled unless stderr is explicitly confirmed as a character device. stderrMode := os.FileMode(0) if stderrInfo != nil { stderrMode = stderrInfo.Mode() From 0406514ad021a86f3b9266a985cbff0df770c34d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 8 Jun 2026 14:33:35 +0000 Subject: [PATCH 5/5] Tighten Windows stderr mode detection Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/styles/theme.go | 2 +- pkg/styles/theme_test.go | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/pkg/styles/theme.go b/pkg/styles/theme.go index f9017021d28..8a4be34d989 100644 --- a/pkg/styles/theme.go +++ b/pkg/styles/theme.go @@ -68,7 +68,7 @@ func shouldConfigureLipglossCompat(goos string, stderrMode os.FileMode, statErr if statErr != nil { return false } - return stderrMode&os.ModeCharDevice != 0 + return stderrMode&(os.ModeDevice|os.ModeCharDevice) == (os.ModeDevice | os.ModeCharDevice) } return true } diff --git a/pkg/styles/theme_test.go b/pkg/styles/theme_test.go index b7bcb330838..583d0d09a36 100644 --- a/pkg/styles/theme_test.go +++ b/pkg/styles/theme_test.go @@ -291,7 +291,7 @@ func TestShouldConfigureLipglossCompat(t *testing.T) { { name: "windows character device", goos: "windows", - stderrMode: os.ModeCharDevice, + stderrMode: os.ModeDevice | os.ModeCharDevice, want: true, }, { @@ -300,12 +300,24 @@ func TestShouldConfigureLipglossCompat(t *testing.T) { stderrMode: os.ModeNamedPipe, want: false, }, + { + name: "windows zero mode stat success", + goos: "windows", + stderrMode: os.FileMode(0), + want: false, + }, { name: "windows stat error", goos: "windows", statErr: os.ErrPermission, want: false, }, + { + name: "windows ErrInvalid fallback", + goos: "windows", + statErr: os.ErrInvalid, + want: false, + }, { name: "non-windows still configures", goos: "linux",