diff --git a/.changeset/fix-agent-manager-scroll.md b/.changeset/fix-agent-manager-scroll.md new file mode 100644 index 00000000000..427e3451f14 --- /dev/null +++ b/.changeset/fix-agent-manager-scroll.md @@ -0,0 +1,5 @@ +--- +"kilo-code": patch +--- + +Fix scroll jump issue when reading long completion messages in Agent Manager diff --git a/webview-ui/src/kilocode/agent-manager/components/MessageList.tsx b/webview-ui/src/kilocode/agent-manager/components/MessageList.tsx index 2ef97722513..d0a2ea305de 100644 --- a/webview-ui/src/kilocode/agent-manager/components/MessageList.tsx +++ b/webview-ui/src/kilocode/agent-manager/components/MessageList.tsx @@ -141,15 +141,26 @@ export function MessageList({ sessionId }: MessageListProps) { return info }, [messages]) + // Track previous message count to detect new messages vs content updates + const prevMessageCountRef = useRef(combinedMessages.length) + // Auto-scroll to bottom when new messages arrive using Virtuoso API useEffect(() => { - if (isAtBottom && combinedMessages.length > 0) { + // Reset scroll state when switching sessions + prevMessageCountRef.current = combinedMessages.length + + // Only auto-scroll if: + // 1. User is at bottom (isAtBottom is true) + // 2. A new message was added (not just content update) + if (isAtBottom && combinedMessages.length > prevMessageCountRef.current) { virtuosoRef.current?.scrollToIndex({ index: combinedMessages.length - 1, behavior: "smooth", }) } - }, [combinedMessages.length, isAtBottom]) + // Update the previous count for next render + prevMessageCountRef.current = combinedMessages.length + }, [combinedMessages.length, isAtBottom, sessionId]) const handleSuggestionClick = useCallback( (suggestion: SuggestionItem) => { @@ -252,10 +263,10 @@ export function MessageList({ sessionId }: MessageListProps) { ref={virtuosoRef} data={allItems} itemContent={itemContent} - followOutput={isAtBottom ? "smooth" : false} // kilocode_change - atBottomStateChange={setIsAtBottom} // kilocode_change + atBottomStateChange={setIsAtBottom} increaseViewportBy={{ top: 400, bottom: 400 }} className="am-messages-list" + followOutput={isAtBottom ? "smooth" : false} /> {showScrollToBottom && (