11import React , { useMemo , useState , useEffect , useCallback , useRef } from 'react' ;
22import { TerminalPane } from './TerminalPane' ;
33import { LifecycleTerminalView } from './LifecycleTerminalView' ;
4- import { Plus , Play , RotateCw , Square , X } from 'lucide-react' ;
4+ import { Plus , Play , RotateCw , Square , X , Maximize2 } from 'lucide-react' ;
55import { useTheme } from '../hooks/useTheme' ;
66import { useTaskTerminals } from '@/lib/taskTerminalsStore' ;
77import { useTerminalSelection } from '../hooks/useTerminalSelection' ;
@@ -29,6 +29,7 @@ import {
2929 formatLifecycleLogLine ,
3030} from '@shared/lifecycle' ;
3131import { shouldDisablePlay } from '../lib/lifecycleUi' ;
32+ import ExpandedTerminalModal from './ExpandedTerminalModal' ;
3233
3334interface Task {
3435 id : string ;
@@ -81,6 +82,16 @@ const TaskTerminalPanelComponent: React.FC<Props> = ({
8182
8283 const selection = useTerminalSelection ( { task, taskTerminals, globalTerminals } ) ;
8384
85+ const [ expandedTerminalId , setExpandedTerminalId ] = useState < string | null > ( null ) ;
86+ // Tracks which terminal needs a key bump to force re-attach after modal close
87+ const [ reattachId , setReattachId ] = useState < string | null > ( null ) ;
88+ const reattachCounter = useRef ( 0 ) ;
89+ const handleCloseExpandedTerminal = useCallback ( ( ) => {
90+ setReattachId ( expandedTerminalId ) ;
91+ reattachCounter . current += 1 ;
92+ setExpandedTerminalId ( null ) ;
93+ } , [ expandedTerminalId ] ) ;
94+
8495 const panelRef = useRef < HTMLDivElement | null > ( null ) ;
8596 const terminalRefs = useRef < Map < string , { focus : ( ) => void } > > ( new Map ( ) ) ;
8697 const setTerminalRef = useCallback ( ( id : string , ref : { focus : ( ) => void } | null ) => {
@@ -645,6 +656,27 @@ const TaskTerminalPanelComponent: React.FC<Props> = ({
645656 </ TooltipProvider >
646657 ) }
647658
659+ { /* Expand terminal to full-screen modal */ }
660+ { selection . activeTerminalId && ! selection . selectedLifecycle && (
661+ < TooltipProvider delayDuration = { 200 } >
662+ < Tooltip >
663+ < TooltipTrigger asChild >
664+ < Button
665+ variant = "ghost"
666+ size = "icon-sm"
667+ onClick = { ( ) => setExpandedTerminalId ( selection . activeTerminalId ) }
668+ className = "text-muted-foreground hover:text-foreground"
669+ >
670+ < Maximize2 className = "h-3.5 w-3.5" />
671+ </ Button >
672+ </ TooltipTrigger >
673+ < TooltipContent side = "bottom" >
674+ < p className = "text-xs" > Expand terminal</ p >
675+ </ TooltipContent >
676+ </ Tooltip >
677+ </ TooltipProvider >
678+ ) }
679+
648680 { ( ( ) => {
649681 const canDelete =
650682 selection . parsed ?. mode === 'task'
@@ -743,6 +775,7 @@ const TaskTerminalPanelComponent: React.FC<Props> = ({
743775 ) }
744776 >
745777 < TerminalPane
778+ key = { `${ terminal . id } ${ reattachId === terminal . id ? `::${ reattachCounter . current } ` : '' } ` }
746779 ref = { ( r ) => setTerminalRef ( terminal . id , r ) }
747780 id = { terminal . id }
748781 cwd = { terminal . cwd || task . path }
@@ -774,6 +807,7 @@ const TaskTerminalPanelComponent: React.FC<Props> = ({
774807 ) }
775808 >
776809 < TerminalPane
810+ key = { `${ terminal . id } ${ reattachId === terminal . id ? `::${ reattachCounter . current } ` : '' } ` }
777811 ref = { ( r ) => setTerminalRef ( terminal . id , r ) }
778812 id = { terminal . id }
779813 cwd = { terminal . cwd || projectPath }
@@ -795,6 +829,21 @@ const TaskTerminalPanelComponent: React.FC<Props> = ({
795829 ) : null }
796830 </ div >
797831 ) }
832+ { /* Expanded terminal modal */ }
833+ { expandedTerminalId && (
834+ < ExpandedTerminalModal
835+ terminalId = { expandedTerminalId }
836+ title = {
837+ selection . parsed ?. mode === 'task'
838+ ? `${ task ?. name || 'Task' } — Terminal`
839+ : selection . parsed ?. mode === 'global'
840+ ? 'Project Terminal'
841+ : 'Terminal'
842+ }
843+ onClose = { handleCloseExpandedTerminal }
844+ variant = { effectiveTheme === 'dark' || effectiveTheme === 'dark-black' ? 'dark' : 'light' }
845+ />
846+ ) }
798847 </ div >
799848 ) ;
800849} ;
0 commit comments