From f817909703292d55a0c6a51af1407ba42c43a2de Mon Sep 17 00:00:00 2001 From: Anthony Ronning <101225832+AnthonyRonning@users.noreply.github.com> Date: Wed, 15 Jul 2026 02:48:56 +0000 Subject: [PATCH] feat(agent): match chat composer sizing --- frontend/src/components/AgentMode.tsx | 98 +++++++++++++++++++++++---- 1 file changed, 83 insertions(+), 15 deletions(-) diff --git a/frontend/src/components/AgentMode.tsx b/frontend/src/components/AgentMode.tsx index 2e04cc39a..36de481b5 100644 --- a/frontend/src/components/AgentMode.tsx +++ b/frontend/src/components/AgentMode.tsx @@ -10,12 +10,14 @@ import { ChevronLeft, ChevronRight, Circle, + Expand, FolderOpen, Loader2, Lock, MessageSquarePlus, MoreHorizontal, ShieldCheck, + Shrink, Trash, X, Zap @@ -250,6 +252,9 @@ export function AgentMode({ userId }: { userId: string }) { const [isSessionMcpServersLoading, setIsSessionMcpServersLoading] = useState(false); const [isMcpServerTogglePending, setIsMcpServerTogglePending] = useState(false); const [input, setInput] = useState(""); + const [isAgentFullscreen, setIsAgentFullscreen] = useState( + () => localStorage.getItem("agentFullscreen") === "true" + ); const [error, setError] = useState(null); const [hasManualProxyConflict, setHasManualProxyConflict] = useState(false); const [isAuthTransitionReady, setIsAuthTransitionReady] = useState(false); @@ -303,6 +308,10 @@ export function AgentMode({ userId }: { userId: string }) { activeSessionIdRef.current = activeSessionId; }, [activeSessionId]); + useEffect(() => { + localStorage.setItem("agentFullscreen", isAgentFullscreen.toString()); + }, [isAgentFullscreen]); + const updateAutoScrollFromPosition = useCallback(() => { const container = chatContainerRef.current; if (!container) return; @@ -1765,7 +1774,14 @@ export function AgentMode({ userId }: { userId: string }) { className="relative flex min-h-0 flex-1 flex-col overflow-y-auto overscroll-y-contain" onScroll={updateAutoScrollFromPosition} > -
+
{timelineItems.length === 0 ? ( void sendMessage()} + onToggleExpanded={() => setIsAgentFullscreen((current) => !current)} /> ) : ( -
-

- Work in a folder... -

+
+
+ {!isExpanded ? ( +

+ Work in a folder... +

+ ) : null} -

- - Encrypted and private at every step -

+ {!isExpanded ? ( +

+ + Encrypted and private at every step +

+ ) : null}
); @@ -2218,6 +2247,7 @@ interface AgentComposerProps { model: string; projectRoot: string; recentRoots: RecentProjectRoot[]; + isExpanded?: boolean; onCancelPrompt: () => void; onChooseProjectRoot: () => void; onInputChange: (value: string) => void; @@ -2228,6 +2258,7 @@ interface AgentComposerProps { onModelChange: (value: string) => void; onProjectRootChange: (value: string) => void; onSendMessage: () => void; + onToggleExpanded?: () => void; } function AgentComposer({ @@ -2245,6 +2276,7 @@ function AgentComposer({ model, projectRoot, recentRoots, + isExpanded = false, onCancelPrompt, onChooseProjectRoot, onInputChange, @@ -2254,28 +2286,64 @@ function AgentComposer({ onModeChange, onModelChange, onProjectRootChange, - onSendMessage + onSendMessage, + onToggleExpanded }: AgentComposerProps) { + const textareaRef = useRef(null); const rootOptions = recentRoots.some((root) => root.path === projectRoot) ? recentRoots : projectRoot ? [{ path: projectRoot, name: activeRootLabel, lastUsedMs: Date.now() }, ...recentRoots] : recentRoots; + useLayoutEffect(() => { + const textarea = textareaRef.current; + if (!textarea) return; + + if (isExpanded) { + textarea.style.height = ""; + return; + } + + textarea.style.height = "auto"; + textarea.style.height = `${Math.min(textarea.scrollHeight, 200)}px`; + }, [input, isExpanded]); + return ( - + + {onToggleExpanded ? ( + + ) : null}