fix(tui): omit metadata below indent width
- commit
- 9f470d309c420d890fdb7995a840459ba5f47e06
- author
- brice · · 2026-08-20 13:25 UTC
- parent
- 778aec9
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
2 files · +30 -4
M packages/agent/modes/resident_subagent_indicator.go +0 -4
| @@ -85,10 +85,6 @@ func renderResidentSubagentActivityGroup(theme tui.Theme, color tui.TerminalColo | |||
| 85 | 85 | } | |
| 86 | 86 | metadataWidthLimit := width - runewidth.StringWidth(metadataIndent) | |
| 87 | 87 | if metadataWidthLimit <= 0 { | |
| 88 | - | metadata = truncateResidentSubagentIndicator(metadata, width) | |
| 89 | - | if metadata != "" { | |
| 90 | - | lines = append(lines, theme.FGColor(theme.Muted, metadata)) | |
| 91 | - | } | |
| 92 | 88 | return lines | |
| 93 | 89 | } | |
| 94 | 90 | for _, metadataLine := range tui.WrapANSILine(metadata, metadataWidthLimit) { | |
| @@ -85,10 +85,6 @@ func renderResidentSubagentActivityGroup(theme tui.Theme, color tui.TerminalColo | |||||
| 85 | } | 85 | } | ||
| 86 | metadataWidthLimit := width - runewidth.StringWidth(metadataIndent) | 86 | metadataWidthLimit := width - runewidth.StringWidth(metadataIndent) | ||
| 87 | if metadataWidthLimit <= 0 { | 87 | if metadataWidthLimit <= 0 { | ||
| 88 | - | metadata = truncateResidentSubagentIndicator(metadata, width) | |||
| 89 | - | if metadata != "" { | |||
| 90 | - | lines = append(lines, theme.FGColor(theme.Muted, metadata)) | |||
| 91 | - | } | |||
| 92 | return lines | 88 | return lines | ||
| 93 | } | 89 | } | ||
| 94 | for _, metadataLine := range tui.WrapANSILine(metadata, metadataWidthLimit) { | 90 | for _, metadataLine := range tui.WrapANSILine(metadata, metadataWidthLimit) { | ||
M packages/agent/modes/resident_subagent_indicator_test.go +30 -0
| @@ -252,6 +252,36 @@ func TestFitResidentSubagentActivityLinesKeepsActivityWhenWrappedMetadataDoesNot | |||
| 252 | 252 | } | |
| 253 | 253 | } | |
| 254 | 254 | ||
| 255 | + | func TestRenderResidentSubagentActivityLinesOmitsMetadataWhenIndentDoesNotFit(t *testing.T) { | |
| 256 | + | now := time.Date(2026, time.August, 13, 12, 0, 0, 0, time.UTC) | |
| 257 | + | snapshot := subagents.ResidentSnapshot{ | |
| 258 | + | ID: "running-id", Profile: "reviewer", State: subagents.ResidentRunning, | |
| 259 | + | Usage: provider.Usage{InputTokens: 84_000, OutputTokens: 1_500, CacheReadTokens: 123_000, CacheMeasuredPromptTokens: 207_000, CacheMeasuredReadTokens: 123_000, CostUSD: 0.525}, | |
| 260 | + | ContextUsed: 45_152, ContextMax: 272_000, Subscription: true, | |
| 261 | + | } | |
| 262 | + | for _, width := range []int{3, 4} { | |
| 263 | + | t.Run(fmt.Sprintf("width_%d", width), func(t *testing.T) { | |
| 264 | + | lines := renderResidentSubagentActivityLines(tui.Dark, "/", []subagents.ResidentSnapshot{snapshot}, width, now) | |
| 265 | + | plain := plainResidentIndicatorLines(lines) | |
| 266 | + | wantActivity := " " + strings.Repeat(".", width-runewidth.StringWidth(" ")) | |
| 267 | + | if len(plain) != 1 || plain[0] != wantActivity { | |
| 268 | + | t.Fatalf("activity lines = %#v, want only activity row %#v", plain, []string{wantActivity}) | |
| 269 | + | } | |
| 270 | + | if strings.Contains(strings.Join(plain, "\n"), "↑84k") { | |
| 271 | + | t.Fatalf("activity lines include metadata despite unavailable indent: %#v", plain) | |
| 272 | + | } | |
| 273 | + | if gotWidth := runewidth.StringWidth(plain[0]); gotWidth > width { | |
| 274 | + | t.Fatalf("activity line width = %d, want <= %d: %q", gotWidth, width, plain[0]) | |
| 275 | + | } | |
| 276 | + | ||
| 277 | + | limited := plainResidentIndicatorLines(limitResidentSubagentActivityLines(tui.Dark, lines, 0, 1, width)) | |
| 278 | + | if len(limited) != 1 || limited[0] != plain[0] || strings.Contains(limited[0], "more active") { | |
| 279 | + | t.Fatalf("limited activity lines = %#v, want preserved activity row %#v without overflow", limited, plain) | |
| 280 | + | } | |
| 281 | + | }) | |
| 282 | + | } | |
| 283 | + | } | |
| 284 | + | ||
| 255 | 285 | func TestRenderResidentSubagentActivityLinesAnimatesModelWait(t *testing.T) { | |
| 256 | 286 | started := time.Date(2026, time.August, 13, 12, 0, 0, 0, time.UTC) | |
| 257 | 287 | now := started.Add(2 * time.Second) | |
| @@ -252,6 +252,36 @@ func TestFitResidentSubagentActivityLinesKeepsActivityWhenWrappedMetadataDoesNot | |||||
| 252 | } | 252 | } | ||
| 253 | } | 253 | } | ||
| 254 | 254 | ||||
| 255 | + | func TestRenderResidentSubagentActivityLinesOmitsMetadataWhenIndentDoesNotFit(t *testing.T) { | |||
| 256 | + | now := time.Date(2026, time.August, 13, 12, 0, 0, 0, time.UTC) | |||
| 257 | + | snapshot := subagents.ResidentSnapshot{ | |||
| 258 | + | ID: "running-id", Profile: "reviewer", State: subagents.ResidentRunning, | |||
| 259 | + | Usage: provider.Usage{InputTokens: 84_000, OutputTokens: 1_500, CacheReadTokens: 123_000, CacheMeasuredPromptTokens: 207_000, CacheMeasuredReadTokens: 123_000, CostUSD: 0.525}, | |||
| 260 | + | ContextUsed: 45_152, ContextMax: 272_000, Subscription: true, | |||
| 261 | + | } | |||
| 262 | + | for _, width := range []int{3, 4} { | |||
| 263 | + | t.Run(fmt.Sprintf("width_%d", width), func(t *testing.T) { | |||
| 264 | + | lines := renderResidentSubagentActivityLines(tui.Dark, "/", []subagents.ResidentSnapshot{snapshot}, width, now) | |||
| 265 | + | plain := plainResidentIndicatorLines(lines) | |||
| 266 | + | wantActivity := " " + strings.Repeat(".", width-runewidth.StringWidth(" ")) | |||
| 267 | + | if len(plain) != 1 || plain[0] != wantActivity { | |||
| 268 | + | t.Fatalf("activity lines = %#v, want only activity row %#v", plain, []string{wantActivity}) | |||
| 269 | + | } | |||
| 270 | + | if strings.Contains(strings.Join(plain, "\n"), "↑84k") { | |||
| 271 | + | t.Fatalf("activity lines include metadata despite unavailable indent: %#v", plain) | |||
| 272 | + | } | |||
| 273 | + | if gotWidth := runewidth.StringWidth(plain[0]); gotWidth > width { | |||
| 274 | + | t.Fatalf("activity line width = %d, want <= %d: %q", gotWidth, width, plain[0]) | |||
| 275 | + | } | |||
| 276 | + | ||||
| 277 | + | limited := plainResidentIndicatorLines(limitResidentSubagentActivityLines(tui.Dark, lines, 0, 1, width)) | |||
| 278 | + | if len(limited) != 1 || limited[0] != plain[0] || strings.Contains(limited[0], "more active") { | |||
| 279 | + | t.Fatalf("limited activity lines = %#v, want preserved activity row %#v without overflow", limited, plain) | |||
| 280 | + | } | |||
| 281 | + | }) | |||
| 282 | + | } | |||
| 283 | + | } | |||
| 284 | + | ||||
| 255 | func TestRenderResidentSubagentActivityLinesAnimatesModelWait(t *testing.T) { | 285 | func TestRenderResidentSubagentActivityLinesAnimatesModelWait(t *testing.T) { | ||
| 256 | started := time.Date(2026, time.August, 13, 12, 0, 0, 0, time.UTC) | 286 | started := time.Date(2026, time.August, 13, 12, 0, 0, 0, time.UTC) | ||
| 257 | now := started.Add(2 * time.Second) | 287 | now := started.Add(2 * time.Second) | ||