diff --git a/apps/web/src/components/app/agents-view.tsx b/apps/web/src/components/app/agents-view.tsx
index 2375030a..1a9038db 100644
--- a/apps/web/src/components/app/agents-view.tsx
+++ b/apps/web/src/components/app/agents-view.tsx
@@ -8,7 +8,7 @@ import {
} from "react";
import { createPortal } from "react-dom";
import { Routes, Route, useNavigate, useParams } from "react-router-dom";
-import { PanelLeftOpen, PanelRightOpen, Split } from "lucide-react";
+import { PanelLeftOpen, PanelRightOpen } from "lucide-react";
import { ChangesTab } from "@/components/app/changes-tab";
import { ChangesSettingsPopover } from "@/components/app/changes-settings-popover";
@@ -17,6 +17,7 @@ import {
TAB_DRAG_MIME,
} from "@/components/app/center-pane-tab-bar";
import { SplitDropZones } from "@/components/app/split-drop-zones";
+import { CenterPaneSplit } from "@/components/app/center-pane-split";
import { useAgentDiffStats } from "@/hooks/use-agent-diff-stats";
import { useSplitPane } from "@/hooks/use-split-pane";
@@ -50,11 +51,6 @@ import {
} from "@/components/app/types";
import { Button } from "@/components/ui/button";
import { GlassSidebar } from "@/components/ui/glass-sidebar";
-import {
- ResizableHandle,
- ResizablePanel,
- ResizablePanelGroup,
-} from "@/components/ui/resizable";
import { uploadAgentMedia } from "@/lib/media-upload";
import {
type AgentType,
@@ -748,85 +744,16 @@ export function AgentsView({
onDrop={handleContentDrop}
>
{isSplit ? (
-
-
-
-
-
-
- {splitState.left === "terminal"
- ? "Terminal"
- : "Changes"}
-
- {splitState.left === "changes" && !isMobile ? (
-
- ) : null}
-
-
- {splitState.left === "terminal" ? (
-
- ) : (
- changesElement
- )}
-
-
-
-
-
-
-
-
- {splitState.right === "terminal"
- ? "Terminal"
- : "Changes"}
-
- {splitState.right === "changes" && !isMobile ? (
-
- ) : null}
-
-
- {splitState.right === "terminal" ? (
-
- ) : (
- changesElement
- )}
-
-
-
-
-
-
-
-
+
) : (
<>
;
+ splitButtonRef: React.RefObject
;
+ splitTerminalSlotRef: React.RefObject;
+ changesElement: React.ReactNode;
+ isMobile: boolean;
+ onLayoutChange: (layout: Record) => void;
+ onExitSplit: () => void;
+};
+
+/**
+ * The split-pane layout for the center pane: two resizable panels, each showing
+ * either the terminal (via the shared terminal slot) or the Changes tab, with an
+ * unsplit button anchored on the divider. Purely presentational — the terminal
+ * DOM node is portaled into `splitTerminalSlotRef` by the parent.
+ */
+export function CenterPaneSplit({
+ splitState,
+ splitLeftRef,
+ splitButtonRef,
+ splitTerminalSlotRef,
+ changesElement,
+ isMobile,
+ onLayoutChange,
+ onExitSplit,
+}: CenterPaneSplitProps): JSX.Element {
+ return (
+
+
+
+
+
+
+ {splitState.left === "terminal" ? "Terminal" : "Changes"}
+
+ {splitState.left === "changes" && !isMobile ? (
+
+ ) : null}
+
+
+ {splitState.left === "terminal" ? (
+
+ ) : (
+ changesElement
+ )}
+
+
+
+
+
+
+
+
+ {splitState.right === "terminal" ? "Terminal" : "Changes"}
+
+ {splitState.right === "changes" && !isMobile ? (
+
+ ) : null}
+
+
+ {splitState.right === "terminal" ? (
+
+ ) : (
+ changesElement
+ )}
+
+
+
+
+
+
+
+
+ );
+}