Change summary
  tui/bubble.go                   |  2 ++
tui/bubbles/selection/bubble.go | 20 ++++++++++++++------
2 files changed, 16 insertions(+), 6 deletions(-)
  Detailed changes
  
  
    
    @@ -140,6 +140,7 @@ func (b *Bubble) viewForBox(i int) string {
 	isActive := i == b.activeBox
 	switch box := b.boxes[i].(type) {
 	case *selection.Bubble:
+		// Menu
 		var s lipgloss.Style
 		s = b.styles.Menu
 		if isActive {
@@ -147,6 +148,7 @@ func (b *Bubble) viewForBox(i int) string {
 		}
 		return s.Render(box.View())
 	case *repo.Bubble:
+		// Repo details
 		box.Active = isActive
 		return box.View()
 	default:
  
  
  
    
    @@ -2,8 +2,11 @@ package selection
 
 import (
 	"soft-serve/tui/style"
+	"strings"
 
 	tea "github.com/charmbracelet/bubbletea"
+	"github.com/charmbracelet/lipgloss"
+	"github.com/muesli/reflow/truncate"
 )
 
 type SelectedMsg struct {
@@ -34,19 +37,24 @@ func (b *Bubble) Init() tea.Cmd {
 }
 
 func (b Bubble) View() string {
-	s := ""
+	s := strings.Builder{}
+	repoNameMaxWidth := b.styles.Menu.GetWidth() - // menu width
+		b.styles.Menu.GetHorizontalPadding() - // menu padding
+		lipgloss.Width(b.styles.MenuCursor.String()) - // cursor
+		b.styles.MenuItem.GetHorizontalFrameSize() // menu item gaps
 	for i, item := range b.Items {
+		item := truncate.StringWithTail(item, uint(repoNameMaxWidth), "…")
 		if i == b.SelectedItem {
-			s += b.styles.MenuCursor.String()
-			s += b.styles.SelectedMenuItem.Render(item)
+			s.WriteString(b.styles.MenuCursor.String())
+			s.WriteString(b.styles.SelectedMenuItem.Render(item))
 		} else {
-			s += b.styles.MenuItem.Render(item)
+			s.WriteString(b.styles.MenuItem.Render(item))
 		}
 		if i < len(b.Items)-1 {
-			s += "\n"
+			s.WriteRune('\n')
 		}
 	}
-	return s
+	return s.String()
 }
 
 func (b *Bubble) Update(msg tea.Msg) (tea.Model, tea.Cmd) {