mirror of
https://github.com/Twigpine/zero.git
synced 2026-11-08 09:49:34 -10:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a1bc1c4af2 |
No files matched your search
@@ -2,6 +2,7 @@ package tui
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -376,3 +377,58 @@ func TestShiftDownComposerGuard(t *testing.T) {
|
||||
t.Fatalf("Shift+Down with non-empty composer scrolled offset to %d, want 3 (unchanged)", got)
|
||||
}
|
||||
}
|
||||
|
||||
// The highlighted permission option must use the selected-row tint, not the
|
||||
// brand chip. zeroTheme.badge is the accent-filled chip for short labels
|
||||
// (" 0 ", " ASK ", " SPEC REVIEW "); using it for a whole row painted a
|
||||
// full-brightness accent slab across a card whose palette is deliberately amber
|
||||
// (warning), and skipped the card tint every other line composes onto. selBg is
|
||||
// the tint tuned for a highlighted row against a panel, and onSel is what every
|
||||
// other selectable list in the TUI uses.
|
||||
func TestFocusedPermissionSelectedRowUsesSelectionTintNotBrandChip(t *testing.T) {
|
||||
request := agent.PermissionRequest{ToolName: "exec_command", SideEffect: "shell"}
|
||||
card, _ := renderFocusedPermissionPrompt(request, 0, 70)
|
||||
|
||||
var selected string
|
||||
for _, line := range strings.Split(card, "\n") {
|
||||
if strings.Contains(ansiPattern.ReplaceAllString(line, ""), "▸ ") {
|
||||
selected = line
|
||||
break
|
||||
}
|
||||
}
|
||||
if selected == "" {
|
||||
t.Fatal("no highlighted option row rendered")
|
||||
}
|
||||
|
||||
accentBg := backgroundCode(darkPalette.accent)
|
||||
selBg := backgroundCode(darkPalette.selBg)
|
||||
if strings.Contains(selected, accentBg) {
|
||||
t.Errorf("selected row is filled with the brand accent %s (zeroTheme.badge); want the selection tint:\n%q", darkPalette.accent, selected)
|
||||
}
|
||||
if !strings.Contains(selected, selBg) {
|
||||
t.Errorf("selected row should carry the selection tint %s:\n%q", darkPalette.selBg, selected)
|
||||
}
|
||||
|
||||
// The PERMISSION chip keeps its amber fill — the card must still read as a
|
||||
// warning surface, so this fix must not flatten it.
|
||||
if !strings.Contains(card, backgroundCode(darkPalette.amber)) {
|
||||
t.Errorf("PERMISSION badge lost its amber fill:\n%q", card)
|
||||
}
|
||||
|
||||
// The card BODY carries no warm permBg wash any more: it matches the other
|
||||
// prompt cards (ask_user, spec) whose bodies are transparent. Warning identity
|
||||
// comes from the amber badge + border, not a full-body tint that clashes on
|
||||
// cool themes.
|
||||
if strings.Contains(card, backgroundCode(darkPalette.permBg)) {
|
||||
t.Errorf("permission card body still tinted with permBg %s; want a transparent body:\n%q", darkPalette.permBg, card)
|
||||
}
|
||||
}
|
||||
|
||||
// backgroundCode renders the SGR truecolor background sequence for a #rrggbb
|
||||
// palette entry, so assertions compare against the palette rather than
|
||||
// hardcoded numbers that drift when a theme is retuned.
|
||||
func backgroundCode(hex string) string {
|
||||
var r, g, b int
|
||||
fmt.Sscanf(hex, "#%02x%02x%02x", &r, &g, &b)
|
||||
return fmt.Sprintf("48;2;%d;%d;%d", r, g, b)
|
||||
}
|
||||
@@ -1112,7 +1112,14 @@ func renderFocusedPermissionPrompt(request agent.PermissionRequest, cursor int,
|
||||
if name == "" {
|
||||
name = "tool"
|
||||
}
|
||||
fill := zeroTheme.onPerm
|
||||
// The card body carries no background fill, matching every other prompt card
|
||||
// (ask_user, spec review, plan) — see the lipgloss.NewStyle() fills below. The
|
||||
// permission card used to tint its whole body with permBg, an amber-family
|
||||
// wash that reads as a warm slab on cool themes (e.g. a brown-yellow box over
|
||||
// dracula's purples) and made it the one outlier. The amber PERMISSION badge
|
||||
// and the amber-mixed border still carry the "this is a permission gate"
|
||||
// signal; the body no longer clashes with the surrounding theme.
|
||||
fill := func(style lipgloss.Style) lipgloss.Style { return style }
|
||||
|
||||
top := zeroTheme.permBadge.Render(" PERMISSION ")
|
||||
|
||||
@@ -1147,8 +1154,16 @@ func renderFocusedPermissionPrompt(request agent.PermissionRequest, cursor int,
|
||||
hotkey := fill(zeroTheme.faint).Render(" [" + option.hotkey + "]")
|
||||
optionLabel := permissionOptionLabel(option, request)
|
||||
if index == cursor {
|
||||
// onSel, not badge. zeroTheme.badge is the brand chip (" 0 ", " ASK ",
|
||||
// " SPEC REVIEW ") — a full-brightness accent fill meant for short
|
||||
// labels. Using it for a selected ROW painted a bright accent slab
|
||||
// across the permission card, fighting the card's amber warning palette
|
||||
// and ignoring the card tint every other line composes onto. selBg is
|
||||
// the tint tuned for exactly this job ("separates from the panel while
|
||||
// ink label contrast stays ~9.4:1"), and onSel is what every other
|
||||
// selectable list in the TUI uses for its highlighted row.
|
||||
marker := fill(zeroTheme.accent).Render("▸ ")
|
||||
label := zeroTheme.badge.Render(" " + optionLabel + " ")
|
||||
label := zeroTheme.onSel(zeroTheme.ink).Bold(true).Render(" " + optionLabel + " ")
|
||||
lines = append(lines, marker+label+hotkey)
|
||||
} else {
|
||||
label := fill(zeroTheme.ink).Render(optionLabel)
|
||||
@@ -1163,7 +1178,7 @@ func renderFocusedPermissionPrompt(request agent.PermissionRequest, cursor int,
|
||||
}
|
||||
lines = append(lines, fill(zeroTheme.faint).Render(footer))
|
||||
|
||||
return styledBlockFill(width, lines, zeroTheme.permBorder, zeroTheme.permBg), offsets
|
||||
return styledBlockFill(width, lines, zeroTheme.permBorder, lipgloss.NewStyle()), offsets
|
||||
}
|
||||
|
||||
func permissionScopeLine(request agent.PermissionRequest, scope string) string {
|
||||
|
||||
Reference in new issue
Block a user