diff --git a/apps/web/src/components/ChatView.tsx b/apps/web/src/components/ChatView.tsx
index b86f81c3..72dbcf66 100644
--- a/apps/web/src/components/ChatView.tsx
+++ b/apps/web/src/components/ChatView.tsx
@@ -39,6 +39,7 @@ import {
useRef,
useState,
} from "react";
+import { createPortal } from "react-dom";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { useDebouncedValue } from "@tanstack/react-pacer";
import { useNavigate } from "@tanstack/react-router";
@@ -236,6 +237,7 @@ import { hasCustomThreadTitle, normalizeThreadTitle } from "~/threadTitle";
import { resolveLiveModelSelection } from "~/modelSelection";
import { getProviderModelOptionsByProvider } from "~/providerModels";
import { enhancePrompt, type PromptEnhancementId } from "../promptEnhancement";
+import { resolveTerminalDockPlacement } from "~/desktopShellLayout";
function preloadThreadTerminalDrawer() {
return import("./ThreadTerminalDrawer");
@@ -398,6 +400,8 @@ function normalizeVisibleInteractionMode(
interface ChatViewProps {
threadId: ThreadId;
onMinimize?: (() => void) | undefined;
+ rightPanelOpen: boolean;
+ rightPanelTerminalDock: HTMLDivElement | null;
}
interface RunProjectScriptOptions {
@@ -408,7 +412,12 @@ interface RunProjectScriptOptions {
rememberAsLastInvoked?: boolean;
}
-export default function ChatView({ threadId, onMinimize }: ChatViewProps) {
+export default function ChatView({
+ threadId,
+ onMinimize,
+ rightPanelOpen,
+ rightPanelTerminalDock,
+}: ChatViewProps) {
const clientMode = useClientMode();
const transportState = useTransportState();
const threads = useStore((store) => store.threads);
@@ -4842,6 +4851,45 @@ export default function ChatView({ threadId, onMinimize }: ChatViewProps) {
return ;
}
+ const terminalDockPlacement = resolveTerminalDockPlacement({
+ clientMode,
+ rightPanelOpen,
+ hasRightPanelTerminalDock: rightPanelTerminalDock !== null,
+ });
+ const terminalDrawer =
+ activeProject && shouldMountTerminalDrawer ? (
+
+ }
+ >
+
+
+
+ ) : null;
+
return (
{/* Top bar */}
@@ -5873,38 +5921,9 @@ export default function ChatView({ threadId, onMinimize }: ChatViewProps) {
{/* Terminal drawer – once mounted, stay mounted to avoid the
unmount/remount flicker when toggling visibility or switching threads.
We hide it with display:none when collapsed so the DOM is retained. */}
- {activeProject && shouldMountTerminalDrawer ? (
-
- }
- >
-
-
-
- ) : null}
+ {terminalDockPlacement === "right-panel" && rightPanelTerminalDock && terminalDrawer
+ ? createPortal(terminalDrawer, rightPanelTerminalDock)
+ : terminalDrawer}