Skip to content

fix(windows): suppress console window flashes in env probes, lazy installs, and platform.win32_ver() - #67690

Closed
m4r13y wants to merge 1 commit into
NousResearch:mainfrom
m4r13y:fix/windows-console-flash-suppression
Closed

fix(windows): suppress console window flashes in env probes, lazy installs, and platform.win32_ver()#67690
m4r13y wants to merge 1 commit into
NousResearch:mainfrom
m4r13y:fix/windows-console-flash-suppression

Conversation

@m4r13y

@m4r13y m4r13y commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Three Windows console-window-flash fixes, all hit from windowless processes (a pythonw gateway and every kanban worker it spawns). Each worker start was flashing a burst of visible console windows on the user's desktop.

  1. tools/env_probe.py_run() called subprocess.run without creationflags. The probe sequence (python3 / python / pip / python3 -m pip / PEP-668 check) is ~5 spawns per worker start, each flashing a console. Now passes creationflags=windows_hide_flags().

  2. tools/lazy_deps.py — four spawn sites with the same defect (uv pip install, the pip --version probe, ensurepip, and the pip-install fallback). Same fix.

  3. platform.win32_ver() / _syscmd_ver() — CPython 3.11's platform.win32_ver() unconditionally calls _syscmd_ver(), which runs cmd /c ver via subprocess.check_output(shell=True) with no window suppression. Any dependency that merely touches platform.uname()/version()/platform() at import time flashes one cmd window per windowless process. New _subprocess_compat.suppress_platform_ver_console() helper (Windows-only, wrapped in try/except, no-op on POSIX) stubs platform._syscmd_ver so win32_ver() takes its documented fallback to sys.getwindowsversion().platform_version. Called at the very top of hermes_cli/main.py, right after the hermes_bootstrap import guard, before heavyweight imports.

windows_hide_flags() returns CREATE_NO_WINDOW on Windows and 0 on POSIX, and — unlike the detach flags — keeps stdio inherited, so capture_output=True in all touched call sites keeps working.

Verification

  • platform.platform() output is byte-identical with the stub active on CPython 3.11 / Windows 11 (Windows-10-10.0.26100-SP0 either way; the fallback reads the same build number in-process via sys.getwindowsversion()).
  • Flash detection was done by polling EnumWindows at ~15 ms and attributing new visible HWNDs to the suspect process tree — note that a conhost.exe child is not evidence of a visible window (it appears even with CREATE_NO_WINDOW), so control runs with/without the flag were used.
  • Tests on Windows 11: tests/tools/test_windows_native_support.py, test_env_probe.py, test_lazy_deps.py, test_lazy_deps_durable_target.py153 passed, 1 skipped. The 3 failures (test_no_op_on_posix, test_getattr_fallback_prefers_sigkill_when_present, test_readonly_target_reports_error) reproduce identically on a pristine upstream/main checkout in the same environment — pre-existing POSIX-only assertions and NTFS chmod semantics, unrelated to this change.

🤖 Generated with Claude Code

…talls, and platform.win32_ver()

From windowless processes (the pythonw gateway and the kanban workers it
spawns), three spawn paths flash visible console windows on Windows:

1. tools/env_probe.py::_run() ran its interpreter/pip probes
   (python3 / python / pip / 'python3 -m pip' / PEP-668 check, ~5 per
   worker start) without creationflags — one console flash per probe.

2. tools/lazy_deps.py had four spawn sites with the same defect:
   'uv pip install', the 'pip --version' probe, ensurepip, and the
   pip install fallback.

Both now pass creationflags=windows_hide_flags() (CREATE_NO_WINDOW on
Windows, 0 on POSIX) — stdio capture still works because the child is
hidden, not detached.

3. CPython 3.11's platform.win32_ver() unconditionally calls
   _syscmd_ver(), which runs 'cmd /c ver' via
   subprocess.check_output(shell=True) with no window suppression. Any
   dependency touching platform.uname()/version()/platform() at import
   time flashes one 'cmd' window per windowless process. New helper
   _subprocess_compat.suppress_platform_ver_console() (Windows-only,
   never raises) stubs platform._syscmd_ver so win32_ver() falls back to
   sys.getwindowsversion().platform_version — verified byte-identical
   platform.platform() output on CPython 3.11
   ('Windows-10-10.0.26100-SP0' either way). Called at the top of
   hermes_cli/main.py, right after the hermes_bootstrap guard, before
   heavyweight imports.

Verified on Windows 11 by polling EnumWindows at ~15 ms and attributing
new visible HWNDs to the suspect process tree (conhost child presence is
NOT evidence of a visible window — it appears even with
CREATE_NO_WINDOW). Tests: tests/tools/test_windows_native_support.py,
test_env_probe.py, test_lazy_deps.py, test_lazy_deps_durable_target.py —
153 passed; the 3 failures are pre-existing on upstream/main in a
Windows environment (POSIX-only assertions and NTFS chmod semantics).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@alt-glitch alt-glitch added type/bug Something isn't working comp/cli CLI entry point, hermes_cli/, setup wizard comp/tools Tool registry, model_tools, toolsets platform/windows Native Windows-specific behavior or breakage P2 Medium — degraded but workaround exists needs-decision Awaiting maintainer decision before any implementation sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows labels Jul 19, 2026
teknium1 added a commit that referenced this pull request Jul 23, 2026
…run + add no-window tests (#67690 follow-up)

Follow-up to the #67690 salvage (@m4r13y). The PR's tools/env_probe.py
hunk was written against the old capture_output=True _run(); #67964/#67999
rewrote _run to temp-file capture on July 20, so that hunk no longer
applied — but the rewritten _run still lacked creationflags and kept
flashing one console per probe (~5 per kanban worker start) from
windowless parents. Re-implement the one-line fix against the current
shape: creationflags=windows_hide_flags() on the temp-file subprocess.run,
preserving the #67964 grandchild-can't-wedge-the-pipe contract.

Also add the tests the PR didn't ship, in
tests/test_windows_subprocess_no_window_flags.py:
- env_probe._run passes CREATE_NO_WINDOW and keeps temp-file (non-PIPE)
  stdout/stderr + DEVNULL stdin
- lazy_deps uv install / pip --version probe / pip install fallback /
  ensurepip bootstrap all pass CREATE_NO_WINDOW
- suppress_platform_ver_console: POSIX no-op (platform._syscmd_ver
  untouched, win32_ver() still returns), and simulated-Windows stubbing
  (echo stub installed, idempotent, never raises)
teknium1 added a commit that referenced this pull request Jul 24, 2026
…run + add no-window tests (#67690 follow-up)

Follow-up to the #67690 salvage (@m4r13y). The PR's tools/env_probe.py
hunk was written against the old capture_output=True _run(); #67964/#67999
rewrote _run to temp-file capture on July 20, so that hunk no longer
applied — but the rewritten _run still lacked creationflags and kept
flashing one console per probe (~5 per kanban worker start) from
windowless parents. Re-implement the one-line fix against the current
shape: creationflags=windows_hide_flags() on the temp-file subprocess.run,
preserving the #67964 grandchild-can't-wedge-the-pipe contract.

Also add the tests the PR didn't ship, in
tests/test_windows_subprocess_no_window_flags.py:
- env_probe._run passes CREATE_NO_WINDOW and keeps temp-file (non-PIPE)
  stdout/stderr + DEVNULL stdin
- lazy_deps uv install / pip --version probe / pip install fallback /
  ensurepip bootstrap all pass CREATE_NO_WINDOW
- suppress_platform_ver_console: POSIX no-op (platform._syscmd_ver
  untouched, win32_ver() still returns), and simulated-Windows stubbing
  (echo stub installed, idempotent, never raises)
teknium1 added a commit that referenced this pull request Jul 24, 2026
…run + add no-window tests (#67690 follow-up)

Follow-up to the #67690 salvage (@m4r13y). The PR's tools/env_probe.py
hunk was written against the old capture_output=True _run(); #67964/#67999
rewrote _run to temp-file capture on July 20, so that hunk no longer
applied — but the rewritten _run still lacked creationflags and kept
flashing one console per probe (~5 per kanban worker start) from
windowless parents. Re-implement the one-line fix against the current
shape: creationflags=windows_hide_flags() on the temp-file subprocess.run,
preserving the #67964 grandchild-can't-wedge-the-pipe contract.

Also add the tests the PR didn't ship, in
tests/test_windows_subprocess_no_window_flags.py:
- env_probe._run passes CREATE_NO_WINDOW and keeps temp-file (non-PIPE)
  stdout/stderr + DEVNULL stdin
- lazy_deps uv install / pip --version probe / pip install fallback /
  ensurepip bootstrap all pass CREATE_NO_WINDOW
- suppress_platform_ver_console: POSIX no-op (platform._syscmd_ver
  untouched, win32_ver() still returns), and simulated-Windows stubbing
  (echo stub installed, idempotent, never raises)
@teknium1

Copy link
Copy Markdown
Contributor

Merged via PR #70264 — your commit was cherry-picked onto current main with authorship preserved (rebase-merge). The suppress_platform_ver_console() stub, the early startup call, and all four lazy_deps sites landed as you wrote them; we re-fitted the env_probe hunk onto the temp-file _run that was rewritten after you filed (and added mocked tests). Nice catch on the stdlib win32_ver() subprocess — verified against the CPython 3.11 source during review.

randlee pushed a commit to randlee/hermes-agent that referenced this pull request Aug 11, 2026
…run + add no-window tests (NousResearch#67690 follow-up)

Follow-up to the NousResearch#67690 salvage (@m4r13y). The PR's tools/env_probe.py
hunk was written against the old capture_output=True _run(); NousResearch#67964/NousResearch#67999
rewrote _run to temp-file capture on July 20, so that hunk no longer
applied — but the rewritten _run still lacked creationflags and kept
flashing one console per probe (~5 per kanban worker start) from
windowless parents. Re-implement the one-line fix against the current
shape: creationflags=windows_hide_flags() on the temp-file subprocess.run,
preserving the NousResearch#67964 grandchild-can't-wedge-the-pipe contract.

Also add the tests the PR didn't ship, in
tests/test_windows_subprocess_no_window_flags.py:
- env_probe._run passes CREATE_NO_WINDOW and keeps temp-file (non-PIPE)
  stdout/stderr + DEVNULL stdin
- lazy_deps uv install / pip --version probe / pip install fallback /
  ensurepip bootstrap all pass CREATE_NO_WINDOW
- suppress_platform_ver_console: POSIX no-op (platform._syscmd_ver
  untouched, win32_ver() still returns), and simulated-Windows stubbing
  (echo stub installed, idempotent, never raises)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/cli CLI entry point, hermes_cli/, setup wizard comp/tools Tool registry, model_tools, toolsets needs-decision Awaiting maintainer decision before any implementation P2 Medium — degraded but workaround exists platform/windows Native Windows-specific behavior or breakage sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants