@@ -14,6 +14,7 @@ import { routeUserPrompt, addBashMessageToHistory } from './commands/router'
1414import type { CommandResult } from './commands/command-registry'
1515import { AnnouncementBanner } from './components/announcement-banner'
1616import { ChatInputBar } from './components/chat-input-bar'
17+ import { LoadPreviousButton } from './components/load-previous-button'
1718import { MessageWithAgents } from './components/message-with-agents'
1819import { PendingBashMessage } from './components/pending-bash-message'
1920import { StatusBar } from './components/status-bar'
@@ -112,6 +113,10 @@ export const Chat = ({
112113 const [ hasOverflow , setHasOverflow ] = useState ( false )
113114 const hasOverflowRef = useRef ( false )
114115
116+ // Message pagination - show last N messages with "Load previous" button
117+ const MESSAGE_BATCH_SIZE = 15
118+ const [ visibleMessageCount , setVisibleMessageCount ] = useState ( MESSAGE_BATCH_SIZE )
119+
115120 const queryClient = useQueryClient ( )
116121 const [ , startUiTransition ] = useTransition ( )
117122
@@ -242,6 +247,13 @@ export const Chat = ({
242247 activeSubagentsRef . current = activeSubagents
243248 } , [ activeSubagents ] )
244249
250+ // Reset visible message count when messages are cleared or conversation changes
251+ useEffect ( ( ) => {
252+ if ( messages . length <= MESSAGE_BATCH_SIZE ) {
253+ setVisibleMessageCount ( MESSAGE_BATCH_SIZE )
254+ }
255+ } , [ messages . length ] )
256+
245257 const isUserCollapsingRef = useRef < boolean > ( false )
246258
247259 const handleCollapseToggle = useCallback (
@@ -1235,6 +1247,20 @@ export const Chat = ({
12351247 [ messages ] ,
12361248 )
12371249
1250+ // Compute visible messages slice (from the end)
1251+ const visibleTopLevelMessages = useMemo ( ( ) => {
1252+ if ( topLevelMessages . length <= visibleMessageCount ) {
1253+ return topLevelMessages
1254+ }
1255+ return topLevelMessages . slice ( - visibleMessageCount )
1256+ } , [ topLevelMessages , visibleMessageCount ] )
1257+
1258+ const hiddenMessageCount = topLevelMessages . length - visibleTopLevelMessages . length
1259+
1260+ const handleLoadPreviousMessages = useCallback ( ( ) => {
1261+ setVisibleMessageCount ( ( prev ) => prev + MESSAGE_BATCH_SIZE )
1262+ } , [ ] )
1263+
12381264 const modeConfig = getInputModeConfig ( inputMode )
12391265 const hasSlashSuggestions =
12401266 slashContext . active &&
@@ -1351,8 +1377,14 @@ export const Chat = ({
13511377 ) }
13521378
13531379 { headerContent }
1354- { topLevelMessages . map ( ( message , idx ) => {
1355- const isLast = idx === topLevelMessages . length - 1
1380+ { hiddenMessageCount > 0 && (
1381+ < LoadPreviousButton
1382+ hiddenCount = { hiddenMessageCount }
1383+ onLoadMore = { handleLoadPreviousMessages }
1384+ />
1385+ ) }
1386+ { visibleTopLevelMessages . map ( ( message , idx ) => {
1387+ const isLast = idx === visibleTopLevelMessages . length - 1
13561388 return (
13571389 < MessageWithAgents
13581390 key = { message . id }
0 commit comments