@@ -127,6 +127,7 @@ const (
127127 rowKindNamespace // namespace path segment
128128 rowKindProjectHeader // project label when it has >1 group
129129 rowKindTask // selectable leaf
130+ rowKindErrorLine // non-selectable continuation line showing a task's error
130131)
131132
132133type treeRow struct {
@@ -593,13 +594,48 @@ func (m *actionsModel) updateCollapsed() {
593594}
594595
595596// visibleRows returns the rows that should be shown (honouring collapsed state).
597+ // Failed tasks have their error message injected as one or more rowKindErrorLine
598+ // rows immediately below the task row.
596599func (m * actionsModel ) visibleRows () []treeRow {
600+ leftW := 48
601+ if m .width > 0 && m .width < 80 {
602+ leftW = m .width / 2
603+ }
604+
597605 visible := make ([]treeRow , 0 , len (m .rows ))
598606 for _ , row := range m .rows {
599607 if row .kind != rowKindAction && m .collapsed [row .action ] {
600608 continue
601609 }
602610 visible = append (visible , row )
611+ if row .kind == rowKindTask {
612+ e , ok := m .taskState [row .taskName ]
613+ if ! ok || e .state != actionFailed || e .err == nil {
614+ continue
615+ }
616+ // Indent: same as task row prefix (depth*2 spaces + cursor + icon+space)
617+ // but without cursor/icon — just depth*2 + 4 spaces so text aligns under the label.
618+ prefixLen := row .depth * 2 + 4
619+ availW := leftW - prefixLen
620+ if availW < 10 {
621+ availW = 10
622+ }
623+ runes := []rune (e .err .Error ())
624+ for len (runes ) > 0 {
625+ n := availW
626+ if n > len (runes ) {
627+ n = len (runes )
628+ }
629+ visible = append (visible , treeRow {
630+ kind : rowKindErrorLine ,
631+ label : string (runes [:n ]),
632+ depth : row .depth ,
633+ taskName : row .taskName ,
634+ action : row .action ,
635+ })
636+ runes = runes [n :]
637+ }
638+ }
603639 }
604640 return visible
605641}
@@ -1306,19 +1342,13 @@ func (m *actionsModel) renderTree(width, height int) []string {
13061342 case actionOK :
13071343 extra = actDimStyle .Render (" " + fmtActionDuration (e .elapsed ))
13081344 case actionFailed :
1309- msg := " FAILED"
1310- if e .err != nil {
1311- short := e .err .Error ()
1312- if len ([]rune (short )) > 28 {
1313- short = string ([]rune (short )[:28 ]) + "…"
1314- }
1315- msg += ": " + short
1316- }
1317- extra = actFailStyle .Render (msg )
1345+ // Error text is shown on rowKindErrorLine rows injected by visibleRows.
13181346 }
13191347 }
13201348
13211349 line = indent + cursor + iconSty .Render (icon + " " ) + labelSty .Render (label ) + extra
1350+ case rowKindErrorLine :
1351+ line = strings .Repeat (" " , row .depth ) + " " + actFailStyle .Render (row .label )
13221352 }
13231353 lines = append (lines , truncateANSILine (line , width ))
13241354 }
0 commit comments