fix: prevent temp file accumulation during long agent runs

Address three issues reported after overnight AutoForge runs:
1. ~193GB of .node files in %TEMP% from V8 compile caching
2. Stale npm artifact folders on drive root when %TEMP% fills up
3. PNG screenshot files left in project root by Playwright

Changes:
- Widen .node cleanup glob from ".78912*.node" to ".[0-9a-f]*.node"
  to match all V8 compile cache hex prefixes
- Add "node-compile-cache" directory to temp cleanup patterns
- Set NODE_COMPILE_CACHE="" in all subprocess environments (client.py,
  parallel_orchestrator.py, process_manager.py) to disable V8 compile
  caching at the source
- Add cleanup_project_screenshots() to remove stale .png files from
  project directories (feature*-*.png, screenshot-*.png, step-*.png)
- Run cleanup_stale_temp() at server startup in lifespan()
- Add _run_inter_session_cleanup() to orchestrator, called after each
  agent completes (both coding and testing paths)
- Update coding and testing prompt templates to instruct agents to use
  inline (base64) screenshots only, never saving files to disk

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Auto
2026-02-09 08:54:52 +02:00
parent 9eb08d3f71
commit f87970daca
7 changed files with 94 additions and 11 deletions

View File

@@ -846,7 +846,7 @@ class ParallelOrchestrator:
"encoding": "utf-8",
"errors": "replace",
"cwd": str(self.project_dir), # Run from project dir so CLI creates .claude/ in project
"env": {**os.environ, "PYTHONUNBUFFERED": "1"},
"env": {**os.environ, "PYTHONUNBUFFERED": "1", "NODE_COMPILE_CACHE": ""},
}
if sys.platform == "win32":
popen_kwargs["creationflags"] = subprocess.CREATE_NO_WINDOW
@@ -909,7 +909,7 @@ class ParallelOrchestrator:
"encoding": "utf-8",
"errors": "replace",
"cwd": str(self.project_dir), # Run from project dir so CLI creates .claude/ in project
"env": {**os.environ, "PYTHONUNBUFFERED": "1"},
"env": {**os.environ, "PYTHONUNBUFFERED": "1", "NODE_COMPILE_CACHE": ""},
}
if sys.platform == "win32":
popen_kwargs["creationflags"] = subprocess.CREATE_NO_WINDOW
@@ -1013,7 +1013,7 @@ class ParallelOrchestrator:
"encoding": "utf-8",
"errors": "replace",
"cwd": str(self.project_dir), # Run from project dir so CLI creates .claude/ in project
"env": {**os.environ, "PYTHONUNBUFFERED": "1"},
"env": {**os.environ, "PYTHONUNBUFFERED": "1", "NODE_COMPILE_CACHE": ""},
}
if sys.platform == "win32":
popen_kwargs["creationflags"] = subprocess.CREATE_NO_WINDOW
@@ -1074,7 +1074,7 @@ class ParallelOrchestrator:
"encoding": "utf-8",
"errors": "replace",
"cwd": str(AUTOFORGE_ROOT),
"env": {**os.environ, "PYTHONUNBUFFERED": "1"},
"env": {**os.environ, "PYTHONUNBUFFERED": "1", "NODE_COMPILE_CACHE": ""},
}
if sys.platform == "win32":
popen_kwargs["creationflags"] = subprocess.CREATE_NO_WINDOW
@@ -1160,6 +1160,19 @@ class ParallelOrchestrator:
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)
def _run_inter_session_cleanup(self):
"""Run lightweight cleanup between agent sessions.
Removes stale temp files and project screenshots to prevent
disk space accumulation during long overnight runs.
"""
try:
from temp_cleanup import cleanup_project_screenshots, cleanup_stale_temp
cleanup_stale_temp()
cleanup_project_screenshots(self.project_dir)
except Exception as e:
debug_log.log("CLEANUP", f"Inter-session cleanup failed (non-fatal): {e}")
def _signal_agent_completed(self):
"""Signal that an agent has completed, waking the main loop.
@@ -1235,6 +1248,8 @@ class ParallelOrchestrator:
pid=proc.pid,
feature_id=feature_id,
status=status)
# Run lightweight cleanup between sessions
self._run_inter_session_cleanup()
# Signal main loop that an agent slot is available
self._signal_agent_completed()
return
@@ -1301,6 +1316,8 @@ class ParallelOrchestrator:
else:
print(f"Feature #{feature_id} {status}", flush=True)
# Run lightweight cleanup between sessions
self._run_inter_session_cleanup()
# Signal main loop that an agent slot is available
self._signal_agent_completed()