-
Notifications
You must be signed in to change notification settings - Fork 2k
fix(extension): allow killing detached processes #5167
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
🦋 Changeset detectedLatest commit: 3d23a26 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
@hdcodedev I can't really reproduce this with the CLI. Do you have a better example todo so? |
|
I'll test more today and update you with the results. |
Pull request was converted to draft
|
@marius-kilocode You're right,
Update: I verified this fix in the VS Code extension. I haven't checked if a similar issue affects the @kilocode/cli |
| // Listening state does not reflect process liveness. | ||
| const terminal = this.terminalRef.deref() | ||
| terminal?.terminal?.sendText("\x03") | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this change is needed
When a user clicks “Proceed/Continue,” we intentionally stop listening to terminal output so the UI stays quiet. That sets isListening = false and removes the line listeners, but the process is still running.
The kill button calls abort(), and the old guard (if (isListening)) meant we never sent Ctrl‑C after Continue. That’s why the kill button looked like a no‑op.
What this fixes
We now send Ctrl‑C unconditionally on user‑initiated abort. Listening state is about UI streaming, not process liveness. This makes “Kill” work even after “Proceed/Continue,” which matches user intent and doesn’t affect normal execution.
| // Don't clear if running in background - user may still want to kill it | ||
| if (!runInBackground) { | ||
| task.terminalProcess = undefined | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why keep task.terminalProcess when running in background
When the user clicks “Proceed/Continue,” we allow the command to keep running in the terminal. At that point the promise resolves and we enter finally, which used to clear task.terminalProcess.
That wiped the only handle the kill button uses, so later aborts did nothing even though the process was still alive.
By only clearing the reference when not running in background, we keep the handle around so the kill button can still terminate the process after “Proceed/Continue.”
kevinvandijk
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lgtm! Thanks!
Context
Fixes #2653
The "Kill Command" button would fail to terminate a process if the user had previously clicked "Proceed While Running". This occurred due to two issues:
TerminalProcess.abort()checkedisListening: The termination signal (\x03) was only sent ifisListeningwas true. Clicking "Proceed While Running" callscontinue(), which setsisListeningto false.task.terminalProcesswas cleared too early: When "Proceed While Running" is clicked,process.continue()emits a "continue" event which resolves the process promise. This triggered thefinallyblock inexecuteCommandInTerminal()which settask.terminalProcess = undefined, making subsequent kill attempts do nothing.Implementation
TerminalProcess.tsif (this.isListening)check fromabort(). The termination signal is now sent unconditionally.terminalRef.deref()) to prevent crashes if the terminal has been garbage collected.ExecuteCommandTool.tsif (!runInBackground)check before clearingtask.terminalProcessin the finally blocks.Tests
abort()works aftercontinue()is called.sendTextis called exactly once to avoid signal spamming.abort()doesn't throw if terminal is undefined.vi.clearAllMocks()tobeforeEachto ensure clean state between tests.How to Test
Start Kilo Code and ask it to run a long-running command that produces output:
Click "Run" to approve the command.
Wait for output to appear, then click "Proceed While Running".
Click the ⊗ (kill) button next to the PID.
Verify: The terminal process terminates successfully.
ps -p <PID>- should show no processDemo
Before (Bug)
2653-bug.mp4
After (Fix)
2653-fix.mp4