skill-creator run_eval.py: Windows incompatibility — select.select() fails on pipe handles (WinError 10038)
Bug
scripts/run_eval.py uses select.select([process.stdout], [], [], 1.0) to check subprocess stdout readiness. On Windows, select.select() only supports sockets (Winsock), not pipe file handles. This raises [WinError 10038] on every query, causing all trigger evaluations to silently fall back to False (recall = 0% across the entire eval set).
Impact
The description optimization loop (run_loop.py) is completely non-functional on Windows — every iteration reports 0% recall regardless of description quality, making the tool useless for Windows users.
Reproduction
Run on Windows:
python -m scripts.run_loop --eval-set <any-eval-set.json> --skill-path <any-skill> --model claude-sonnet-4-6 --max-iterations 1 --verbose --report none
Expected: eval queries return meaningful trigger rates.
Actual: [WinError 10038] on every query, all trigger rates = 0/3.
Fix
Replace select.select() + os.read() with a background reader thread using queue.Queue. This is cross-platform and works on Windows pipe handles:
import queue as queue_module
import threading
def _reader_thread(stdout, q):
try:
for line in iter(stdout.readline, b''):
q.put(line)
finally:
q.put(None)
# In run_single_query, replace the select loop with:
output_queue = queue_module.Queue()
reader = threading.Thread(target=_reader_thread, args=(process.stdout, output_queue), daemon=True)
reader.start()
while time.time() - start_time < timeout:
try:
chunk = output_queue.get(timeout=0.5)
except queue_module.Empty:
if process.poll() is not None:
break
continue
if chunk is None:
break
line = chunk.decode("utf-8", errors="replace").strip()
# ... rest of event parsing ...
Environment
- Windows 11 Enterprise 10.0.26200
- Python 3.x (PowerShell)
- Claude Code CLI, skill-creator plugin
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗