Skip to content

fix(ui): pad viewport rows to prevent iTerm2 ghost lines on scroll#1240

Open
Juoper wants to merge 1 commit into
asheshgoplani:mainfrom
Juoper:fix/iterm-incremental-redraw-ghost-lines
Open

fix(ui): pad viewport rows to prevent iTerm2 ghost lines on scroll#1240
Juoper wants to merge 1 commit into
asheshgoplani:mainfrom
Juoper:fix/iterm-incremental-redraw-ghost-lines

Conversation

@Juoper
Copy link
Copy Markdown
Contributor

@Juoper Juoper commented Jun 1, 2026

Pad each frame line to full terminal cell width so incremental redraw overwrites stale glyphs when scrolling the session list, without using tea.ClearScreen.

Summary by CodeRabbit

  • Bug Fixes

    • Fixed rendering artifacts that could appear when line lengths change during viewport updates
    • Improved cell width alignment handling for consistent terminal display rendering
  • Tests

    • Added regression test to verify viewport padding behavior

Pad each frame line to full terminal cell width so incremental redraw
overwrites stale glyphs when scrolling the session list, without using
tea.ClearScreen.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 1, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds terminal cell-width adjustment helpers and applies them throughout viewport clamping logic to ensure consistent line widths for emoji and keycap rendering. The changes prevent glyph leftovers during incremental redraws by enforcing exact cell-width padding and truncation.

Changes

Cell-width consistency in viewport rendering

Layer / File(s) Summary
Terminal cell-width adjustment helpers
internal/ui/cellwidth.go
New fitCellWidth function measures a string's terminal cell width and truncates or right-pads it to exact target width; fitLinesToWidth applies the same logic line-by-line for multi-line content.
Viewport clamping refactoring
internal/ui/home.go
clampViewToViewport applies fitCellWidth to each rendered line to eliminate glyph leftovers; ensureExactWidth delegates to fitLinesToWidth and documentation updated to emphasize cell-width consistency over lipgloss measurement.
Regression test for row padding
internal/ui/issue937_keycap_test.go
New test Test_clampViewToViewport_PadsEveryRow verifies that every output row is padded to the requested width, including short and empty lines, by checking cell width values.

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 6 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Remote_parity ⚠️ Warning Test_clampViewToViewport_PadsEveryRow added in issue937_keycap_test.go tests padding behavior but lacks RemoteSession coverage and has no t.Skip explaining why per TUI guidelines. Add a RemoteSession test variant to Test_clampViewToViewport_PadsEveryRow (e.g., with home.flatItems containing RemoteSession items) or add explicit t.Skip with justification.
✅ Passed checks (6 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title follows Conventional Commits format with 'fix:' prefix and clearly describes the main change: padding viewport rows to prevent iTerm2 ghost lines during scrolling.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 70.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Test_coverage_per_surface ✅ Passed PR modifies only TUI surface (internal/ui/*) with test coverage. No Web, CLI, or remote surfaces are affected. TUI has regression test for padding logic.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@internal/ui/cellwidth.go`:
- Around line 30-58: Tests currently don't exercise the clampViewToViewport →
fitCellWidth path for RemoteSession rendering; add a test that sets up
Home.remoteSessions with one or more RemoteSession rows, calls Home.View(), and
asserts the output lines produced by fitCellWidth/fitLinesToWidth are correctly
padded or truncated to the expected cell width (use cellWidth expectations for
multibyte/emoji cases), or if coverage cannot be added, add a t.Skipf in the
existing RemoteSession-related tests explaining why RemoteSession frames can't
be validated here; refer to Home.View(), Home.remoteSessions,
clampViewToViewport, fitCellWidth and fitLinesToWidth when locating code to
modify.

In `@internal/ui/issue937_keycap_test.go`:
- Around line 280-296: This test (Test_clampViewToViewport_PadsEveryRow)
exercises clampViewToViewport but doesn't cover the RemoteSession path; either
add a parallel subtest that runs under a RemoteSession context (e.g., initialize
or mock RemoteSession and call clampViewToViewport the same way) to assert
identical padding behavior, or add an explicit t.Skip with a short justification
at the top of Test_clampViewToViewport_PadsEveryRow explaining why RemoteSession
isn't applicable; ensure you reference the RemoteSession initializer/mocker used
elsewhere in internal/ui tests, keep assertions identical (cellWidth check), and
name the subtest to indicate RemoteSession coverage.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 17702318-a442-4957-a8b6-cd7d85dae62e

📥 Commits

Reviewing files that changed from the base of the PR and between 23887fc and a1a7e05.

📒 Files selected for processing (3)
  • internal/ui/cellwidth.go
  • internal/ui/home.go
  • internal/ui/issue937_keycap_test.go

Comment thread internal/ui/cellwidth.go
Comment on lines +30 to +58
// fitCellWidth returns s truncated or space-padded so it occupies exactly width
// terminal cells. Used by clampViewToViewport so each frame overwrites the full
// row and incremental redraw does not leave ghost characters (issue #607) —
// avoids tea.ClearScreen / flicker on iTerm2.
func fitCellWidth(s string, width int) string {
if width <= 0 {
return ""
}
w := cellWidth(s)
if w > width {
return cellTruncate(s, width, "")
}
if w < width {
return s + strings.Repeat(" ", width-w)
}
return s
}

// fitLinesToWidth applies fitCellWidth to each line of a multi-line string.
func fitLinesToWidth(content string, width int) string {
if width <= 0 || content == "" {
return content
}
lines := strings.Split(content, "\n")
for i := range lines {
lines[i] = fitCellWidth(lines[i], width)
}
return strings.Join(lines, "\n")
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== PR files touching internal/ui or cmd/agent-deck =="
git diff --name-only origin/main...HEAD | rg -n '^(internal/ui|cmd/agent-deck)/.*\.go$' || true

echo
echo "== Candidate tests mentioning clamp/viewport/width helpers =="
rg -n --type go -C2 'fitCellWidth|fitLinesToWidth|clampViewToViewport|ensureExactWidth' internal/ui cmd/agent-deck || true

echo
echo "== RemoteSession coverage in tests =="
rg -n --type go -C2 'RemoteSession' internal/ui cmd/agent-deck || true

echo
echo "== Explicit t.Skip rationale mentions (RemoteSession / why) =="
rg -n --type go -C2 't\.Skip\(|Skipf\(' internal/ui cmd/agent-deck || true

Repository: asheshgoplani/agent-deck

Length of output: 50439


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== clampViewToViewport / ensureExactWidth / fitCellWidth usage in tests (w/ file+line) =="
rg -n --type go 'clampViewToViewport\(|ensureExactWidth\(|fitCellWidth\(|fitLinesToWidth\(' internal/ui cmd/agent-deck -g'*_test.go' || true

echo
echo "== Tests that mention RemoteSession AND clamp/width helpers =="
rg -n --type go 'RemoteSession.*(clampViewToViewport|ensureExactWidth|fitCellWidth|fitLinesToWidth)|\(clampViewToViewport|ensureExactWidth|fitCellWidth|fitLinesToWidth\).*RemoteSession' internal/ui -g'*_test.go' || true

echo
echo "== RemoteSession mentioned in tests that render Home.View/frames =="
rg -n --type go 'RemoteSession' internal/ui -g'*_test.go' | head -n 200
echo
rg -n --type go 'home\.View\(|View\(\)' internal/ui -g'*_test.go' || true
echo
rg -n --type go 'RemoteSession.*home\.View|home\.View.*RemoteSession' internal/ui -g'*_test.go' || true

echo
echo "== t.Skip / Skipf occurrences in internal/ui and cmd/agent-deck =="
rg -n --type go 't\.Skip\(|Skipf\(' internal/ui cmd/agent-deck -g'*_test.go' || true

Repository: asheshgoplani/agent-deck

Length of output: 29080


🏁 Script executed:

#!/bin/bash
set -euo pipefail

files=(
  internal/ui/issue953_counter_test.go
  internal/ui/issue1101_remote_preview_test.go
  internal/ui/issue1091_remote_render_test.go
  internal/ui/issue1112_remote_waiting_status_test.go
  internal/ui/issue1100_shift_enter_remote_test.go
)

for f in "${files[@]}"; do
  echo "================ $f ================"
  nl -ba "$f" | sed -n '1,220p'
  echo
done

echo "== Search within these files for width/clamp helpers =="
for f in "${files[@]}"; do
  echo "-- $f"
  rg -n --type go 'clampViewToViewport|ensureExactWidth|fitCellWidth|fitLinesToWidth' "$f" || true
done

Repository: asheshgoplani/agent-deck

Length of output: 201


🏁 Script executed:

#!/bin/bash
set -euo pipefail

files=(
  internal/ui/issue953_counter_test.go
  internal/ui/issue1101_remote_preview_test.go
  internal/ui/issue1091_remote_render_test.go
  internal/ui/issue1112_remote_waiting_status_test.go
  internal/ui/issue1100_shift_enter_remote_test.go
)

for f in "${files[@]}"; do
  echo "================ $f (first 220 lines) ================"
  stat "$f" | cat
  cat -n "$f" | head -n 220
  echo
done

echo "== Search within these files for width/clamp helpers =="
for f in "${files[@]}"; do
  echo "-- $f"
  rg -n --type go 'clampViewToViewport|ensureExactWidth|fitCellWidth|fitLinesToWidth' "$f" || true
  echo
done

Repository: asheshgoplani/agent-deck

Length of output: 221


🏁 Script executed:

#!/bin/bash
set -euo pipefail

files=(
  internal/ui/issue953_counter_test.go
  internal/ui/issue1101_remote_preview_test.go
  internal/ui/issue1091_remote_render_test.go
  internal/ui/issue1112_remote_waiting_status_test.go
  internal/ui/issue1100_shift_enter_remote_test.go
)

for f in "${files[@]}"; do
  echo "================ $f ================"
  echo "-- RemoteSession / remoteSessions occurrences --"
  rg -n --type go 'RemoteSession|remoteSessions' "$f" || true
  echo "-- Width/clamp helper occurrences --"
  rg -n --type go 'clampViewToViewport|ensureExactWidth|fitCellWidth|fitLinesToWidth' "$f" || true
  echo "-- Home.View() occurrences --"
  rg -n --type go 'home\.View\(' "$f" || true
  echo "-- Any View() call occurrences --"
  rg -n --type go '\bView\(\)' "$f" || true
  echo
done

Repository: asheshgoplani/agent-deck

Length of output: 3966


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== issue953_counter_test.go relevant section =="
sed -n '1,210p' internal/ui/issue953_counter_test.go

echo
echo "== Home.View() implementation snippet (should call clampViewToViewport) =="
rg -n --type go 'func \(.*\) View\(' internal/ui/home.go | head -n 20
# Print around the clampViewToViewport call site we saw earlier.
rg -n --type go 'return clampViewToViewport\(' internal/ui/home.go
# Show a small window around the clampViewToViewport return.
clamp_line=$(rg -n --type go 'return clampViewToViewport\(' internal/ui/home.go | head -n 1 | cut -d: -f1)
start=$((clamp_line-20))
end=$((clamp_line+20))
sed -n "${start},${end}p" internal/ui/home.go

Repository: asheshgoplani/agent-deck

Length of output: 8136


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Files that mention RemoteSession / RemoteSessionInfo
rg -l --type go 'RemoteSession' internal/ui cmd/agent-deck -g'*_test.go' > /tmp/remote_files.txt || true

# Files that call home.View()
rg -l --type go 'home\.View\(' internal/ui -g'*_test.go' > /tmp/home_view_files.txt || true

echo "== RemoteSession files =="
wc -l /tmp/remote_files.txt; head -n 50 /tmp/remote_files.txt || true
echo "== home.View() files =="
wc -l /tmp/home_view_files.txt; head -n 50 /tmp/home_view_files.txt || true

# Intersection
comm -12 <(sort -u /tmp/remote_files.txt) <(sort -u /tmp/home_view_files.txt) | sed -n '1,200p'
echo "== Files with RemoteSession AND home.View() (count) =="
comm -12 <(sort -u /tmp/remote_files.txt) <(sort -u /tmp/home_view_files.txt) | wc -l

# Also check for any direct View() calls on a Home instance with RemoteSession in the same file.
echo "== Files with RemoteSession AND Home.View() anywhere (home.View or .View() on Home var) =="
rg -l --type go '(RemoteSession.*|.*RemoteSession)\s*\n.*\.View\(' internal/ui -g'*_test.go' || true

Repository: asheshgoplani/agent-deck

Length of output: 827


🏁 Script executed:

#!/bin/bash
set -euo pipefail

remote_files=/tmp/remote_files.txt
home_view_files=/tmp/home_view_files.txt

# Files that mention RemoteSession
rg -l --type go 'RemoteSession' internal/ui cmd/agent-deck -g'*_test.go' > "$remote_files" || true
# Files that call home.View()
rg -l --type go 'home\.View\(' internal/ui -g'*_test.go' > "$home_view_files" || true

echo "== Intersection (RemoteSession files ∩ home.View() files) =="
# grep -Fxf expects one file list in pattern; use grep with -x for exact lines.
grep -Fxf "$remote_files" "$home_view_files" || true

echo
echo "== Quick check: in those intersection files, any t.Skip rationale mentioning RemoteSession? =="
intersection="$(grep -Fxf "$remote_files" "$home_view_files" || true)"
if [ -n "$intersection" ]; then
  for f in $intersection; do
    echo "-- $f"
    rg -n --type go 't\.Skip\(|Skipf\(' "$f" || true
  done
else
  echo "No intersection files found."
fi

Repository: asheshgoplani/agent-deck

Length of output: 355


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== issue953_counter_test.go: home.View() call sites =="
rg -n --type go 'home\.View\(' internal/ui/issue953_counter_test.go

echo
echo "== issue953_counter_test.go: nearby remoteSessions / RemoteSession setup near home.View() =="
# show a window around the home.View() call
view_line=$(rg -n --type go 'home\.View\(' internal/ui/issue953_counter_test.go | head -n 1 | cut -d: -f1)
start=$((view_line-60)); end=$((view_line+60))
sed -n "${start},${end}p" internal/ui/issue953_counter_test.go

echo
echo "== home_test.go: home.View() call sites =="
rg -n --type go 'home\.View\(' internal/ui/home_test.go

echo
echo "== home_test.go: check remote setup near each home.View() occurrence =="
# For each View() line, print a small context and look for remoteSessions / RemoteSession / ItemTypeRemoteSession
rg -n --type go 'home\.View\(' internal/ui/home_test.go | while read -r line; do
  ln=$(echo "$line" | cut -d: -f1)
  echo "---- home_test.go:$ln ----"
  sed -n "$((ln-50)),$((ln+50))p" internal/ui/home_test.go | rg -n 'remoteSessions|RemoteSession|ItemTypeRemoteSession|remotePreviewCacheKey' || true
done

echo
echo "== home_test.go: any Home.View tests that explicitly set flatItems with RemoteSession just before View() =="
rg -n --type go 'ItemTypeRemoteSession|RemoteSessionInfo|remoteSessions' internal/ui/home_test.go -g'*_test.go' | head -n 80

Repository: asheshgoplani/agent-deck

Length of output: 6780


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show context around remote flatItems assignments and the next View() usage.
ranges=(
  "1260,1320"
  "1310,1380"
  "1360,1425"
  "1410,1475"
  "1460,1525"
  "2940,3020"
)

for r in "${ranges[@]}"; do
  echo "==== internal/ui/home_test.go lines $r ===="
  sed -n "${r}p" internal/ui/home_test.go | rg -n 'RemoteSession|RemoteSessionInfo|ItemTypeRemoteSession|flatItems|home\.View\(' || true
done

echo
echo "== List all home.View() occurrences with nearby line window in home_test.go =="
rg -n --type go 'home\.View\(' internal/ui/home_test.go | while read -r line; do
  ln=$(echo "$line" | cut -d: -f1)
  echo "-- home.View() at $ln --"
  sed -n "$((ln-20)),$((ln+20))p" internal/ui/home_test.go | rg -n 'RemoteSession|remoteSessions|ItemTypeRemoteSession|flatItems' || true
done

Repository: asheshgoplani/agent-deck

Length of output: 4112


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the blocks around each home.View() call and also any nearby remote flatItems assignments.
view_lines=(195 238 1755 1784 1842 1874 2351)

for ln in "${view_lines[@]}"; do
  start=$((ln-120)); end=$((ln+120))
  echo "================ home_test.go around home.View() at $ln ($start-$end) ================"
  sed -n "${start},${end}p" internal/ui/home_test.go | rg -n 'RemoteSessionInfo|ItemTypeRemoteSession|RemoteSession:|flatItems|remote|Home\.View|home\.View|previewCache|render' || true
done

echo
echo "== List remote flatItems assignments in home_test.go =="
rg -n 'home\.flatItems\s*=\s*\[\]session\.Item\{\{Type:\s*session\.ItemTypeRemoteSession' internal/ui/home_test.go

echo
echo "== List all home.flatItems assignments in home_test.go (near those view calls) =="
# Only print flatItems assignments that are within 600 lines of any View() call we care about.
# Build a set of candidate line numbers by grepping for View() and then checking nearby flatItems lines.
rg -n --type go 'home\.View\(' internal/ui/home_test.go | awk -F: '{print $1}' > /tmp/view_lines.txt
python3 - <<'PY'
import re
views=[int(x.strip()) for x in open('/tmp/view_lines.txt') if x.strip()]
flat=[]
with open('internal/ui/home_test.go','r',encoding='utf-8') as f:
    for i,line in enumerate(f, start=1):
        if re.search(r'home\.flatItems\s*=', line):
            # keep if close to any view line
            if any(abs(i-v)<=600 for v in views):
                flat.append(i)
for i in sorted(set(flat)):
    print(i)
PY

Repository: asheshgoplani/agent-deck

Length of output: 6127


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import re, pathlib

def analyze(path):
    text = pathlib.Path(path).read_text(encoding='utf-8')
    lines = text.splitlines()
    # Find home.View() call sites
    view_idxs = [i for i,l in enumerate(lines) if re.search(r'\bhome\.View\(\)', l)]
    print(f"\n== {path} home.View() call sites: {len(view_idxs)} ==")
    for i in view_idxs:
        # Find enclosing func Test... by scanning backwards to last func start
        start = None
        for j in range(i, -1, -1):
            if re.match(r'^\s*func\s+Test[A-Za-z0-9_]*\s*\(.*\)\s*\{', lines[j]):
                start = j
                break
        if start is None:
            print(f"- View at line {i+1}: no enclosing Test func found")
            continue
        # Brace count forward to find end of that func
        brace = 0
        end = None
        for j in range(start, len(lines)):
            brace += lines[j].count('{')
            brace -= lines[j].count('}')
            if j>start and brace<=0:
                end = j
                break
        if end is None:
            end = min(len(lines)-1, start+400)

        block = "\n".join(lines[start:end+1])
        has_remote = bool(re.search(r'\bRemoteSession\b|remoteSessionsMu\.|remoteSessions\b|ItemTypeRemoteSession', block))
        has_skip_remote = bool(re.search(r't\.Skipf?\(|Skipf?\(', block) and re.search(r'RemoteSession|remoteSessions', block))
        print(f"- View at line {i+1} inside func at line {start+1}-{end+1}: remote-related={has_remote}, skip-remote-rationale={has_skip_remote}")
        # Print a tiny window with relevant markers if any
        if has_remote:
            # show up to 15 lines around first matching marker in the block
            m = re.search(r'(\bRemoteSession\b|remoteSessionsMu\.|remoteSessions\b|ItemTypeRemoteSession)', block)
            # find its approximate line in file
            # We'll just print the first 80 lines of the block that contain any remote markers.
            for k in range(start, end+1):
                if re.search(r'\bRemoteSession\b|remoteSessionsMu\.|remoteSessions\b|ItemTypeRemoteSession', lines[k]):
                    a=max(start, k-3); b=min(end, k+5)
                    snippet="\n".join(f"{t+1}:{lines[t]}" for t in range(a,b+1))
                    print("  snippet:\n"+snippet)
                    break

for p in [
    "internal/ui/issue953_counter_test.go",
    "internal/ui/home_test.go",
]:
    analyze(p)
PY

Repository: asheshgoplani/agent-deck

Length of output: 995


Add RemoteSession-based coverage for the clampViewToViewport/fitCellWidth path

  • The Home.View() rendering path clamps via clampViewToViewportfitCellWidth, but the existing tests that exercise width/padding (e.g., internal/ui/issue937_keycap_test.go) don’t cover session.RemoteSessionInfo/RemoteSession rendering.
  • In the RemoteSession-related files that call home.View() (internal/ui/issue953_counter_test.go, internal/ui/home_test.go), the home.View() assertions run with non-RemoteSession snapshots (RemoteSession setup happens in other tests that don’t call home.View()), so RemoteSession frames aren’t validated for the width clamping behavior.
  • No t.Skip/Skipf rationale exists for why RemoteSession isn’t covered.

Add a test that populates Home.remoteSessions with RemoteSession rows and asserts the resulting Home.View() output is correctly cell-width padded/truncated (or add an explicit t.Skip with rationale).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/ui/cellwidth.go` around lines 30 - 58, Tests currently don't
exercise the clampViewToViewport → fitCellWidth path for RemoteSession
rendering; add a test that sets up Home.remoteSessions with one or more
RemoteSession rows, calls Home.View(), and asserts the output lines produced by
fitCellWidth/fitLinesToWidth are correctly padded or truncated to the expected
cell width (use cellWidth expectations for multibyte/emoji cases), or if
coverage cannot be added, add a t.Skipf in the existing RemoteSession-related
tests explaining why RemoteSession frames can't be validated here; refer to
Home.View(), Home.remoteSessions, clampViewToViewport, fitCellWidth and
fitLinesToWidth when locating code to modify.

Comment on lines +280 to +296
// Test_clampViewToViewport_PadsEveryRow ensures the final frame pads narrow lines.
func Test_clampViewToViewport_PadsEveryRow(t *testing.T) {
const width, height = 30, 3
in := strings.Join([]string{
strings.Repeat("X", width),
"short",
"",
}, "\n")
out := clampViewToViewport(in, width, height)
lines := strings.Split(out, "\n")
if len(lines) != height {
t.Fatalf("want %d lines, got %d", height, len(lines))
}
if got := cellWidth(lines[1]); got != width {
t.Fatalf("line 1 cellWidth = %d; want %d (must pad, not only truncate)", got, width)
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add RemoteSession coverage (or explicit t.Skip) for this TUI behavior change.

This regression test validates padding behavior, but it does not verify the same behavior under RemoteSession conditions, and there is no explicit t.Skip explaining why that path is excluded. Please add a RemoteSession variant (or document a justified skip) to satisfy the TUI test requirement.

As per coding guidelines, "If a PR changes TUI behavior in internal/ui/ or cmd/agent-deck/, verify it also handles RemoteSession (or has an explicit t.Skip documenting why)."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/ui/issue937_keycap_test.go` around lines 280 - 296, This test
(Test_clampViewToViewport_PadsEveryRow) exercises clampViewToViewport but
doesn't cover the RemoteSession path; either add a parallel subtest that runs
under a RemoteSession context (e.g., initialize or mock RemoteSession and call
clampViewToViewport the same way) to assert identical padding behavior, or add
an explicit t.Skip with a short justification at the top of
Test_clampViewToViewport_PadsEveryRow explaining why RemoteSession isn't
applicable; ensure you reference the RemoteSession initializer/mocker used
elsewhere in internal/ui tests, keep assertions identical (cellWidth check), and
name the subtest to indicate RemoteSession coverage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant