145d76e7da
sendViewport called the associated Client.viewport, which builds the handshake frame without RECORDING the window. A client learns its window only from what it announced -- row_labels.len() is the window clipped to the grid, so the two differ exactly at the bottom edge, which is where the scroll arithmetic matters. Without the record the client cannot clamp, so every cursor key goes upstream into Host::handle's empty vec and the arrow keys silently do nothing. Flagged by the improvise-bpq2 agent as the one line its work depended on and which it could not make, web/ being another agent's ground. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EoW5BB87ZZdm96SvBTWawH