From 15f52696b9067a2e8b2517ac05157b57ae64d2ef Mon Sep 17 00:00:00 2001 From: Saoud Rizwan <7799382+saoudrizwan@users.noreply.github.com> Date: Fri, 2 Aug 2024 18:01:44 -0400 Subject: [PATCH] Fix sending SIGINT to the command process's subprocesses --- package-lock.json | 9 +++++++++ package.json | 1 + src/ClaudeDev.ts | 11 ++++++++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 2769529..dc85af3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "os-name": "^6.0.0", "p-wait-for": "^5.0.2", "serialize-error": "^11.0.3", + "tree-kill": "^1.2.2", "tree-sitter-wasms": "^0.1.11", "web-tree-sitter": "^0.22.6" }, @@ -5616,6 +5617,14 @@ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "license": "MIT" }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "bin": { + "tree-kill": "cli.js" + } + }, "node_modules/tree-sitter-wasms": { "version": "0.1.11", "resolved": "https://registry.npmjs.org/tree-sitter-wasms/-/tree-sitter-wasms-0.1.11.tgz", diff --git a/package.json b/package.json index 9808420..f96e6d6 100644 --- a/package.json +++ b/package.json @@ -131,6 +131,7 @@ "os-name": "^6.0.0", "p-wait-for": "^5.0.2", "serialize-error": "^11.0.3", + "tree-kill": "^1.2.2", "tree-sitter-wasms": "^0.1.11", "web-tree-sitter": "^0.22.6" } diff --git a/src/ClaudeDev.ts b/src/ClaudeDev.ts index 338a64e..75caf49 100644 --- a/src/ClaudeDev.ts +++ b/src/ClaudeDev.ts @@ -16,6 +16,7 @@ import { DEFAULT_MAX_REQUESTS_PER_TASK } from "./shared/Constants" import { ClaudeAsk, ClaudeMessage, ClaudeSay, ClaudeSayTool } from "./shared/ExtensionMessage" import { Tool, ToolName } from "./shared/Tool" import { ClaudeAskResponse } from "./shared/WebviewMessage" +import treeKill from "tree-kill" const SYSTEM_PROMPT = () => `You are Claude Dev, a highly skilled software developer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices. @@ -627,7 +628,15 @@ export class ClaudeDev { // if this ask promise is not ignored, that means the user responded to it somehow either by clicking primary button or by typing text if (response === "yesButtonTapped") { // SIGINT is typically what's sent when a user interrupts a process (like pressing Ctrl+C) - subprocess.kill("SIGINT") // will result in for loop throwing error + /* + .kill sends SIGINT by default. However by not passing any options into .kill(), execa internally sends a SIGKILL after a grace period if the SIGINT failed. + however it turns out that even this isn't enough for certain processes like npm starting servers. therefore we use the tree-kill package to kill all processes in the process tree, including the root process. + - Sends signal to all children processes of the process with pid pid, including pid. Signal defaults to SIGTERM. + */ + if (subprocess.pid) { + //subprocess.kill("SIGINT") // will result in for loop throwing error + treeKill(subprocess.pid, "SIGINT") + } } else { // if the user sent some input, we send it to the command stdin // add newline as cli programs expect a newline after each input