fix(workspace-git): hide git subprocess console windows on Windows (#5692)

Add creationflags to _run_git() and _config_names_for_scope() so git
child processes don't accumulate hidden cmd.exe/conhost windows on Windows.

Uses a local module-level _windows_hide_flags() helper (mirrors the
api/updates.py pattern: CREATE_NO_WINDOW on win32, 0 elsewhere) rather than
importing from the OPTIONAL hermes_cli package — a standalone/agent-less
WebUI (and the repo's own CI runners, which don't pip-install hermes-agent)
must keep full workspace-git functionality. windows_hide_flags() is a safe
no-op (0) on non-Windows. Scoped to workspace git commands.

Adds mutation-checked tests asserting the kwarg is wired on both sites.

Co-authored-by: nesquena-hermes <nesquena-hermes@users.noreply.github.com>
This commit is contained in:
Jinho Seokandnesquena-hermes committed 2026-07-07 02:07:39 +00:00
1 parent 8fee7da3ee
commit f106fcd1f5
2 files changed
+75

No files matched your search

+17
View File
@@ -12,6 +12,7 @@ import logging
import os
import shutil
import subprocess
import sys
import tempfile
import threading
import re
@@ -22,6 +23,20 @@ from typing import Iterable
logger = logging.getLogger(__name__)
def _windows_hide_flags() -> int:
"""Win32 ``creationflags`` that hide a short-lived console child's window
(``CREATE_NO_WINDOW``) without detaching it, so ``capture_output`` still
works. Returns ``0`` on non-Windows — the ``subprocess`` default, a genuine
no-op. Mirrors the ``api/updates.py`` pattern; kept local so workspace-git
never takes a hard dependency on the optional ``hermes_cli`` package (a
standalone/agent-less WebUI must keep full git functionality). See #5692.
"""
if sys.platform == "win32":
return getattr(subprocess, "CREATE_NO_WINDOW", 0)
return 0
from api.workspace import rmtree_anchored, safe_resolve_ws, unlink_anchored
@@ -248,6 +263,7 @@ def _run_git(
text=True,
timeout=timeout,
env=run_env,
creationflags=_windows_hide_flags(),
)
except subprocess.TimeoutExpired as exc:
raise GitWorkspaceError("Git command timed out", "timeout") from exc
@@ -290,6 +306,7 @@ def _config_names_for_scope(
capture_output=True,
timeout=GIT_TIMEOUT,
env=env,
creationflags=_windows_hide_flags(),
)
if result.returncode not in {0, 1}:
if ignore_unsupported: