diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-07-24 02:49:33 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-07-24 02:50:58 +0300 |
| commit | e608a75159fc5cca70485d83ffb8ee681c9da385 (patch) | |
| tree | 5ffdec62d0bee9a798418d6414ecbddae7ff8ae5 /src/pane.rs | |
| parent | 169a4fd90c20a00aec77d684ecec98b9f0f996cc (diff) | |
fix: make known-agent exit process-owned
refs #1792
refs #1648
Diffstat (limited to 'src/pane.rs')
| -rw-r--r-- | src/pane.rs | 122 |
1 files changed, 81 insertions, 41 deletions
diff --git a/src/pane.rs b/src/pane.rs index ee3aee12..ea6a13fd 100644 --- a/src/pane.rs +++ b/src/pane.rs @@ -290,6 +290,7 @@ fn foreground_member_cwd_different_from_shell( enum ForegroundShellAgentAction { ObserveProbe, ReportProcessExit, + ReportReplacementProcess, ClearAgent, } @@ -299,12 +300,20 @@ fn foreground_shell_agent_action( foreground_is_pane_shell: bool, process_exit_reported: bool, ) -> ForegroundShellAgentAction { - if previous_agent.is_none() || new_agent.is_some() { + let Some(previous_agent) = previous_agent else { return ForegroundShellAgentAction::ObserveProbe; - } - + }; if process_exit_reported { - return ForegroundShellAgentAction::ClearAgent; + return if new_agent == Some(previous_agent) { + ForegroundShellAgentAction::ReportReplacementProcess + } else if new_agent.is_none() { + ForegroundShellAgentAction::ClearAgent + } else { + ForegroundShellAgentAction::ObserveProbe + }; + } + if new_agent.is_some() { + return ForegroundShellAgentAction::ObserveProbe; } if foreground_is_pane_shell { @@ -317,6 +326,38 @@ fn foreground_shell_agent_action( ForegroundShellAgentAction::ObserveProbe } +fn apply_foreground_shell_agent_action( + agent_presence: &mut AgentDetectionPresence, + action: ForegroundShellAgentAction, + previous_agent: Option<Agent>, + new_agent: Option<Agent>, + pending_foreground_shell_clear: &mut bool, + foreground_shell_exit_reported: &mut bool, +) -> bool { + match action { + ForegroundShellAgentAction::ReportReplacementProcess => { + *pending_foreground_shell_clear = false; + *foreground_shell_exit_reported = false; + agent_presence.observe_process_probe(previous_agent); + true + } + ForegroundShellAgentAction::ReportProcessExit => { + *pending_foreground_shell_clear = true; + false + } + ForegroundShellAgentAction::ClearAgent => { + *pending_foreground_shell_clear = false; + *foreground_shell_exit_reported = false; + agent_presence.clear_current_agent() + } + ForegroundShellAgentAction::ObserveProbe => { + *pending_foreground_shell_clear = false; + *foreground_shell_exit_reported = false; + agent_presence.observe_process_probe(new_agent) + } + } +} + #[derive(Debug, Clone, Copy)] struct ProcessProbeInput { current_agent: Option<Agent>, @@ -680,27 +721,20 @@ fn spawn_basic_detection_task( } } let previous_agent = agent_presence.current_agent(); - let changed = match foreground_shell_agent_action( + let foreground_action = foreground_shell_agent_action( previous_agent, new_agent, foreground_is_pane_shell, foreground_shell_exit_reported, - ) { - ForegroundShellAgentAction::ReportProcessExit => { - pending_foreground_shell_clear = true; - false - } - ForegroundShellAgentAction::ClearAgent => { - pending_foreground_shell_clear = false; - foreground_shell_exit_reported = false; - agent_presence.clear_current_agent() - } - ForegroundShellAgentAction::ObserveProbe => { - pending_foreground_shell_clear = false; - foreground_shell_exit_reported = false; - agent_presence.observe_process_probe(new_agent) - } - }; + ); + let changed = apply_foreground_shell_agent_action( + &mut agent_presence, + foreground_action, + previous_agent, + new_agent, + &mut pending_foreground_shell_clear, + &mut foreground_shell_exit_reported, + ); if new_agent.is_some() { last_foreground_pgid = process_group_id.or(foreground_pgid); acquisition_started_at = None; @@ -715,7 +749,9 @@ fn spawn_basic_detection_task( } if changed { agent = agent_presence.current_agent(); - agent_changed = previous_agent != agent; + agent_changed = previous_agent != agent + || foreground_action + == ForegroundShellAgentAction::ReportReplacementProcess; if agent_changed { pending_idle.clear(); last_screen_scan_detection_content_seq = None; @@ -2105,27 +2141,20 @@ impl PaneRuntime { } let previous_agent = agent_presence.current_agent(); - let changed = match foreground_shell_agent_action( + let foreground_action = foreground_shell_agent_action( previous_agent, new_agent, foreground_is_pane_shell, foreground_shell_exit_reported, - ) { - ForegroundShellAgentAction::ReportProcessExit => { - pending_foreground_shell_clear = true; - false - } - ForegroundShellAgentAction::ClearAgent => { - pending_foreground_shell_clear = false; - foreground_shell_exit_reported = false; - agent_presence.clear_current_agent() - } - ForegroundShellAgentAction::ObserveProbe => { - pending_foreground_shell_clear = false; - foreground_shell_exit_reported = false; - agent_presence.observe_process_probe(new_agent) - } - }; + ); + let changed = apply_foreground_shell_agent_action( + &mut agent_presence, + foreground_action, + previous_agent, + new_agent, + &mut pending_foreground_shell_clear, + &mut foreground_shell_exit_reported, + ); if new_agent.is_some() { last_foreground_pgid = process_group_id; acquisition_started_at = None; @@ -2142,7 +2171,10 @@ impl PaneRuntime { } if changed { agent = agent_presence.current_agent(); - if agent != previous_agent { + if agent != previous_agent + || foreground_action + == ForegroundShellAgentAction::ReportReplacementProcess + { pending_idle.clear(); last_screen_scan_detection_content_seq = None; // A new foreground agent must not inherit OSC @@ -3370,6 +3402,14 @@ mod tests { } #[test] + fn same_agent_after_reported_exit_is_a_replacement_process() { + assert_eq!( + foreground_shell_agent_action(Some(Agent::Pi), Some(Agent::Pi), false, true), + ForegroundShellAgentAction::ReportReplacementProcess + ); + } + + #[test] fn unknown_non_shell_foreground_job_is_not_immediate_clear_signal() { assert_eq!( foreground_shell_agent_action(Some(Agent::Claude), None, false, false), @@ -3388,7 +3428,7 @@ mod tests { #[test] fn foreground_agent_job_is_not_clear_signal() { assert_eq!( - foreground_shell_agent_action(Some(Agent::Claude), Some(Agent::OpenCode), true, false), + foreground_shell_agent_action(Some(Agent::Claude), Some(Agent::OpenCode), true, false,), ForegroundShellAgentAction::ObserveProbe ); } |
