on main help sign in
fix: render pills box reliably when todos or queue appear mid-session

The pills panel only drew when layout.pills had vertical space, but that space was reserved by updateLayoutAndSize which ran only on explicit triggers (toggle, resize, in-progress flip). When the model created new todos while the panel was collapsed, the layout never recomputed and the box stayed invisible until ctrl+t forced it. Re-render pills on every Draw pass so the box appears as soon as content exists, regardless of whether the layout footprint changed.

commit1350167227756c67ea429c5191a05f6b23fd35b8 authorKieran Klukas <kieran@dunkirk.sh> dateMon 22 Jun 2026, 18:02 (4 months ago) parentde67920
1 file changed+19
internal/ui/model/ui.go+19
internal/ui/model/ui.go+19
@@ -714,11 +714,23 @@ func (m *UI) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
714714 }
715715 if m.session != nil && msg.Payload.ID == m.session.ID {
716716 prevHasInProgress := hasInProgressTodo(m.session.Todos)
717+ prevPillsHeight := m.pillsAreaHeight()
717718 m.session = &msg.Payload
718719 if !prevHasInProgress && hasInProgressTodo(m.session.Todos) {
719720 m.todoIsSpinning = true
720721 cmds = append(cmds, m.todoSpinner.Tick)
722+ }
723+ // The pills panel reserves vertical space that the chat area
724+ // must yield. Recompute the layout whenever that footprint
725+ // changes (todos appearing, the list growing, etc.) so the
726+ // box renders on first paint rather than waiting for a toggle.
727+ // When the footprint is unchanged we still re-render the pill
728+ // content so status changes (e.g. the in-progress spinner)
729+ // show up.
730+ if m.pillsAreaHeight() != prevPillsHeight {
721731 m.updateLayoutAndSize()
732+ } else {
733+ m.renderPills()
722734 }
723735 m.autoExpandPillsIfReasonable()
724736 }
@@ -2377,6 +2389,13 @@ func (m *UI) Draw(scr uv.Screen, area uv.Rectangle) *tea.Cursor {
23772389 if m.layout != layout {
23782390 m.layout = layout
23792391 m.updateSize()
2392+ } else if m.state == uiChat && m.hasSession() {
2393+ // Re-render pills on every draw so the box appears even when
2394+ // the layout footprint hasn't changed (e.g. todos arrived
2395+ // while the panel was collapsed). updateSize already calls
2396+ // renderPills, but only when the layout actually differs;
2397+ // this catches the steady-state case.
2398+ m.renderPills()
23802399 }
23812400
23822401 // Clear the screen first