fix(windows): make gateway install lifecycle idempotent (salvage of #26488)#28874
Merged
Conversation
Apply CREATE_NO_WINDOW flags when the cron scheduler launches job scripts on Windows so gateway-managed no-agent cron jobs do not flash cmd or python console windows every tick.
Apply Windows CREATE_NO_WINDOW flags to foreground local terminal subprocesses and tracked background processes so Hermes operations do not flash or steal focus with extra console windows.
Preserve Windows profile install decisions across UAC handoff, avoid visible console windows by launching via pythonw, make repeated install/start idempotent, recreate stale Scheduled Tasks, and separate start-now from login auto-start behavior. Add Windows gateway regression coverage and systemd setup tests for the shared install flow.
…-Windows Linux/macOS CI runners don't have ctypes.windll, so the elevated-gateway test fails at module load. Adding raising=False lets monkeypatch install the mock attribute without first requiring it to exist.
Contributor
🔎 Lint report:
|
| Rule | Count |
|---|---|
no-matching-overload |
2 |
unresolved-attribute |
2 |
First entries
tools/environments/local.py:525: [no-matching-overload] no-matching-overload: No overload of `Popen.__init__` matches arguments
hermes_cli/gateway_windows.py:168: [unresolved-attribute] unresolved-attribute: Module `ctypes` has no member `windll`
tools/process_registry.py:555: [no-matching-overload] no-matching-overload: No overload of `Popen.__init__` matches arguments
tools/environments/local.py:541: [unresolved-attribute] unresolved-attribute: Unresolved attribute `_hermes_pgid` on type `Popen[AnyStr@Popen]`
✅ Fixed issues (2):
| Rule | Count |
|---|---|
unresolved-attribute |
2 |
First entries
tools/process_registry.py:563: [unresolved-attribute] unresolved-attribute: Module `subprocess` has no member `CREATE_NO_WINDOW`
tools/environments/local.py:537: [unresolved-attribute] unresolved-attribute: Unresolved attribute `_hermes_pgid` on type `Popen[str]`
Unchanged: 4720 pre-existing issues carried over.
Diagnostics are surfaced as warnings — this check never fails the build.
This was referenced May 19, 2026
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Salvages @nekwo's Windows gateway lifecycle work from #26488 onto current main. Closes #26487 — "Severe: Windows gateway install may spawn repeated console windows that make the desktop unusable" — by making repeated
hermes gateway install/startidempotent, hiding subprocess consoles, and routing UAC escalation only through the access-denied path.Original PR #26488 was 23 commits behind main with major conflicts in cron/scheduler.py, tools/process_registry.py, and tests/hermes_cli/test_gateway_windows.py. This salvage cherry-picks the three substantive contributor commits, resolves conflicts in favor of recent main changes (stdin=DEVNULL fix from 214b953, env=run_env from cron HERMES_HOME work), and adds one follow-up fixup for cross-platform test compatibility.
Changes
hermes_cli/gateway_windows.py— idempotent install/start, schtasks /Create /F reconciliation, UAC only on access-denied, pythonw + hidden flags for detached spawn (nekwo, +361/-…)hermes_cli/gateway.py— passes setup choices through to Windows install, honors start/startup choices on systemd, declines launchd when login auto-start declined (nekwo)hermes_cli/main.py— adds--start-now/--no-start-now/--start-on-login/--no-start-on-login/--elevated-handofffor UAC handoff (nekwo)tools/environments/local.py,tools/process_registry.py,cron/scheduler.py—creationflags=windows_hide_flags()so foreground/background terminal subprocesses and cron jobs don't flash cmd/python windows (nekwo)tests/hermes_cli/test_gateway.py,tests/hermes_cli/test_gateway_windows.py— regression coverage for the lifecycle behaviors above (nekwo, +85 / +424). Merged with the 3 pre-existing tests on main covering schtasks fallback patterns and uv venv launcher detection.monkeypatch.setattr(..., raising=False)onctypes.windllso the elevated-gateway test runs on non-Windows CI.Validation
Matches the contributor's own
pytest … -qresult (45 passed at the time of his branch; we have 54 because main added tests in the meantime).Closes