@@ -58,6 +58,7 @@ import {
5858 fitAgentTerminals ,
5959 isAgentRuntimeRunning ,
6060 markAgentRuntimeStarted ,
61+ previewAgentSessionTitle ,
6162 setAgentTerminalRef ,
6263 setDraftPromptInputRef ,
6364 syncAgentPaneSize ,
@@ -409,6 +410,10 @@ export default function WorkspaceScreen({ locale, appSettings, onOpenSettings }:
409410 const [ slashSkillItems , setSlashSkillItems ] = useState < ClaudeSlashSkillEntry [ ] > ( [ ] ) ;
410411 const [ bootstrapReady , setBootstrapReady ] = useState ( false ) ;
411412 const [ controllerActionBusy , setControllerActionBusy ] = useState < "takeover" | "reject" | null > ( null ) ;
413+ const [ agentRecoveryBusy , setAgentRecoveryBusy ] = useState < {
414+ sessionId : string ;
415+ kind : "resume" | "restart" ;
416+ } | null > ( null ) ;
412417 const [ optimisticTakeoverWorkspaceId , setOptimisticTakeoverWorkspaceId ] = useState < string | null > ( null ) ;
413418 const t = useMemo ( ( ) => createTranslator ( locale ) , [ locale ] ) ;
414419 const deviceId = useMemo ( ( ) => getOrCreateDeviceId ( ) , [ ] ) ;
@@ -1697,10 +1702,22 @@ export default function WorkspaceScreen({ locale, appSettings, onOpenSettings }:
16971702 const onRecoverActiveSession = async ( ) => {
16981703 const currentTab = stateRef . current . tabs . find ( ( tab ) => tab . id === activeTab . id ) ?? activeTab ;
16991704 const session = currentTab . sessions . find ( ( item ) => item . id === activePaneSession . id ) ?? activePaneSession ;
1700- const started = await agentStartMaybe ( currentTab , session , currentTab . activePaneId ) ;
1701- if ( ! started ) return ;
1702- if ( started . started && started . startupToken !== null ) {
1703- await waitForAgentStartupDrain ( agentRuntimeRefs , currentTab . id , session . id , started . startupToken ) ;
1705+ const recoveryAction = resolveAgentRecoveryAction ( currentTab . controller , session ) ;
1706+ if ( ! recoveryAction ) return ;
1707+ setAgentRecoveryBusy ( {
1708+ sessionId : session . id ,
1709+ kind : recoveryAction . kind ,
1710+ } ) ;
1711+ try {
1712+ const started = await agentStartMaybe ( currentTab , session , currentTab . activePaneId ) ;
1713+ if ( ! started ) return ;
1714+ if ( started . started && started . startupToken !== null ) {
1715+ await waitForAgentStartupDrain ( agentRuntimeRefs , currentTab . id , session . id , started . startupToken ) ;
1716+ }
1717+ } finally {
1718+ setAgentRecoveryBusy ( ( current ) => (
1719+ current ?. sessionId === session . id ? null : current
1720+ ) ) ;
17041721 }
17051722 } ;
17061723
@@ -2226,13 +2243,30 @@ export default function WorkspaceScreen({ locale, appSettings, onOpenSettings }:
22262243
22272244 const onSubmitDraftPrompt = async ( paneId : string , submittedValue ?: string ) => {
22282245 if ( ! guardWorkspaceMutation ( "agent_input" ) ) return ;
2246+ const activeTabSnapshot = stateRef . current . tabs . find ( ( tab ) => tab . id === stateRef . current . activeTabId ) ;
2247+ const paneSessionId = activeTabSnapshot
2248+ ? ( findPaneSessionId ( activeTabSnapshot . paneLayout , paneId ) ?? activeTabSnapshot . activeSessionId )
2249+ : null ;
2250+ const currentSessionSnapshot = paneSessionId && activeTabSnapshot
2251+ ? activeTabSnapshot . sessions . find ( ( session ) => session . id === paneSessionId ) ?? null
2252+ : null ;
22292253 const content = (
22302254 submittedValue
22312255 ?? draftPromptInputRefs . current . get ( paneId ) ?. value
22322256 ?? draftPromptInputs [ paneId ]
22332257 ?? ""
22342258 ) . trim ( ) ;
22352259 if ( ! content ) return ;
2260+ if ( activeTabSnapshot && currentSessionSnapshot ) {
2261+ previewAgentSessionTitle ( {
2262+ tabId : activeTabSnapshot . id ,
2263+ sessionId : currentSessionSnapshot . id ,
2264+ rawInput : content ,
2265+ locale,
2266+ t,
2267+ updateTab,
2268+ } ) ;
2269+ }
22362270 setDraftPromptInputs ( ( current ) => ( {
22372271 ...current ,
22382272 [ paneId ] : ""
@@ -2496,6 +2530,10 @@ export default function WorkspaceScreen({ locale, appSettings, onOpenSettings }:
24962530 ? ( hasTerminalOutput ? "live" : "steady" )
24972531 : "idle" ;
24982532 const agentRecoveryAction = resolveAgentRecoveryAction ( activeTab . controller , isArchiveView ? null : activePaneSession ) ;
2533+ const activeAgentRecoveryBusy = ! isArchiveView && agentRecoveryBusy ?. sessionId === activePaneSession . id
2534+ ? agentRecoveryBusy
2535+ : null ;
2536+ const visibleAgentRecoveryAction = agentRecoveryAction ?? activeAgentRecoveryBusy ;
24992537 const terminalRecoveryAction = resolveTerminalRecoveryAction ( activeTab . controller , activeTerminal ) ;
25002538 const workspaceStatusBanner = isObserverMode ? (
25012539 < div
@@ -2549,17 +2587,17 @@ export default function WorkspaceScreen({ locale, appSettings, onOpenSettings }:
25492587 </ button >
25502588 </ div >
25512589 </ div >
2552- ) : ( agentRecoveryAction || terminalRecoveryAction ) ? (
2590+ ) : ( visibleAgentRecoveryAction || terminalRecoveryAction ) ? (
25532591 < >
2554- { agentRecoveryAction && (
2592+ { visibleAgentRecoveryAction && (
25552593 < div
25562594 className = "workspace-status-banner recovery"
25572595 data-testid = "workspace-agent-recovery-banner"
25582596 >
25592597 < div className = "workspace-status-banner-copy" >
25602598 < span className = "workspace-status-banner-title" > { t ( "workspaceAgentRecoveryTitle" ) } </ span >
25612599 < span className = "workspace-status-banner-text" >
2562- { agentRecoveryAction . kind === "resume"
2600+ { visibleAgentRecoveryAction . kind === "resume"
25632601 ? t ( "workspaceAgentResumeBody" )
25642602 : t ( "workspaceAgentRestartBody" ) }
25652603 </ span >
@@ -2572,9 +2610,9 @@ export default function WorkspaceScreen({ locale, appSettings, onOpenSettings }:
25722610 onClick = { ( ) => {
25732611 void onRecoverActiveSession ( ) ;
25742612 } }
2575- disabled = { controllerActionBusy !== null }
2613+ disabled = { controllerActionBusy !== null || activeAgentRecoveryBusy !== null }
25762614 >
2577- { agentRecoveryAction . kind === "resume"
2615+ { visibleAgentRecoveryAction . kind === "resume"
25782616 ? t ( "workspaceAgentResumeAction" )
25792617 : t ( "workspaceAgentRestartAction" ) }
25802618 </ button >
0 commit comments