77 "strconv"
88
99 tea "github.com/charmbracelet/bubbletea"
10+ "github.com/charmbracelet/lipgloss"
1011 "github.com/charmbracelet/x/term"
12+ "github.com/muesli/termenv"
1113
1214 "github.com/evolution-cms/installer/internal/domain"
1315)
@@ -17,8 +19,6 @@ func Run(ctx context.Context, mode Mode, events <-chan domain.Event, meta Meta)
1719}
1820
1921func RunWithCancel (ctx context.Context , mode Mode , events <- chan domain.Event , actions chan <- domain.Action , meta Meta , cancel func ()) error {
20- m := NewModel (ctx , mode , events , actions , meta , cancel )
21-
2222 in := os .Stdin
2323 out := os .Stdout
2424 var tty * os.File
@@ -38,6 +38,12 @@ func RunWithCancel(ctx context.Context, mode Mode, events <-chan domain.Event, a
3838 defer tty .Close ()
3939 }
4040
41+ // Ensure Lip Gloss and other Charm components detect color capabilities based on the
42+ // actual terminal output we're writing to (which might be /dev/tty).
43+ configureTerminalOutput (out )
44+
45+ m := NewModel (ctx , mode , events , actions , meta , cancel )
46+
4147 // Seed a sensible initial size so the UI can render even if WindowSizeMsg never arrives.
4248 if w , h , ok := detectTerminalSize (in , out , tty ); ok {
4349 m .width = w
@@ -53,6 +59,17 @@ func RunWithCancel(ctx context.Context, mode Mode, events <-chan domain.Event, a
5359 return err
5460}
5561
62+ func configureTerminalOutput (out * os.File ) {
63+ if out == nil {
64+ return
65+ }
66+
67+ o := termenv .NewOutput (out , termenv .WithTTY (true ), termenv .WithColorCache (true ))
68+ termenv .SetDefaultOutput (o )
69+ lipgloss .DefaultRenderer ().SetOutput (o )
70+ lipgloss .SetColorProfile (o .Profile )
71+ }
72+
5673func detectTerminalSize (in * os.File , out * os.File , tty * os.File ) (w int , h int , ok bool ) {
5774 fds := []uintptr {}
5875 if out != nil {
0 commit comments