fix(windows): hide console flashes from LSP server spawn and installer subprocesses

Salvaged from PR #47971 (LSP subset). On Windows, .cmd-wrapped language
servers (e.g. pyright-langserver.CMD launched via cmd.exe /c) and the
npm/go/pip LSP auto-installers spawn without CREATE_NO_WINDOW, so a
console window flashes whenever the spawn happens under a console-less
parent — e.g. a VS Code/Zed extension host running the ACP adapter.

- agent/lsp/client.py::_spawn: pass creationflags=windows_hide_flags()
  to the language-server asyncio subprocess (inert 0 on POSIX;
  start_new_session is kept — it is POSIX-only and ignored on Windows).
- agent/lsp/install.py: same flags on the npm and go installer
  subprocess.run calls. The pip path goes through
  hermes_cli.tools_config._pip_install, which already hides its windows.

Adapted from the PR's hand-rolled _NO_WINDOW constant to the repo's
hermes_cli._subprocess_compat.windows_hide_flags() convention.
This commit is contained in:
hellofrommorgan 2026-07-23 12:22:22 -07:00 committed by Teknium
parent 30bb55588f
commit d6ffe3d767
3 changed files with 14 additions and 0 deletions

View file

@ -56,6 +56,8 @@ from pathlib import Path
from typing import Any, Awaitable, Callable, Dict, List, Optional, Set
from urllib.parse import quote, unquote
from hermes_cli._subprocess_compat import windows_hide_flags
from agent.lsp.protocol import (
ERROR_CONTENT_MODIFIED,
ERROR_METHOD_NOT_FOUND,
@ -294,6 +296,12 @@ class LSPClient:
cmd = self._command
if sys.platform == "win32":
cmd = self._win_wrap_cmd(cmd)
# Suppress the cmd.exe console window that would otherwise flash
# every time we launch a ``.cmd``-wrapped language server
# (e.g. pyright-langserver.CMD) from a console-less host such as
# a VS Code/Zed extension running the ACP adapter.
# windows_hide_flags() is CREATE_NO_WINDOW on Windows, 0 on POSIX.
creationflags = windows_hide_flags()
try:
# start_new_session=True detaches the LSP server into its own
@ -312,6 +320,7 @@ class LSPClient:
env=env,
cwd=self._cwd,
start_new_session=True,
creationflags=creationflags,
)
except FileNotFoundError as e:
raise LSPProtocolError(

View file

@ -35,6 +35,8 @@ import threading
from pathlib import Path
from typing import Any, Dict, Optional
from hermes_cli._subprocess_compat import windows_hide_flags
logger = logging.getLogger("agent.lsp.install")
# Package-name → install-strategy hint registry. Each entry is a
@ -268,6 +270,7 @@ def _install_npm(
text=True,
timeout=300,
stdin=subprocess.DEVNULL,
creationflags=windows_hide_flags(),
)
if proc.returncode != 0:
logger.warning(
@ -317,6 +320,7 @@ def _install_go(pkg: str, bin_name: str) -> Optional[str]:
timeout=600,
env=env,
stdin=subprocess.DEVNULL,
creationflags=windows_hide_flags(),
)
if proc.returncode != 0:
logger.warning(

View file

@ -0,0 +1 @@
hellofrommorgan