Skip to main content

aft/commands/
bash_kill.rs

1use crate::context::AppContext;
2use crate::protocol::{RawRequest, Response};
3use serde::Deserialize;
4use serde_json::json;
5
6#[derive(Debug, Deserialize)]
7struct BashKillParams {
8    #[serde(default)]
9    task_id: Option<String>,
10}
11
12pub fn handle(req: &RawRequest, ctx: &AppContext) -> Response {
13    let raw_params = req
14        .params
15        .get("params")
16        .cloned()
17        .unwrap_or_else(|| req.params.clone());
18    let params = match serde_json::from_value::<BashKillParams>(raw_params) {
19        Ok(params) => params,
20        Err(e) => {
21            return Response::error(
22                &req.id,
23                "invalid_request",
24                format!("bash_kill: invalid params: {e}"),
25            );
26        }
27    };
28
29    let Some(task_id) = params.task_id else {
30        return Response::error(&req.id, "invalid_request", "bash_kill: missing task_id");
31    };
32
33    let storage_dir = crate::bash_background::storage_dir(ctx.config().storage_dir.as_deref());
34    let result = ctx
35        .bash_background()
36        .kill(&task_id, req.session())
37        .or_else(|message| {
38            if !message.contains("not found") {
39                return Err(message);
40            }
41            let _ = ctx
42                .bash_background()
43                .replay_session(&storage_dir, req.session());
44            ctx.bash_background().kill(&task_id, req.session())
45        })
46        .or_else(|message| {
47            if !message.contains("not found") {
48                return Err(message);
49            }
50            let config = ctx.config();
51            let Some(project_root) = config.project_root.as_deref() else {
52                return Err(message);
53            };
54            ctx.bash_background()
55                .kill_relaxed(&task_id, project_root, &storage_dir)
56        });
57
58    match result {
59        Ok(snapshot) => Response::success(&req.id, json!(snapshot)),
60        Err(message) if message.contains("not found") => {
61            Response::error(&req.id, "task_not_found", message)
62        }
63        Err(message) => Response::error(&req.id, "kill_failed", message),
64    }
65}