Merge pull request #520 from Kilo-Org/fix/fix-orphan-sub-agents

fix: Close sub-agents, preventing them from becoming orphan processes
This commit is contained in:
Marian Alexandru Alecu
2026-02-20 18:14:37 +02:00
committed by GitHub
4 changed files with 43 additions and 5 deletions
+16 -2
View File
@@ -2,6 +2,7 @@ import { Server } from "../../server/server"
import { cmd } from "./cmd"
import { withNetworkOptions, resolveNetworkOptions } from "../network"
import { Flag } from "../../flag/flag"
import { Instance } from "../../project/instance" // kilocode_change
export const ServeCommand = cmd({
command: "serve",
@@ -14,7 +15,20 @@ export const ServeCommand = cmd({
const opts = await resolveNetworkOptions(args)
const server = Server.listen(opts)
console.log(`kilo server listening on http://${server.hostname}:${server.port}`) // kilocode_change
await new Promise(() => {})
await server.stop()
// kilocode_change start - graceful signal shutdown
const abort = new AbortController()
const shutdown = async () => {
try {
await Instance.disposeAll()
await server.stop(true)
} finally {
abort.abort()
}
}
process.on("SIGTERM", shutdown)
process.on("SIGINT", shutdown)
process.on("SIGHUP", shutdown)
await new Promise((resolve) => abort.signal.addEventListener("abort", resolve))
// kilocode_change end
},
})
@@ -127,6 +127,13 @@ export const TuiThreadCommand = cmd({
process.on("SIGUSR2", async () => {
await client.call("reload", undefined)
})
// kilocode_change start - graceful shutdown on external signals
const shutdown = async () => {
await client.call("shutdown", undefined).catch(() => {})
}
process.on("SIGHUP", shutdown)
process.on("SIGTERM", shutdown)
// kilocode_change end
const prompt = await iife(async () => {
const piped = !process.stdin.isTTY ? await Bun.stdin.text() : undefined
+16 -2
View File
@@ -3,6 +3,7 @@ import { UI } from "../ui"
import { cmd } from "./cmd"
import { withNetworkOptions, resolveNetworkOptions } from "../network"
import { Flag } from "../../flag/flag"
import { Instance } from "../../project/instance" // kilocode_change
import open from "open"
import { networkInterfaces } from "os"
@@ -75,7 +76,20 @@ export const WebCommand = cmd({
open(displayUrl).catch(() => {})
}
await new Promise(() => {})
await server.stop()
// kilocode_change start - graceful signal shutdown
const abort = new AbortController()
const shutdown = async () => {
try {
await Instance.disposeAll()
await server.stop(true)
} finally {
abort.abort()
}
}
process.on("SIGTERM", shutdown)
process.on("SIGINT", shutdown)
process.on("SIGHUP", shutdown)
await new Promise((resolve) => abort.signal.addEventListener("abort", resolve))
// kilocode_change end
},
})
+4 -1
View File
@@ -26,8 +26,9 @@ import { EOL } from "os"
import { WebCommand } from "./cli/cmd/web"
import { PrCommand } from "./cli/cmd/pr"
import { SessionCommand } from "./cli/cmd/session"
// kilocode_change start - Import telemetry and legacy migration
// kilocode_change start - Import telemetry, instance disposal, and legacy migration
import { Telemetry } from "@kilocode/kilo-telemetry"
import { Instance } from "./project/instance" // kilocode_change
import { migrateLegacyKiloAuth, ENV_FEATURE } from "@kilocode/kilo-gateway"
// kilocode_change - set feature for tracking. 'serve' is spawned by other services
@@ -197,6 +198,8 @@ try {
await Telemetry.shutdown()
// kilocode_change end
await Instance.disposeAll() // kilocode_change - safety net disposal (no-op if already disposed)
// Some subprocesses don't react properly to SIGTERM and similar signals.
// Most notably, some docker-container-based MCP servers don't handle such signals unless
// run using `docker run --init`.