diff --git a/apps/app/src/components/secondary-panel/SecondaryPanelLayout.tsx b/apps/app/src/components/secondary-panel/SecondaryPanelLayout.tsx
index bafad99c04c..1f23136689b 100644
--- a/apps/app/src/components/secondary-panel/SecondaryPanelLayout.tsx
+++ b/apps/app/src/components/secondary-panel/SecondaryPanelLayout.tsx
@@ -92,6 +92,8 @@ export function SecondaryPanelLayout({
}: SecondaryPanelLayoutProps) {
const paneContext = useOptionalPaneContext();
const secondaryPanelHost = paneContext?.secondaryPanelHost ?? null;
+ const inlinePaneTargetId =
+ secondaryPanelHost === null ? paneContext?.paneId : undefined;
const renderAsDrawer = useIsCompactViewport();
const sidebarDrawerShowing = useSyncExternalStore(
subscribeCompactSidebarDrawerShowing,
@@ -297,6 +299,7 @@ export function SecondaryPanelLayout({
const mainContent = (
= MAX_PANES,
+ singlePane: countPanes(layout.root) === 1,
});
},
onDrop: (target) => {
diff --git a/apps/app/src/components/sidebar/useThreadRowSplitDrag.ts b/apps/app/src/components/sidebar/useThreadRowSplitDrag.ts
index e1531f7277e..b4f5c4aad35 100644
--- a/apps/app/src/components/sidebar/useThreadRowSplitDrag.ts
+++ b/apps/app/src/components/sidebar/useThreadRowSplitDrag.ts
@@ -82,6 +82,7 @@ export function useThreadRowSplitDrag({
threadAlreadyOpen:
findPaneByThread(layout.root, projectId, threadId) !== null,
atMaxPanes: countPanes(layout.root) >= MAX_PANES,
+ singlePane: countPanes(layout.root) === 1,
});
},
onDrop: (target) => {
diff --git a/apps/app/src/lib/split-drag/zones.test.ts b/apps/app/src/lib/split-drag/zones.test.ts
index 30e91a12eb4..cac2e37e706 100644
--- a/apps/app/src/lib/split-drag/zones.test.ts
+++ b/apps/app/src/lib/split-drag/zones.test.ts
@@ -89,6 +89,17 @@ describe("decideThreadDrop", () => {
).toEqual({ zone: "center", label: "Replace this chat" });
});
+ it("splits a center zone when the workspace has a single pane", () => {
+ expect(
+ decideThreadDrop({
+ zone: "center",
+ threadAlreadyOpen: false,
+ atMaxPanes: false,
+ singlePane: true,
+ }),
+ ).toEqual({ zone: "right", label: "Split right" });
+ });
+
it("coerces edges to center-replace at the pane cap", () => {
expect(
decideThreadDrop({
diff --git a/apps/app/src/lib/split-drag/zones.ts b/apps/app/src/lib/split-drag/zones.ts
index 19016ea827a..77c3c7c2504 100644
--- a/apps/app/src/lib/split-drag/zones.ts
+++ b/apps/app/src/lib/split-drag/zones.ts
@@ -85,12 +85,14 @@ interface ThreadDropInput {
zone: SplitZone;
threadAlreadyOpen: boolean;
atMaxPanes: boolean;
+ singlePane?: boolean;
}
export function decideThreadDrop({
zone,
threadAlreadyOpen,
atMaxPanes,
+ singlePane = false,
}: ThreadDropInput): ZoneDecision {
if (threadAlreadyOpen) {
return { zone: "center", label: "Already open — focus pane" };
@@ -98,9 +100,13 @@ export function decideThreadDrop({
if (atMaxPanes) {
return { zone: "center", label: "Replace this chat" };
}
+ const resolvedZone = singlePane && zone === "center" ? "right" : zone;
return {
- zone,
- label: zone === "center" ? "Replace this chat" : `Split ${zone}`,
+ zone: resolvedZone,
+ label:
+ resolvedZone === "center"
+ ? "Replace this chat"
+ : `Split ${resolvedZone}`,
};
}