Merge pull request #89 from mmereu/master

fix: prevent agent subprocess blocking on Windows
This commit is contained in:
Leon van Zyl
2026-01-29 10:54:12 +02:00
committed by GitHub
3 changed files with 34 additions and 18 deletions

View File

@@ -504,14 +504,20 @@ class ParallelOrchestrator:
cmd.append("--yolo") cmd.append("--yolo")
try: try:
proc = subprocess.Popen( # CREATE_NO_WINDOW on Windows prevents console window pop-ups
cmd, # stdin=DEVNULL prevents blocking on stdin reads
stdout=subprocess.PIPE, popen_kwargs = {
stderr=subprocess.STDOUT, "stdin": subprocess.DEVNULL,
text=True, "stdout": subprocess.PIPE,
cwd=str(AUTOCODER_ROOT), "stderr": subprocess.STDOUT,
env={**os.environ, "PYTHONUNBUFFERED": "1"}, "text": True,
) "cwd": str(AUTOCODER_ROOT), # Run from autocoder root for proper imports
"env": {**os.environ, "PYTHONUNBUFFERED": "1"},
}
if sys.platform == "win32":
popen_kwargs["creationflags"] = subprocess.CREATE_NO_WINDOW
proc = subprocess.Popen(cmd, **popen_kwargs)
except Exception as e: except Exception as e:
# Reset in_progress on failure # Reset in_progress on failure
session = self.get_session() session = self.get_session()
@@ -703,6 +709,12 @@ class ParallelOrchestrator:
print(f"[Feature #{feature_id}] {line}", flush=True) print(f"[Feature #{feature_id}] {line}", flush=True)
proc.wait() proc.wait()
finally: finally:
# CRITICAL: Kill the process tree to clean up any child processes (e.g., Claude CLI)
# This prevents zombie processes from accumulating
try:
_kill_process_tree(proc, timeout=2.0)
except Exception as e:
debug_log.log("CLEANUP", f"Error killing process tree for {agent_type} agent", error=str(e))
self._on_agent_complete(feature_id, proc.returncode, agent_type, proc) self._on_agent_complete(feature_id, proc.returncode, agent_type, proc)
def _signal_agent_completed(self): def _signal_agent_completed(self):

View File

@@ -349,14 +349,20 @@ class AgentProcessManager:
try: try:
# Start subprocess with piped stdout/stderr # Start subprocess with piped stdout/stderr
# Use project_dir as cwd so Claude SDK sandbox allows access to project files # Use project_dir as cwd so Claude SDK sandbox allows access to project files
# IMPORTANT: Set PYTHONUNBUFFERED to ensure output isn't delayed # stdin=DEVNULL prevents blocking if Claude CLI or child process tries to read stdin
self.process = subprocess.Popen( # CREATE_NO_WINDOW on Windows prevents console window pop-ups
cmd, # PYTHONUNBUFFERED ensures output isn't delayed
stdout=subprocess.PIPE, popen_kwargs = {
stderr=subprocess.STDOUT, "stdin": subprocess.DEVNULL,
cwd=str(self.project_dir), "stdout": subprocess.PIPE,
env={**os.environ, "PYTHONUNBUFFERED": "1"}, "stderr": subprocess.STDOUT,
) "cwd": str(self.project_dir),
"env": {**os.environ, "PYTHONUNBUFFERED": "1"},
}
if sys.platform == "win32":
popen_kwargs["creationflags"] = subprocess.CREATE_NO_WINDOW
self.process = subprocess.Popen(cmd, **popen_kwargs)
# Atomic lock creation - if it fails, another process beat us # Atomic lock creation - if it fails, another process beat us
if not self._create_lock(): if not self._create_lock():

View File

@@ -39,5 +39,3 @@ pip install -r requirements.txt --quiet
REM Run the Python launcher REM Run the Python launcher
python "%~dp0start_ui.py" %* python "%~dp0start_ui.py" %*
pause