@@ -51,9 +51,11 @@ interface MainTerminalProps {
5151 onCwdChange ?: ( cwd : string ) => void ;
5252 /** Called when terminal title changes (via OSC escape codes) */
5353 onTitleChange ?: ( title : string ) => void ;
54+ /** Called when PTY is spawned with the PTY ID (for cleanup tracking) */
55+ onPtyIdReady ?: ( ptyId : string ) => void ;
5456}
5557
56- export function MainTerminal ( { entityId, sessionId, type = 'main' , isActive, shouldAutoFocus, focusTrigger, terminalConfig, activityTimeout = 250 , initialCwd, onFocus, onNotification, onThinkingChange, onCwdChange, onTitleChange } : MainTerminalProps ) {
58+ export function MainTerminal ( { entityId, sessionId, type = 'main' , isActive, shouldAutoFocus, focusTrigger, terminalConfig, activityTimeout = 250 , initialCwd, onFocus, onNotification, onThinkingChange, onCwdChange, onTitleChange, onPtyIdReady } : MainTerminalProps ) {
5759 // Use sessionId for spawn if provided, otherwise fall back to entityId (for backward compatibility)
5860 const spawnId = sessionId ?? entityId ;
5961 const containerRef = useRef < HTMLDivElement > ( null ) ;
@@ -220,6 +222,12 @@ export function MainTerminal({ entityId, sessionId, type = 'main', isActive, sho
220222 onTitleChangeRef . current = onTitleChange ;
221223 } , [ onTitleChange ] ) ;
222224
225+ // Store onPtyIdReady in ref so spawn handlers can access the latest version
226+ const onPtyIdReadyRef = useRef ( onPtyIdReady ) ;
227+ useEffect ( ( ) => {
228+ onPtyIdReadyRef . current = onPtyIdReady ;
229+ } , [ onPtyIdReady ] ) ;
230+
223231 // Progress indicator logic:
224232 // - Activity (output/title): start timer, reset on more activity, turn off when timer expires
225233 // - OSC 9 progress: explicit start/stop (no timeout)
@@ -470,7 +478,12 @@ export function MainTerminal({ entityId, sessionId, type = 'main', isActive, sho
470478
471479 spawnedAtRef . current = Date . now ( ) ;
472480 // Pass initialCwd for scratch terminals to start in the specified directory
473- await spawnRef . current ( spawnId , type , cols , rows , type === 'scratch' ? initialCwd : undefined ) ;
481+ const newPtyId = await spawnRef . current ( spawnId , type , cols , rows , type === 'scratch' ? initialCwd : undefined ) ;
482+
483+ // Notify parent of the PTY ID for cleanup tracking
484+ if ( newPtyId && isMounted ) {
485+ onPtyIdReadyRef . current ?.( newPtyId ) ;
486+ }
474487
475488 // For project type, mark as ready immediately (no startup delay like main command)
476489 if ( type === 'project' && isMounted ) {
@@ -543,7 +556,12 @@ export function MainTerminal({ entityId, sessionId, type = 'main', isActive, sho
543556 const cols = terminal . cols ;
544557 const rows = terminal . rows ;
545558 spawnedAtRef . current = Date . now ( ) ;
546- await spawn ( spawnId , currentMode , cols , rows ) ;
559+ const newPtyId = await spawn ( spawnId , currentMode , cols , rows ) ;
560+
561+ // Notify parent of the new PTY ID for cleanup tracking
562+ if ( newPtyId ) {
563+ onPtyIdReadyRef . current ?.( newPtyId ) ;
564+ }
547565 } , [ spawn , spawnId , currentMode ] ) ;
548566
549567 // Launch shell handler for when the user wants a shell instead of the main command
@@ -571,7 +589,12 @@ export function MainTerminal({ entityId, sessionId, type = 'main', isActive, sho
571589 const cols = terminal . cols ;
572590 const rows = terminal . rows ;
573591 spawnedAtRef . current = Date . now ( ) ;
574- await spawn ( spawnId , 'shell' , cols , rows ) ;
592+ const newPtyId = await spawn ( spawnId , 'shell' , cols , rows ) ;
593+
594+ // Notify parent of the new PTY ID for cleanup tracking
595+ if ( newPtyId ) {
596+ onPtyIdReadyRef . current ?.( newPtyId ) ;
597+ }
575598 } , [ spawn , spawnId ] ) ;
576599
577600 // Store resize function in ref to avoid dependency issues
0 commit comments