Issue
In dist/self_command.js (line 247-251), run_long_command spawns a child process but does NOT call child.unref():
const child = spawn(command, {
shell: true,
detached: true,
stdio: ['ignore', 'pipe', 'pipe'],
});
// ❌ missing: child.unref()
All other tools in the same file consistently call subprocess.unref() after spawn:
wait_for_idle (line 55): subprocess.unref() ✅
self_command (line 95): subprocess.unref() ✅
gemini_sleep (line 414): subprocess.unref() ✅
watch_log (line 466): subprocess.unref() ✅
Impact
Without unref(), the long-running child process keeps the Node.js event loop alive, preventing the MCP server from cleanly shutting down while the background command is still running. detached: true alone prevents the child from being killed when the parent exits, but does NOT allow the event loop to exit.
Fix
Add child.unref() after the spawn call to match the pattern used by all other tools.
Found during code review. @toller892.
Issue
In
dist/self_command.js(line 247-251),run_long_commandspawns a child process but does NOT callchild.unref():All other tools in the same file consistently call
subprocess.unref()after spawn:wait_for_idle(line 55):subprocess.unref()✅self_command(line 95):subprocess.unref()✅gemini_sleep(line 414):subprocess.unref()✅watch_log(line 466):subprocess.unref()✅Impact
Without
unref(), the long-running child process keeps the Node.js event loop alive, preventing the MCP server from cleanly shutting down while the background command is still running.detached: truealone prevents the child from being killed when the parent exits, but does NOT allow the event loop to exit.Fix
Add
child.unref()after the spawn call to match the pattern used by all other tools.Found during code review. @toller892.