tui: add blank interior rows at top and bottom of tool boxes
Body content used to start on the row immediately under the top edge and end on the row immediately above the bottom edge, leaving the box visually cramped against its corners. Insert a blank box-side row (a \u2502 \u2026 \u2502 with no content) after the top edge and before the bottom edge in both the transcript path (renderMessage RoleTool branch) and the live overlay path (renderToolCall, both streaming and finished-with-body). Empty- bodied boxes (finished call with no result) stay compact \u2014 the top and bottom edges sit directly adjacent so a no-output tool doesn't render as a tall hollow frame.
- commit
- 48d22c481505901e8d084313732dfe332dd58eef
- author
- patriceckhart · · 2026-04-27 14:08 UTC
- parent
- 955a9b7
- signature
- unsigned
- refs
- tag: v0.1.29
1 file · +9 -1
M internal/tui/view.go +9 -1
| @@ -561,6 +561,7 @@ func (v *View) renderMessage(m provider.Message, width int, turnOpen bool) []str | |||
| 561 | 561 | // in one assistant message render as N adjacent boxes | |
| 562 | 562 | // instead of stacking unclosed top edges. | |
| 563 | 563 | lines = append(lines, toolBoxTop(v.Theme, label, width)) | |
| 564 | + | lines = append(lines, toolBoxSide(v.Theme, "", width)) | |
| 564 | 565 | if tr.IsError { | |
| 565 | 566 | lines = append(lines, toolBoxSide(v.Theme, v.Theme.FG256(color, " error"), width)) | |
| 566 | 567 | } | |
| @@ -576,6 +577,7 @@ func (v *View) renderMessage(m provider.Message, width int, turnOpen bool) []str | |||
| 576 | 577 | } | |
| 577 | 578 | lines = append(lines, toolBoxSide(v.Theme, body, width)) | |
| 578 | 579 | } | |
| 580 | + | lines = append(lines, toolBoxSide(v.Theme, "", width)) | |
| 579 | 581 | lines = append(lines, toolBoxBottom(v.Theme, width)) | |
| 580 | 582 | } | |
| 581 | 583 | } | |
| @@ -608,9 +610,11 @@ func (v *View) renderToolCall(tc ToolCallView, width int) []string { | |||
| 608 | 610 | if tc.Streaming && tc.Result == "" { | |
| 609 | 611 | lines = append(lines, "") | |
| 610 | 612 | lines = append(lines, toolBoxTop(v.Theme, label, width)) | |
| 613 | + | lines = append(lines, toolBoxSide(v.Theme, "", width)) | |
| 611 | 614 | if body := v.renderLiveToolBody(tc, width); len(body) > 0 { | |
| 612 | 615 | lines = append(lines, body...) | |
| 613 | 616 | } | |
| 617 | + | lines = append(lines, toolBoxSide(v.Theme, "", width)) | |
| 614 | 618 | lines = append(lines, toolBoxBottom(v.Theme, width)) | |
| 615 | 619 | return lines | |
| 616 | 620 | } | |
| @@ -627,9 +631,12 @@ func (v *View) renderToolCall(tc ToolCallView, width int) []string { | |||
| 627 | 631 | ||
| 628 | 632 | // Finished tool call with a result body. Top edge embeds the | |
| 629 | 633 | // label; body lines go through toolBoxSide so each row gets | |
| 630 | - | // vertical edges; bottom edge closes the box. | |
| 634 | + | // vertical edges; bottom edge closes the box. Blank interior | |
| 635 | + | // rows after the top and before the bottom give the body a bit | |
| 636 | + | // of breathing room from the corners. | |
| 631 | 637 | lines = append(lines, "") | |
| 632 | 638 | lines = append(lines, toolBoxTop(v.Theme, label, width)) | |
| 639 | + | lines = append(lines, toolBoxSide(v.Theme, "", width)) | |
| 633 | 640 | color := v.Theme.ToolOut | |
| 634 | 641 | if tc.Error { | |
| 635 | 642 | color = v.Theme.Error | |
| @@ -642,6 +649,7 @@ func (v *View) renderToolCall(tc ToolCallView, width int) []string { | |||
| 642 | 649 | } | |
| 643 | 650 | lines = append(lines, toolBoxSide(v.Theme, l, width)) | |
| 644 | 651 | } | |
| 652 | + | lines = append(lines, toolBoxSide(v.Theme, "", width)) | |
| 645 | 653 | lines = append(lines, toolBoxBottom(v.Theme, width)) | |
| 646 | 654 | return lines | |
| 647 | 655 | } | |
| @@ -561,6 +561,7 @@ func (v *View) renderMessage(m provider.Message, width int, turnOpen bool) []str | |||||
| 561 | // in one assistant message render as N adjacent boxes | 561 | // in one assistant message render as N adjacent boxes | ||
| 562 | // instead of stacking unclosed top edges. | 562 | // instead of stacking unclosed top edges. | ||
| 563 | lines = append(lines, toolBoxTop(v.Theme, label, width)) | 563 | lines = append(lines, toolBoxTop(v.Theme, label, width)) | ||
| 564 | + | lines = append(lines, toolBoxSide(v.Theme, "", width)) | |||
| 564 | if tr.IsError { | 565 | if tr.IsError { | ||
| 565 | lines = append(lines, toolBoxSide(v.Theme, v.Theme.FG256(color, " error"), width)) | 566 | lines = append(lines, toolBoxSide(v.Theme, v.Theme.FG256(color, " error"), width)) | ||
| 566 | } | 567 | } | ||
| @@ -576,6 +577,7 @@ func (v *View) renderMessage(m provider.Message, width int, turnOpen bool) []str | |||||
| 576 | } | 577 | } | ||
| 577 | lines = append(lines, toolBoxSide(v.Theme, body, width)) | 578 | lines = append(lines, toolBoxSide(v.Theme, body, width)) | ||
| 578 | } | 579 | } | ||
| 580 | + | lines = append(lines, toolBoxSide(v.Theme, "", width)) | |||
| 579 | lines = append(lines, toolBoxBottom(v.Theme, width)) | 581 | lines = append(lines, toolBoxBottom(v.Theme, width)) | ||
| 580 | } | 582 | } | ||
| 581 | } | 583 | } | ||
| @@ -608,9 +610,11 @@ func (v *View) renderToolCall(tc ToolCallView, width int) []string { | |||||
| 608 | if tc.Streaming && tc.Result == "" { | 610 | if tc.Streaming && tc.Result == "" { | ||
| 609 | lines = append(lines, "") | 611 | lines = append(lines, "") | ||
| 610 | lines = append(lines, toolBoxTop(v.Theme, label, width)) | 612 | lines = append(lines, toolBoxTop(v.Theme, label, width)) | ||
| 613 | + | lines = append(lines, toolBoxSide(v.Theme, "", width)) | |||
| 611 | if body := v.renderLiveToolBody(tc, width); len(body) > 0 { | 614 | if body := v.renderLiveToolBody(tc, width); len(body) > 0 { | ||
| 612 | lines = append(lines, body...) | 615 | lines = append(lines, body...) | ||
| 613 | } | 616 | } | ||
| 617 | + | lines = append(lines, toolBoxSide(v.Theme, "", width)) | |||
| 614 | lines = append(lines, toolBoxBottom(v.Theme, width)) | 618 | lines = append(lines, toolBoxBottom(v.Theme, width)) | ||
| 615 | return lines | 619 | return lines | ||
| 616 | } | 620 | } | ||
| @@ -627,9 +631,12 @@ func (v *View) renderToolCall(tc ToolCallView, width int) []string { | |||||
| 627 | 631 | ||||
| 628 | // Finished tool call with a result body. Top edge embeds the | 632 | // Finished tool call with a result body. Top edge embeds the | ||
| 629 | // label; body lines go through toolBoxSide so each row gets | 633 | // label; body lines go through toolBoxSide so each row gets | ||
| 630 | - | // vertical edges; bottom edge closes the box. | 634 | + | // vertical edges; bottom edge closes the box. Blank interior |
| 635 | + | // rows after the top and before the bottom give the body a bit | |||
| 636 | + | // of breathing room from the corners. | |||
| 631 | lines = append(lines, "") | 637 | lines = append(lines, "") | ||
| 632 | lines = append(lines, toolBoxTop(v.Theme, label, width)) | 638 | lines = append(lines, toolBoxTop(v.Theme, label, width)) | ||
| 639 | + | lines = append(lines, toolBoxSide(v.Theme, "", width)) | |||
| 633 | color := v.Theme.ToolOut | 640 | color := v.Theme.ToolOut | ||
| 634 | if tc.Error { | 641 | if tc.Error { | ||
| 635 | color = v.Theme.Error | 642 | color = v.Theme.Error | ||
| @@ -642,6 +649,7 @@ func (v *View) renderToolCall(tc ToolCallView, width int) []string { | |||||
| 642 | } | 649 | } | ||
| 643 | lines = append(lines, toolBoxSide(v.Theme, l, width)) | 650 | lines = append(lines, toolBoxSide(v.Theme, l, width)) | ||
| 644 | } | 651 | } | ||
| 652 | + | lines = append(lines, toolBoxSide(v.Theme, "", width)) | |||
| 645 | lines = append(lines, toolBoxBottom(v.Theme, width)) | 653 | lines = append(lines, toolBoxBottom(v.Theme, width)) | ||
| 646 | return lines | 654 | return lines | ||
| 647 | } | 655 | } | ||