mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-04 12:33:08 +00:00
fix(windows): hide console flash on checkpoint git + skills_hub gh probes
The #54236/#54417 backend git/gh sweep routed git_probe, the repo-file picker, coding_context, context_references, copilot_auth, and the gateway process scans through CREATE_NO_WINDOW, but two sibling spawn legs that also run inside the console-less desktop/gateway backend were missed: - tools/checkpoint_manager.py `_run_git` (and the one-shot `git init --bare` in `_init_store`) — when checkpoints are enabled, every file-mutating turn fires multiple bare `git` calls (status, add, write-tree/commit-tree, update-ref). Spawned from a parent with no console (Electron spawns the backend with windowsHide → CREATE_NO_WINDOW), each one allocates its own conhost window → a flurry of terminal popups. - tools/skills_hub.py `GitHubAuth._try_gh_cli` — `gh auth token`, the same bug class as the already-fixed copilot_auth gh probe. Route both through `windows_hide_flags()` (no-op on POSIX), matching the established per-site pattern. Tests added to tests/test_windows_subprocess_no_window_flags.py.
This commit is contained in:
parent
980622d0ec
commit
32087e4bc9
3 changed files with 47 additions and 0 deletions
|
|
@ -300,6 +300,44 @@ def test_local_stt_audio_prep_hides_ffmpeg_window(monkeypatch, tmp_path):
|
|||
assert captured[0][0][0] == "ffmpeg"
|
||||
assert captured[0][1]["creationflags"] == _CREATE_NO_WINDOW
|
||||
|
||||
def test_checkpoint_manager_git_hides_windows(monkeypatch):
|
||||
from tools import checkpoint_manager
|
||||
|
||||
captured = []
|
||||
|
||||
def fake_run(cmd, **kwargs):
|
||||
captured.append((cmd, kwargs))
|
||||
return _Completed(stdout="clean\n")
|
||||
|
||||
monkeypatch.setattr(checkpoint_manager, "IS_WINDOWS", True)
|
||||
monkeypatch.setattr(checkpoint_manager, "windows_hide_flags", lambda: _CREATE_NO_WINDOW)
|
||||
monkeypatch.setattr(checkpoint_manager.subprocess, "run", fake_run)
|
||||
|
||||
ok, _, _ = checkpoint_manager._run_git(["status", "--short"], Path("C:/store"), ".")
|
||||
assert ok
|
||||
assert captured[0][0][0] == "git"
|
||||
assert captured[0][1]["creationflags"] == _CREATE_NO_WINDOW
|
||||
|
||||
|
||||
def test_skills_hub_gh_token_hides_windows(monkeypatch):
|
||||
from tools import skills_hub
|
||||
|
||||
captured = []
|
||||
|
||||
def fake_run(cmd, **kwargs):
|
||||
captured.append((cmd, kwargs))
|
||||
return _Completed(stdout="gho_from_cli\n")
|
||||
|
||||
monkeypatch.setattr(skills_hub, "IS_WINDOWS", True)
|
||||
monkeypatch.setattr(skills_hub, "windows_hide_flags", lambda: _CREATE_NO_WINDOW)
|
||||
monkeypatch.setattr(skills_hub.subprocess, "run", fake_run)
|
||||
|
||||
auth = skills_hub.GitHubAuth.__new__(skills_hub.GitHubAuth)
|
||||
assert auth._try_gh_cli() == "gho_from_cli"
|
||||
assert captured[0][0] == ["gh", "auth", "token"]
|
||||
assert captured[0][1]["creationflags"] == _CREATE_NO_WINDOW
|
||||
|
||||
|
||||
def test_tui_slash_worker_hides_python_window(monkeypatch):
|
||||
from tui_gateway import server
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ import subprocess
|
|||
import time
|
||||
from pathlib import Path
|
||||
from hermes_constants import get_hermes_home
|
||||
from hermes_cli._subprocess_compat import IS_WINDOWS, windows_hide_flags
|
||||
from typing import Dict, List, Optional, Set, Tuple
|
||||
|
||||
from utils import env_int
|
||||
|
|
@ -321,6 +322,10 @@ def _run_git(
|
|||
env = _git_env(store, str(normalized_working_dir), index_file=index_file)
|
||||
cmd = ["git"] + list(args)
|
||||
allowed_returncodes = allowed_returncodes or set()
|
||||
# Checkpoints run inside the console-less desktop/gateway backend; a bare
|
||||
# git spawn there pops a fresh conhost window per call (status, add,
|
||||
# commit, …) on Windows. No-op on POSIX.
|
||||
_popen_kwargs = {"creationflags": windows_hide_flags()} if IS_WINDOWS else {}
|
||||
try:
|
||||
result = subprocess.run(
|
||||
cmd,
|
||||
|
|
@ -330,6 +335,7 @@ def _run_git(
|
|||
env=env,
|
||||
cwd=str(normalized_working_dir),
|
||||
stdin=subprocess.DEVNULL,
|
||||
**_popen_kwargs,
|
||||
)
|
||||
ok = result.returncode == 0
|
||||
stdout = result.stdout.strip()
|
||||
|
|
@ -450,6 +456,7 @@ def _init_store(store: Path, working_dir: str) -> Optional[str]:
|
|||
capture_output=True, text=True,
|
||||
env=init_env, timeout=_GIT_TIMEOUT,
|
||||
stdin=subprocess.DEVNULL,
|
||||
**({"creationflags": windows_hide_flags()} if IS_WINDOWS else {}),
|
||||
)
|
||||
if result.returncode != 0:
|
||||
return f"Shadow store init failed: {result.stderr.strip()}"
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ from dataclasses import dataclass, field
|
|||
from datetime import datetime, timezone
|
||||
from pathlib import Path, PurePosixPath
|
||||
from hermes_constants import get_hermes_home
|
||||
from hermes_cli._subprocess_compat import IS_WINDOWS, windows_hide_flags
|
||||
from agent.skill_utils import is_excluded_skill_path
|
||||
from typing import Any, Dict, List, Optional, Tuple, Union
|
||||
from urllib.parse import urljoin, urlparse, urlunparse
|
||||
|
|
@ -302,6 +303,7 @@ class GitHubAuth:
|
|||
["gh", "auth", "token"],
|
||||
capture_output=True, text=True, timeout=5,
|
||||
stdin=subprocess.DEVNULL,
|
||||
**({"creationflags": windows_hide_flags()} if IS_WINDOWS else {}),
|
||||
)
|
||||
if result.returncode == 0 and result.stdout.strip():
|
||||
return result.stdout.strip()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue