on main help sign in
chore: bump bubbletea and ultraviolet dependencies
commit04d05e158480513828a2c2538853432a92f2a630 authorAyman Bagabas <ayman.bagabas@gmail.com> dateMon 9 Feb 2026, 10:50 (8 months ago) parentfb9eb92
6 files changed+55−52
go.mod+3−3 go.sum+6−6 internal/ui/common/capabilities.go+2−1 internal/ui/model/landing.go+2−2 internal/ui/model/sidebar.go+2−1 internal/ui/model/ui.go+40−39
go.mod+3−3
@@ -4,7 +4,7 @@ go 1.25.5
44
55require (
66 charm.land/bubbles/v2 v2.0.0-rc.1.0.20260109112849-ae99f46cec66
7− charm.land/bubbletea/v2 v2.0.0-rc.2.0.20251216153312-819e2e89c62e
7+ charm.land/bubbletea/v2 v2.0.0-rc.2.0.20260209074636-30878e43d7b0
88 charm.land/catwalk v0.17.1
99 charm.land/fantasy v0.7.1
1010 charm.land/glamour/v2 v2.0.0-20260123212943-6014aa153a9b
@@ -22,8 +22,8 @@ require (
2222 github.com/charlievieth/fastwalk v1.0.14
2323 github.com/charmbracelet/colorprofile v0.4.1
2424 github.com/charmbracelet/fang v0.4.4
25− github.com/charmbracelet/ultraviolet v0.0.0-20251212194010-b927aa605560
26− github.com/charmbracelet/x/ansi v0.11.4
25+ github.com/charmbracelet/ultraviolet v0.0.0-20260205113103-524a6607adb8
26+ github.com/charmbracelet/x/ansi v0.11.6
2727 github.com/charmbracelet/x/editor v0.2.0
2828 github.com/charmbracelet/x/etag v0.2.0
2929 github.com/charmbracelet/x/exp/charmtone v0.0.0-20260109001716-2fbdffcb221f
go.sum+6−6
@@ -1,7 +1,7 @@
11charm.land/bubbles/v2 v2.0.0-rc.1.0.20260109112849-ae99f46cec66 h1:2BdJynsAW+8rv9xq6ZS+x0mtacfxpxjIK1KUIeTqBOs=
22charm.land/bubbles/v2 v2.0.0-rc.1.0.20260109112849-ae99f46cec66/go.mod h1:5AbN6cEd/47gkEf8TgiQ2O3RZ5QxMS14l9W+7F9fPC4=
3−charm.land/bubbletea/v2 v2.0.0-rc.2.0.20251216153312-819e2e89c62e h1:tXwTmgGpwZT7ParKF5xbEQBVjM2e1uKhKi/GpfU3mYQ=
4−charm.land/bubbletea/v2 v2.0.0-rc.2.0.20251216153312-819e2e89c62e/go.mod h1:pDM18flq3Z4njKZPA3zCvyVSSIJbMcoqlE82BdGUtL8=
3+charm.land/bubbletea/v2 v2.0.0-rc.2.0.20260209074636-30878e43d7b0 h1:HAbpM9TPjZM18D677ww3VnkKXdd2hyMQtHUsVV0HcPQ=
4+charm.land/bubbletea/v2 v2.0.0-rc.2.0.20260209074636-30878e43d7b0/go.mod h1:3LRff2U4WIYXy7MTxfbAQ+AdfM3D8Xuvz2wbsOD9OHQ=
55charm.land/catwalk v0.17.1 h1:UsHvBi3S7CxONiIZTWKTXM+H9qla8I0fCb/SVru33ms=
66charm.land/catwalk v0.17.1/go.mod h1:kAdk/GjAJbl1AjRjmfU5c9lZfs7PeC3Uy9TgaVtlN64=
77charm.land/fantasy v0.7.1 h1:JOCYeLz32PM11y1u08/YgWl3LfPwhjOIuoyjBXjFofI=
@@ -102,10 +102,10 @@ github.com/charmbracelet/colorprofile v0.4.1 h1:a1lO03qTrSIRaK8c3JRxJDZOvhvIeSco
102102github.com/charmbracelet/colorprofile v0.4.1/go.mod h1:U1d9Dljmdf9DLegaJ0nGZNJvoXAhayhmidOdcBwAvKk=
103103github.com/charmbracelet/fang v0.4.4 h1:G4qKxF6or/eTPgmAolwPuRNyuci3hTUGGX1rj1YkHJY=
104104github.com/charmbracelet/fang v0.4.4/go.mod h1:P5/DNb9DddQ0Z0dbc0P3ol4/ix5Po7Ofr2KMBfAqoCo=
105−github.com/charmbracelet/ultraviolet v0.0.0-20251212194010-b927aa605560 h1:j3PW2hypGoPKBy3ooKzW0TFxaxhyHK3NbkLLn4KeRFc=
106−github.com/charmbracelet/ultraviolet v0.0.0-20251212194010-b927aa605560/go.mod h1:VWATWLRwYP06VYCEur7FsNR2B1xAo7Y+xl1PTbd1ePc=
107−github.com/charmbracelet/x/ansi v0.11.4 h1:6G65PLu6HjmE858CnTUQY1LXT3ZUWwfvqEROLF8vqHI=
108−github.com/charmbracelet/x/ansi v0.11.4/go.mod h1:/5AZ+UfWExW3int5H5ugnsG/PWjNcSQcwYsHBlPFQN4=
105+github.com/charmbracelet/ultraviolet v0.0.0-20260205113103-524a6607adb8 h1:eyFRbAmexyt43hVfeyBofiGSEmJ7krjLOYt/9CF5NKA=
106+github.com/charmbracelet/ultraviolet v0.0.0-20260205113103-524a6607adb8/go.mod h1:SQpCTRNBtzJkwku5ye4S3HEuthAlGy2n9VXZnWkEW98=
107+github.com/charmbracelet/x/ansi v0.11.6 h1:GhV21SiDz/45W9AnV2R61xZMRri5NlLnl6CVF7ihZW8=
108+github.com/charmbracelet/x/ansi v0.11.6/go.mod h1:2JNYLgQUsyqaiLovhU2Rv/pb8r6ydXKS3NIttu3VGZQ=
109109github.com/charmbracelet/x/editor v0.2.0 h1:7XLUKtaRaB8jN7bWU2p2UChiySyaAuIfYiIRg8gGWwk=
110110github.com/charmbracelet/x/editor v0.2.0/go.mod h1:p3oQ28TSL3YPd+GKJ1fHWcp+7bVGpedHpXmo0D6t1dY=
111111github.com/charmbracelet/x/etag v0.2.0 h1:Euj1VkheoHfTYA9y+TCwkeXF/hN8Fb9l4LqZl79pt04=
internal/ui/common/capabilities.go+2−1
@@ -47,7 +47,7 @@ func (c *Capabilities) Update(msg any) {
4747 case tea.WindowSizeMsg:
4848 c.Columns = m.Width
4949 c.Rows = m.Height
50− case uv.WindowPixelSizeEvent:
50+ case uv.PixelSizeEvent:
5151 c.PixelX = m.Width
5252 c.PixelY = m.Height
5353 case uv.KittyGraphicsEvent:
@@ -71,6 +71,7 @@ func (c *Capabilities) Update(msg any) {
7171func QueryCmd(env uv.Environ) tea.Cmd {
7272 var sb strings.Builder
7373 sb.WriteString(ansi.RequestPrimaryDeviceAttributes)
74+ sb.WriteString(ansi.QueryModifyOtherKeys)
7475
7576 // Queries that should only be sent to "smart" normal terminals.
7677 shouldQueryFor := shouldQueryCapabilities(env)
internal/ui/model/landing.go+2−2
@@ -4,7 +4,7 @@ import (
44 "charm.land/lipgloss/v2"
55 "github.com/charmbracelet/crush/internal/agent"
66 "github.com/charmbracelet/crush/internal/ui/common"
7− uv "github.com/charmbracelet/ultraviolet"
7+ "github.com/charmbracelet/ultraviolet/layout"
88)
99
1010// selectedLargeModel returns the currently selected large language model from
@@ -31,7 +31,7 @@ func (m *UI) landingView() string {
3131 parts = append(parts, "", m.modelInfo(width))
3232 infoSection := lipgloss.JoinVertical(lipgloss.Left, parts...)
3333
34− _, remainingHeightArea := uv.SplitVertical(m.layout.main, uv.Fixed(lipgloss.Height(infoSection)+1))
34+ _, remainingHeightArea := layout.SplitVertical(m.layout.main, layout.Fixed(lipgloss.Height(infoSection)+1))
3535
3636 mcpLspSectionWidth := min(30, (width-1)/2)
3737
internal/ui/model/sidebar.go+2−1
@@ -8,6 +8,7 @@ import (
88 "github.com/charmbracelet/crush/internal/ui/common"
99 "github.com/charmbracelet/crush/internal/ui/logo"
1010 uv "github.com/charmbracelet/ultraviolet"
11+ "github.com/charmbracelet/ultraviolet/layout"
1112 "golang.org/x/text/cases"
1213 "golang.org/x/text/language"
1314)
@@ -134,7 +135,7 @@ func (m *UI) drawSidebar(scr uv.Screen, area uv.Rectangle) {
134135 blocks...,
135136 )
136137
137− _, remainingHeightArea := uv.SplitVertical(m.layout.sidebar, uv.Fixed(lipgloss.Height(sidebarHeader)))
138+ _, remainingHeightArea := layout.SplitVertical(m.layout.sidebar, layout.Fixed(lipgloss.Height(sidebarHeader)))
138139 remainingHeight := remainingHeightArea.Dy() - 10
139140 maxFiles, maxLSPs, maxMCPs := getDynamicHeightLimits(remainingHeight)
140141
internal/ui/model/ui.go+40−39
@@ -47,6 +47,7 @@ import (
4747 "github.com/charmbracelet/crush/internal/ui/util"
4848 "github.com/charmbracelet/crush/internal/version"
4949 uv "github.com/charmbracelet/ultraviolet"
50+ "github.com/charmbracelet/ultraviolet/layout"
5051 "github.com/charmbracelet/ultraviolet/screen"
5152 "github.com/charmbracelet/x/editor"
5253)
@@ -135,7 +136,7 @@ type UI struct {
135136 // The width and height of the terminal in cells.
136137 width int
137138 height int
138− layout layout
139+ layout uiLayout
139140
140141 isTransparent bool
141142
@@ -2235,7 +2236,7 @@ func (m *UI) updateSize() {
22352236
22362237// generateLayout calculates the layout rectangles for all UI components based
22372238// on the current UI state and terminal dimensions.
2238−func (m *UI) generateLayout(w, h int) layout {
2239+func (m *UI) generateLayout(w, h int) uiLayout {
22392240 // The screen area we're working with
22402241 area := image.Rect(0, 0, w, h)
22412242
@@ -2256,7 +2257,7 @@ func (m *UI) generateLayout(w, h int) layout {
22562257 }
22572258
22582259 // Add app margins
2259− appRect, helpRect := uv.SplitVertical(area, uv.Fixed(area.Dy()-helpHeight))
2260+ appRect, helpRect := layout.SplitVertical(area, layout.Fixed(area.Dy()-helpHeight))
22602261 appRect.Min.Y += 1
22612262 appRect.Max.Y -= 1
22622263 helpRect.Min.Y -= 1
@@ -2269,7 +2270,7 @@ func (m *UI) generateLayout(w, h int) layout {
22692270 appRect.Max.X -= 1
22702271 }
22712272
2272− layout := layout{
2273+ uiLayout := uiLayout{
22732274 area: area,
22742275 status: helpRect,
22752276 }
@@ -2285,9 +2286,9 @@ func (m *UI) generateLayout(w, h int) layout {
22852286 // ------
22862287 // help
22872288
2288− headerRect, mainRect := uv.SplitVertical(appRect, uv.Fixed(landingHeaderHeight))
2289− layout.header = headerRect
2290− layout.main = mainRect
2289+ headerRect, mainRect := layout.SplitVertical(appRect, layout.Fixed(landingHeaderHeight))
2290+ uiLayout.header = headerRect
2291+ uiLayout.main = mainRect
22912292
22922293 case uiLanding:
22932294 // Layout
@@ -2299,14 +2300,14 @@ func (m *UI) generateLayout(w, h int) layout {
22992300 // editor
23002301 // ------
23012302 // help
2302− headerRect, mainRect := uv.SplitVertical(appRect, uv.Fixed(landingHeaderHeight))
2303− mainRect, editorRect := uv.SplitVertical(mainRect, uv.Fixed(mainRect.Dy()-editorHeight))
2303+ headerRect, mainRect := layout.SplitVertical(appRect, layout.Fixed(landingHeaderHeight))
2304+ mainRect, editorRect := layout.SplitVertical(mainRect, layout.Fixed(mainRect.Dy()-editorHeight))
23042305 // Remove extra padding from editor (but keep it for header and main)
23052306 editorRect.Min.X -= 1
23062307 editorRect.Max.X += 1
2307− layout.header = headerRect
2308− layout.main = mainRect
2309− layout.editor = editorRect
2308+ uiLayout.header = headerRect
2309+ uiLayout.main = mainRect
2310+ uiLayout.editor = editorRect
23102311
23112312 case uiChat:
23122313 if m.isCompact {
@@ -2320,28 +2321,28 @@ func (m *UI) generateLayout(w, h int) layout {
23202321 // ------
23212322 // help
23222323 const compactHeaderHeight = 1
2323− headerRect, mainRect := uv.SplitVertical(appRect, uv.Fixed(compactHeaderHeight))
2324+ headerRect, mainRect := layout.SplitVertical(appRect, layout.Fixed(compactHeaderHeight))
23242325 detailsHeight := min(sessionDetailsMaxHeight, area.Dy()-1) // One row for the header
2325− sessionDetailsArea, _ := uv.SplitVertical(appRect, uv.Fixed(detailsHeight))
2326− layout.sessionDetails = sessionDetailsArea
2327− layout.sessionDetails.Min.Y += compactHeaderHeight // adjust for header
2326+ sessionDetailsArea, _ := layout.SplitVertical(appRect, layout.Fixed(detailsHeight))
2327+ uiLayout.sessionDetails = sessionDetailsArea
2328+ uiLayout.sessionDetails.Min.Y += compactHeaderHeight // adjust for header
23282329 // Add one line gap between header and main content
23292330 mainRect.Min.Y += 1
2330− mainRect, editorRect := uv.SplitVertical(mainRect, uv.Fixed(mainRect.Dy()-editorHeight))
2331+ mainRect, editorRect := layout.SplitVertical(mainRect, layout.Fixed(mainRect.Dy()-editorHeight))
23312332 mainRect.Max.X -= 1 // Add padding right
2332− layout.header = headerRect
2333+ uiLayout.header = headerRect
23332334 pillsHeight := m.pillsAreaHeight()
23342335 if pillsHeight > 0 {
23352336 pillsHeight = min(pillsHeight, mainRect.Dy())
2336− chatRect, pillsRect := uv.SplitVertical(mainRect, uv.Fixed(mainRect.Dy()-pillsHeight))
2337− layout.main = chatRect
2338− layout.pills = pillsRect
2337+ chatRect, pillsRect := layout.SplitVertical(mainRect, layout.Fixed(mainRect.Dy()-pillsHeight))
2338+ uiLayout.main = chatRect
2339+ uiLayout.pills = pillsRect
23392340 } else {
2340− layout.main = mainRect
2341+ uiLayout.main = mainRect
23412342 }
23422343 // Add bottom margin to main
2343− layout.main.Max.Y -= 1
2344− layout.editor = editorRect
2344+ uiLayout.main.Max.Y -= 1
2345+ uiLayout.editor = editorRect
23452346 } else {
23462347 // Layout
23472348 //
@@ -2352,40 +2353,40 @@ func (m *UI) generateLayout(w, h int) layout {
23522353 // ----------
23532354 // help
23542355
2355− mainRect, sideRect := uv.SplitHorizontal(appRect, uv.Fixed(appRect.Dx()-sidebarWidth))
2356+ mainRect, sideRect := layout.SplitHorizontal(appRect, layout.Fixed(appRect.Dx()-sidebarWidth))
23562357 // Add padding left
23572358 sideRect.Min.X += 1
2358− mainRect, editorRect := uv.SplitVertical(mainRect, uv.Fixed(mainRect.Dy()-editorHeight))
2359+ mainRect, editorRect := layout.SplitVertical(mainRect, layout.Fixed(mainRect.Dy()-editorHeight))
23592360 mainRect.Max.X -= 1 // Add padding right
2360− layout.sidebar = sideRect
2361+ uiLayout.sidebar = sideRect
23612362 pillsHeight := m.pillsAreaHeight()
23622363 if pillsHeight > 0 {
23632364 pillsHeight = min(pillsHeight, mainRect.Dy())
2364− chatRect, pillsRect := uv.SplitVertical(mainRect, uv.Fixed(mainRect.Dy()-pillsHeight))
2365− layout.main = chatRect
2366− layout.pills = pillsRect
2365+ chatRect, pillsRect := layout.SplitVertical(mainRect, layout.Fixed(mainRect.Dy()-pillsHeight))
2366+ uiLayout.main = chatRect
2367+ uiLayout.pills = pillsRect
23672368 } else {
2368− layout.main = mainRect
2369+ uiLayout.main = mainRect
23692370 }
23702371 // Add bottom margin to main
2371− layout.main.Max.Y -= 1
2372− layout.editor = editorRect
2372+ uiLayout.main.Max.Y -= 1
2373+ uiLayout.editor = editorRect
23732374 }
23742375 }
23752376
2376− if !layout.editor.Empty() {
2377+ if !uiLayout.editor.Empty() {
23772378 // Add editor margins 1 top and bottom
23782379 if len(m.attachments.List()) == 0 {
2379− layout.editor.Min.Y += 1
2380+ uiLayout.editor.Min.Y += 1
23802381 }
2381− layout.editor.Max.Y -= 1
2382+ uiLayout.editor.Max.Y -= 1
23822383 }
23832384
2384− return layout
2385+ return uiLayout
23852386}
23862387
2387−// layout defines the positioning of UI elements.
2388−type layout struct {
2388+// uiLayout defines the positioning of UI elements.
2389+type uiLayout struct {
23892390 // area is the overall available area.
23902391 area uv.Rectangle
23912392