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