feat(tui): surface plane-2 rationale in the approval band
The plane-2 tool-call assessor records verified preconditions
("[PATH_OUTSIDE_WORKSPACE] …") and the server already ships them in
RiskSummaryDto.rationale, but the Go TUI's RiskSummaryDto had no
Rationale field — so the justification was silently dropped at decode
and the gate showed only an opaque tier.
Decode the rationale, carry it on Approval, and render it under the
header in the approval band (warn-marked, above the diff). This closes
the last deferred item of the plane-2 slice-1 plan: the assessment
surfaced to the approval UX. Golden test pins the rationale decode.
This commit is contained in:
@@ -56,11 +56,14 @@ func mbg(t Theme, s string, fg lipgloss.Color) string {
|
||||
// never crowds out the session above (longer diffs spill to the ^x fullscreen
|
||||
// view). Layout: 2 borders + header + blank + diff rows + blank + action row.
|
||||
func (m Model) approvalBandHeight() int {
|
||||
rows := 0
|
||||
rows, rat := 0, 0
|
||||
if s := m.session(m.selectedID); s != nil && s.Pending != nil {
|
||||
rows = len(parseUnifiedDiff(s.Pending.Preview))
|
||||
if n := len(s.Pending.Rationale); n > 0 {
|
||||
rat = n + 1 // rationale lines + trailing blank
|
||||
}
|
||||
}
|
||||
h := 2 + 1 + 1 + rows + 1 + 1
|
||||
h := 2 + 1 + 1 + rat + rows + 1 + 1
|
||||
if maxH := m.height * 55 / 100; h > maxH {
|
||||
h = maxH
|
||||
}
|
||||
@@ -103,7 +106,11 @@ func (m Model) renderApprovalBand(h int) string {
|
||||
lipgloss.NewStyle().Foreground(riskColor).Background(t.P.Bg).Bold(true).Render(strings.ToUpper(a.Risk))
|
||||
|
||||
innerH := h - 2
|
||||
diffH := innerH - 4 // header, blank, blank, action row
|
||||
ratBlock := 0
|
||||
if len(a.Rationale) > 0 {
|
||||
ratBlock = len(a.Rationale) + 1 // rationale lines + trailing blank
|
||||
}
|
||||
diffH := innerH - 4 - ratBlock // header, blank, blank, action row, + rationale block
|
||||
if diffH < 1 {
|
||||
diffH = 1
|
||||
}
|
||||
@@ -111,8 +118,16 @@ func (m Model) renderApprovalBand(h int) string {
|
||||
|
||||
body := make([]string, 0, innerH)
|
||||
body = append(body, m.justify(leftHdr, rightHdr, textW, t.P.Bg), "")
|
||||
for _, r := range a.Rationale {
|
||||
marker := lipgloss.NewStyle().Foreground(t.P.Warn).Background(t.P.Bg).Render("▲ ")
|
||||
body = append(body, marker+t.span(truncate(r, textW-2), t.P.Dim))
|
||||
}
|
||||
if len(a.Rationale) > 0 {
|
||||
body = append(body, "")
|
||||
}
|
||||
diffStart := len(body)
|
||||
body = append(body, m.renderSplitDiff(rows, textW, diffH, 0)...)
|
||||
for len(body) < 2+diffH {
|
||||
for len(body) < diffStart+diffH {
|
||||
body = append(body, "")
|
||||
}
|
||||
body = append(body, "", m.approvalActions())
|
||||
|
||||
Reference in New Issue
Block a user