| ... | ... | @@ -112,6 +112,7 @@ interface TerminalViewportProps { |
| 112 | 112 | terminalId: string; |
| 113 | 113 | cwd: string; |
| 114 | 114 | runtimeEnv?: Record<string, string>; |
| 115 | onSessionExited: () => void; |
| 115 | 116 | focusRequestId: number; |
| 116 | 117 | autoFocus: boolean; |
| 117 | 118 | resizeEpoch: number; |
| ... | ... | @@ -123,6 +124,7 @@ function TerminalViewport({ |
| 123 | 124 | terminalId, |
| 124 | 125 | cwd, |
| 125 | 126 | runtimeEnv, |
| 127 | onSessionExited, |
| 126 | 128 | focusRequestId, |
| 127 | 129 | autoFocus, |
| 128 | 130 | resizeEpoch, |
| ... | ... | @@ -131,6 +133,12 @@ function TerminalViewport({ |
| 131 | 133 | const containerRef = useRef<HTMLDivElement>(null); |
| 132 | 134 | const terminalRef = useRef<Terminal | null>(null); |
| 133 | 135 | const fitAddonRef = useRef<FitAddon | null>(null); |
| 136 | const onSessionExitedRef = useRef(onSessionExited); |
| 137 | const hasHandledExitRef = useRef(false); |
| 138 | |
| 139 | useEffect(() => { |
| 140 | onSessionExitedRef.current = onSessionExited; |
| 141 | }, [onSessionExited]); |
| 134 | 142 | |
| 135 | 143 | useEffect(() => { |
| 136 | 144 | const mount = containerRef.current; |
| ... | ... | @@ -306,6 +314,7 @@ function TerminalViewport({ |
| 306 | 314 | } |
| 307 | 315 | |
| 308 | 316 | if (event.type === "started" || event.type === "restarted") { |
| 317 | hasHandledExitRef.current = false; |
| 309 | 318 | activeTerminal.write("\u001bc"); |
| 310 | 319 | if (event.snapshot.history.length > 0) { |
| 311 | 320 | activeTerminal.write(event.snapshot.history); |
| ... | ... | @@ -335,6 +344,13 @@ function TerminalViewport({ |
| 335 | 344 | activeTerminal, |
| 336 | 345 | details.length > 0 ? `Process exited (${details})` : "Process exited", |
| 337 | 346 | ); |
| 347 | if (hasHandledExitRef.current) { |
| 348 | return; |
| 349 | } |
| 350 | hasHandledExitRef.current = true; |
| 351 | window.setTimeout(() => { |
| 352 | onSessionExitedRef.current(); |
| 353 | }, 0); |
| 338 | 354 | } |
| 339 | 355 | }); |
| 340 | 356 | |
| ... | ... | @@ -783,6 +799,7 @@ export default function ThreadTerminalDrawer({ |
| 783 | 799 | terminalId={terminalId} |
| 784 | 800 | cwd={cwd} |
| 785 | 801 | {...(runtimeEnv ? { runtimeEnv } : {})} |
| 802 | onSessionExited={() => onCloseTerminal(terminalId)} |
| 786 | 803 | focusRequestId={focusRequestId} |
| 787 | 804 | autoFocus={terminalId === resolvedActiveTerminalId} |
| 788 | 805 | resizeEpoch={resizeEpoch} |
| ... | ... | @@ -800,6 +817,7 @@ export default function ThreadTerminalDrawer({ |
| 800 | 817 | terminalId={resolvedActiveTerminalId} |
| 801 | 818 | cwd={cwd} |
| 802 | 819 | {...(runtimeEnv ? { runtimeEnv } : {})} |
| 820 | onSessionExited={() => onCloseTerminal(resolvedActiveTerminalId)} |
| 803 | 821 | focusRequestId={focusRequestId} |
| 804 | 822 | autoFocus |
| 805 | 823 | resizeEpoch={resizeEpoch} |