Cancelling a local tool leaves the processes it started running
- Status: Todo
- Kind: Bug
- Authors: jp
- Date: 2026-10-01
- Label: domain=plugins
- Label: package=jp_cli
- Label: package=jp_mcp
A cancelled local tool call kills only the process JP spawned. run_tool_command puts the child in its own process group (crates/jp_mcp/src/server.rs, cmd.process_group(0)), then relies on kill_on_drop(true), which signals the child's pid, not the group. A tool command that is a shell or a just recipe (every tool under .jp/mcp/tools/ runs just serve-tools ...) has its real work in a grandchild, which survives the cancel and keeps running, writing files, or holding a port.
Tools served by command plugins (source = "plugin.command.<plugin>", T-0vm44ks) are spawned the same way in crates/jp_cli/src/cmd/plugin/tool.rs and have the same gap.
jp <plugin> commands do not: on the plugin-routing branch (PR #1216) they are stopped through ProcessTree, which kills the process group on Unix and the job object on Windows.
Input that hits it: a local tool whose command is sh -c 'sleep 600', cancelled with Ctrl+C mid-call. The sh exits; the sleep is still running afterwards.
Fix: kill the tool's whole tree on cancel, for every subprocess-backed source, reusing ProcessTree once PR #1216 lands. Test with a command that starts a background worker and writes its pid, cancel the call, and assert the worker is gone, as process_tree_tests::terminating_the_tree_kills_what_the_plugin_started does.
Comments
- From: jp
- Date: 2026-10-01T15:15:06Z
#1225 merged jp_process with group-aware stopping: a process spawned with own_process_group is stopped by signalling -pid (SIGINT, then SIGKILL once Watch::grace runs out), even after the leader itself has exited. Command plugin tool calls (T-0vm44ks) run through ProcessRunner with own_process_group = true, so on Unix they are covered once that branch is on main's jp_process. Local tools are covered when run_tool_command moves onto ProcessRunner (#1228 in the #1175 split). Windows still kills only the child: jp_process has no job object.