From 8ae6189c0f092dbd2525ee3614dbf5cd231eda5f Mon Sep 17 00:00:00 2001 From: Auto Date: Thu, 29 Jan 2026 10:56:02 +0200 Subject: [PATCH] fix: apply Windows subprocess fixes to testing agent and initializer Follow-up to PR #89 - apply the same popen_kwargs pattern with stdin=DEVNULL and CREATE_NO_WINDOW to _spawn_testing_agent() and _run_initializer() for consistent Windows behavior. Also fixes typo: _kill_process_tree -> kill_process_tree Co-Authored-By: Claude Opus 4.5 --- parallel_orchestrator.py | 46 +++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/parallel_orchestrator.py b/parallel_orchestrator.py index 60b4489..ab28ae6 100644 --- a/parallel_orchestrator.py +++ b/parallel_orchestrator.py @@ -593,14 +593,20 @@ class ParallelOrchestrator: cmd.extend(["--model", self.model]) try: - proc = subprocess.Popen( - cmd, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - text=True, - cwd=str(AUTOCODER_ROOT), - env={**os.environ, "PYTHONUNBUFFERED": "1"}, - ) + # CREATE_NO_WINDOW on Windows prevents console window pop-ups + # stdin=DEVNULL prevents blocking on stdin reads + popen_kwargs = { + "stdin": subprocess.DEVNULL, + "stdout": subprocess.PIPE, + "stderr": subprocess.STDOUT, + "text": True, + "cwd": str(AUTOCODER_ROOT), + "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: debug_log.log("TESTING", f"FAILED to spawn testing agent: {e}") return False, f"Failed to start testing agent: {e}" @@ -644,14 +650,20 @@ class ParallelOrchestrator: print("Running initializer agent...", flush=True) - proc = subprocess.Popen( - cmd, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - text=True, - cwd=str(AUTOCODER_ROOT), - env={**os.environ, "PYTHONUNBUFFERED": "1"}, - ) + # CREATE_NO_WINDOW on Windows prevents console window pop-ups + # stdin=DEVNULL prevents blocking on stdin reads + popen_kwargs = { + "stdin": subprocess.DEVNULL, + "stdout": subprocess.PIPE, + "stderr": subprocess.STDOUT, + "text": True, + "cwd": str(AUTOCODER_ROOT), + "env": {**os.environ, "PYTHONUNBUFFERED": "1"}, + } + if sys.platform == "win32": + popen_kwargs["creationflags"] = subprocess.CREATE_NO_WINDOW + + proc = subprocess.Popen(cmd, **popen_kwargs) debug_log.log("INIT", "Initializer subprocess started", pid=proc.pid) @@ -712,7 +724,7 @@ class ParallelOrchestrator: # 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) + 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)