diff --git a/ui/src/components/TaskChatThread.tsx b/ui/src/components/TaskChatThread.tsx index 5c74721f620..df8ca8c647b 100644 --- a/ui/src/components/TaskChatThread.tsx +++ b/ui/src/components/TaskChatThread.tsx @@ -16,8 +16,11 @@ import type { TaskChatTurnItem, } from "@/components/task-chat/task-chat-model"; import { TaskChatInteractionCard } from "@/components/task-chat/TaskChatInteractionCard"; -import { TaskChatThreadView } from "@/components/task-chat/TaskChatThreadView"; +import { TaskChatThreadView, taskChatContentKey } from "@/components/task-chat/TaskChatThreadView"; import { TaskChatComposer } from "@/components/task-chat/TaskChatComposer"; +import { useWindowAutoFollow } from "@/components/task-chat/useWindowAutoFollow"; +import { useSidebar } from "@/context/SidebarContext"; +import { cn } from "@/lib/utils"; import { useIssuePlanDocument } from "@/hooks/useIssuePlanDocument"; import { latestSameRunHandoffTimestamp, type IssueChatComment } from "@/lib/issue-chat-messages"; import { workModeInEffectAt } from "@/lib/issue-timeline-events"; @@ -373,14 +376,22 @@ export function TaskChatThread(props: TaskChatThreadProps) { ], ); + // Mobile (PAP-360): the app shell scrolls the DOCUMENT (Layout's main is + // overflow-visible with auto height), so the desktop bounded h-dvh chain + // collapses the absolute-inset transcript viewport to 0px. Render the thread + // in document flow instead (the same scroll={false} path the previews use) + // and track auto-follow against window scroll. Desktop stays byte-identical. + const { isMobile } = useSidebar(); + useWindowAutoFollow(isMobile ? taskChatContentKey(items) : 0, isMobile); + return (