mirror of
https://github.com/codewhale-hq/Codewhale.git
synced 2026-11-07 17:09:13 -10:00
fix(shell): a self-cancelled job stays quiet, and an exited job keeps its exit
Two session-export defects in the background-shell cancel path:
- Cancelling your own background job also queued its completion
notification. The session then got a "finished" event for a job it had
just killed, and a new model turn could start from it.
`ShellManager::kill` now marks a job it killed as
`completion_reported`, so the completion drain skips it.
- A job that exited between the user's look and the cancel was still
killed and reported as "Killed" with exit 0.
`BackgroundShell::kill` now polls first and returns without signalling
when the process has already finished. The cancel receipt then reports
the real status and exit ("... Nothing was killed.") instead of "Canceled
background command".
Evidence: cargo fmt --all -- --check is clean. The compile and the
tools::shell / tool_cancellation tests are pending a local test build and
hosted CI on codewhale-hq/Codewhale#6957.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01BsXVvReYca2UxzimQtj7Mj
This commit is contained in:
1 file changed
+14
-4
@@ -1586,6 +1586,9 @@ impl BackgroundShell {
|
||||
|
||||
/// Kill the process
|
||||
fn kill(&mut self) -> Result<()> {
|
||||
if self.poll() && self.status != ShellStatus::Running {
|
||||
return Ok(());
|
||||
}
|
||||
#[cfg(unix)]
|
||||
if self.ownership == ShellOwnership::PersistPending
|
||||
&& let Some(process_group_id) = self.child.as_ref().and_then(ShellChild::process_id)
|
||||
@@ -3204,6 +3207,9 @@ impl ShellManager {
|
||||
.ok_or_else(|| anyhow!("Task {task_id} not found"))?;
|
||||
|
||||
shell.kill()?;
|
||||
if shell.status == ShellStatus::Killed {
|
||||
shell.completion_reported = true;
|
||||
}
|
||||
shell.snapshot()
|
||||
}
|
||||
|
||||
@@ -7034,10 +7040,14 @@ impl BashTool {
|
||||
.clone()
|
||||
.unwrap_or_else(|| task_id.to_string());
|
||||
Ok(ToolResult {
|
||||
content: format!(
|
||||
"Canceled background command: {task_id}. {}",
|
||||
kill_outcome_note(&format!("{}{}", result.stdout, result.stderr))
|
||||
),
|
||||
content: if result.status == ShellStatus::Killed {
|
||||
format!(
|
||||
"Canceled background command: {task_id}. {}",
|
||||
kill_outcome_note(&format!("{}{}", result.stdout, result.stderr))
|
||||
)
|
||||
} else {
|
||||
format!("{} Nothing was killed.", wait_timing_line(&result))
|
||||
},
|
||||
success: true,
|
||||
metadata: Some(json!({
|
||||
"status": format!("{:?}", result.status),
|
||||
|
||||
Reference in new issue
Block a user