From acae8b9419d39ecff6ef96335412baab5fcc1f20 Mon Sep 17 00:00:00 2001 From: Johannes du Plessis Date: Mon, 15 Jun 2026 09:55:19 -0700 Subject: [PATCH] feat: let agent git panel resize to nearly full window width (#1525) The git panel was capped at a fixed 720px max width, which wasted space on wide/ultrawide screens. Make the max width dynamic relative to the viewport (window width minus a minimum chat width) so it can be dragged up to ~50/50 or wider, and re-clamp on window resize. Co-authored-by: open-swe[bot] --- ui/src/components/agents/AgentGitPanel.tsx | 26 +++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/ui/src/components/agents/AgentGitPanel.tsx b/ui/src/components/agents/AgentGitPanel.tsx index b85c97e5..219f6cfc 100644 --- a/ui/src/components/agents/AgentGitPanel.tsx +++ b/ui/src/components/agents/AgentGitPanel.tsx @@ -77,14 +77,25 @@ const COLLAPSED_STATE_TRUE = "1" const COLLAPSED_STATE_FALSE = "0" const PANEL_DEFAULT_WIDTH = 420 const PANEL_MIN_WIDTH = 320 -const PANEL_MAX_WIDTH = 720 +// Keep at least this much room for the chat so the panel can grow to nearly the +// full window (e.g. ~50/50 on ultrawide screens) without hiding the chat. +const PANEL_MIN_CHAT_WIDTH = 360 + +function getPanelMaxWidth(): number { + if (typeof window === "undefined") return PANEL_DEFAULT_WIDTH + return Math.max(PANEL_MIN_WIDTH, window.innerWidth - PANEL_MIN_CHAT_WIDTH) +} + +function clampPanelWidth(width: number): number { + return Math.min(getPanelMaxWidth(), Math.max(PANEL_MIN_WIDTH, width)) +} function readStoredPanelWidth(): number { if (typeof window === "undefined") return PANEL_DEFAULT_WIDTH const raw = window.localStorage.getItem(PANEL_STORAGE_WIDTH) const parsed = raw ? Number(raw) : NaN if (!Number.isFinite(parsed)) return PANEL_DEFAULT_WIDTH - return Math.min(PANEL_MAX_WIDTH, Math.max(PANEL_MIN_WIDTH, parsed)) + return clampPanelWidth(parsed) } function readStoredPanelCollapsed(): boolean { @@ -191,10 +202,19 @@ export function AgentGitPanel({ thread, messages }: AgentGitPanelProps) { } const setWidth = useCallback((next: number) => { - const clamped = Math.min(PANEL_MAX_WIDTH, Math.max(PANEL_MIN_WIDTH, next)) + const clamped = clampPanelWidth(next) setWidthState(clamped) window.localStorage.setItem(PANEL_STORAGE_WIDTH, String(clamped)) }, []) + + // Re-clamp the stored width when the window shrinks so the panel never + // exceeds the available space (which would squeeze out the chat). + useEffect(() => { + if (typeof window === "undefined") return + const onResize = () => setWidth(width) + window.addEventListener("resize", onResize) + return () => window.removeEventListener("resize", onResize) + }, [setWidth, width]) const [selectedTreePath, setSelectedTreePath] = useState(null) const sectionRefs = useRef>({}) const pr = thread.pr