on main help sign in
fix(tui): disable progress bar for unsupported terminals (#1329)
commit05577de71848be1bae6f9684ddcec280c18fa7ec authorAyman Bagabas <ayman.bagabas@gmail.com> dateWed 29 Oct 2025, 17:55 (1 year ago) parent7b4cb40
2 files changed+48−3
internal/cmd/root.go+22−1 internal/tui/tui.go+26−2
internal/cmd/root.go+22−1
@@ -10,6 +10,7 @@ import (
1010 "os"
1111 "path/filepath"
1212 "strconv"
13+ "strings"
1314
1415 tea "github.com/charmbracelet/bubbletea/v2"
1516 "github.com/charmbracelet/colorprofile"
@@ -21,6 +22,7 @@ import (
2122 "github.com/charmbracelet/crush/internal/version"
2223 "github.com/charmbracelet/fang"
2324 "github.com/charmbracelet/lipgloss/v2"
25+ uv "github.com/charmbracelet/ultraviolet"
2426 "github.com/charmbracelet/x/exp/charmtone"
2527 "github.com/charmbracelet/x/term"
2628 "github.com/spf13/cobra"
@@ -81,8 +83,13 @@ crush -y
8183 event.AppInitialized()
8284
8385 // Set up the TUI.
86+ var env uv.Environ = os.Environ()
87+ ui := tui.New(app)
88+ ui.QueryVersion = shouldQueryTerminalVersion(env)
89+
8490 program := tea.NewProgram(
85− tui.New(app),
91+ ui,
92+ tea.WithEnvironment(env),
8693 tea.WithContext(cmd.Context()),
8794 tea.WithFilter(tui.MouseEventFilter)) // Filter mouse events based on focus state
8895
@@ -250,3 +257,17 @@ func createDotCrushDir(dir string) error {
250257
251258 return nil
252259}
260+
261+func shouldQueryTerminalVersion(env uv.Environ) bool {
262+ termType := env.Getenv("TERM")
263+ termProg, okTermProg := env.LookupEnv("TERM_PROGRAM")
264+ _, okSSHTTY := env.LookupEnv("SSH_TTY")
265+ return (!okTermProg && !okSSHTTY) ||
266+ (!strings.Contains(termProg, "Apple") && !okSSHTTY) ||
267+ // Terminals that do support XTVERSION.
268+ strings.Contains(termType, "ghostty") ||
269+ strings.Contains(termType, "wezterm") ||
270+ strings.Contains(termType, "alacritty") ||
271+ strings.Contains(termType, "kitty") ||
272+ strings.Contains(termType, "rio")
273+}
internal/tui/tui.go+26−2
@@ -4,6 +4,7 @@ import (
44 "context"
55 "fmt"
66 "math/rand"
7+ "slices"
78 "strings"
89 "time"
910
@@ -72,6 +73,14 @@ type appModel struct {
7273
7374 // Chat Page Specific
7475 selectedSessionID string // The ID of the currently selected session
76+
77+ // sendProgressBar instructs the TUI to send progress bar updates to the
78+ // terminal.
79+ sendProgressBar bool
80+
81+ // QueryVersion instructs the TUI to query for the terminal version when it
82+ // starts.
83+ QueryVersion bool
7584}
7685
7786// Init initializes the application model and returns initial commands.
@@ -88,6 +97,9 @@ func (a appModel) Init() tea.Cmd {
8897
8998 cmd = a.status.Init()
9099 cmds = append(cmds, cmd)
100+ if a.QueryVersion {
101+ cmds = append(cmds, tea.RequestTerminalVersion)
102+ }
91103
92104 return tea.Batch(cmds...)
93105}
@@ -99,6 +111,18 @@ func (a *appModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
99111 a.isConfigured = config.HasInitialDataConfig()
100112
101113 switch msg := msg.(type) {
114+ case tea.EnvMsg:
115+ // Is this Windows Terminal?
116+ if !a.sendProgressBar {
117+ a.sendProgressBar = slices.Contains(msg, "WT_SESSION")
118+ }
119+ case tea.TerminalVersionMsg:
120+ termVersion := strings.ToLower(string(msg))
121+ // Only enable progress bar for the following terminals.
122+ if !a.sendProgressBar {
123+ a.sendProgressBar = strings.Contains(termVersion, "ghostty")
124+ }
125+ return a, nil
102126 case tea.KeyboardEnhancementsMsg:
103127 for id, page := range a.pages {
104128 m, pageCmd := page.Update(msg)
@@ -555,7 +579,7 @@ func (a *appModel) View() tea.View {
555579 view.MouseMode = tea.MouseModeCellMotion
556580 view.AltScreen = true
557581
558− if a.app != nil && a.app.AgentCoordinator != nil && a.app.AgentCoordinator.IsBusy() {
582+ if a.sendProgressBar && a.app != nil && a.app.AgentCoordinator != nil && a.app.AgentCoordinator.IsBusy() {
559583 // HACK: use a random percentage to prevent ghostty from hiding it
560584 // after a timeout.
561585 view.ProgressBar = tea.NewProgressBar(tea.ProgressBarIndeterminate, rand.Intn(100))
@@ -564,7 +588,7 @@ func (a *appModel) View() tea.View {
564588}
565589
566590// New creates and initializes a new TUI application model.
567−func New(app *app.App) tea.Model {
591+func New(app *app.App) *appModel {
568592 chatPage := chat.New(app)
569593 keyMap := DefaultKeyMap()
570594 keyMap.pageBindings = chatPage.Bindings()