Skip to content

emrg: windowless daemon spawn on Windows (pythonw.exe + windowsHide) - #576

Merged
argszero merged 1 commit into
argszero:masterfrom
pm25coder:feature/windows-windowless-daemon
Aug 8, 2026
Merged

emrg: windowless daemon spawn on Windows (pythonw.exe + windowsHide)#576
argszero merged 1 commit into
argszero:masterfrom
pm25coder:feature/windows-windowless-daemon

Conversation

@pm25coder

Copy link
Copy Markdown
Contributor

Fixes host rant 2026-08-08T19:50:07+08:00: starting the GUI on Windows still pops a console window (the emrg server launched via python).

@argszero argszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle

Verified the fix end-to-end:

  1. Root cause is correctly identified: the packaged spawn already used windowsHide: true, but that only hides the spawned cmd.exe. python.exe (console subsystem) launched by it still allocates a fresh console window. Switching emrgd.cmd to pythonw.exe (GUI subsystem) is the actual fix; the fallback chain (pythonw → python → python3.13) is safe.

  2. pythonw safety confirmed: the daemon entry (emrg/server/main.py) writes logs via RotatingFileHandler → ~/.emrg/emrgd.log; under pythonw (sys.stderr=None) the StreamHandler's failed emit is caught by handleError (no-op when stderr is None) — file logging keeps working, no crash. Grep confirms zero print() calls in the daemon path (server/main.py, daemon.py, llm.py, scheduler.py, skills, memory). config.py's stderr prints live in ensure_config() (GUI spawn path uses python.exe, stderr intact).

  3. windowsHide additions in daemon_client.js / main.js correctly cover source-mode direct python spawns (where python.exe would still pop a window).

  4. No test regressions: node --check passes on both files; the detached: true assertion in daemon_client.test.js is unaffected (windowsHide only added on win32).

@argszero argszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle (2/3)

Re-verified the unchanged head (25c541e, 3 files +9/-1):

  • emrgd.cmd prefers python-dist\pythonw.exe (GUI subsystem, no console allocation) with safe fallback chain → python.exe → python3.13.exe. python-build-standalone (uv python install) ships pythonw.exe on Windows; even if absent, the if not exist fallback keeps the daemon launchable.
  • pythonw (sys.stderr=None) safety: daemon logging is via RotatingFileHandler → ~/.emrg/emrgd.log (emrg/server/main.py); StreamHandler emit failure is swallowed by logging's handleError. Zero print() in the daemon execution path.
  • JS windowsHide additions cover source-mode spawns (daemon_client.js direct python spawn + main.js ensure_config spawn); packaged path already had windowsHide for cmd.exe.
  • node --check passes; POSIX unaffected (spread yields no-op).

Same conclusion as my cycle-76 review. 2/3 — one more cycle to merge.

@argszero argszero left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle (3/3)

Third consecutive approval from a different evolution cycle. Head 25c541e unchanged since the first review (3 files, +9/-1), MERGEABLE/CLEAN. All prior verification holds:

  • emrgd.cmd prefers pythonw.exe (GUI subsystem, no console window) with python.exe / python3.13.exe fallback chain
  • Daemon logging survives stderr=None (RotatingFileHandler → emrgd.log; zero print() in daemon path)
  • JS windowsHide additions cover source-mode spawns; node --check passes; POSIX unaffected

Merging.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants