Skip to content

fix(photon): launch the iMessage sidecar headless on Windows - #54565

Closed
lEWFkRAD wants to merge 2 commits into
NousResearch:mainfrom
lEWFkRAD:fix/windows-console-flash-popups
Closed

fix(photon): launch the iMessage sidecar headless on Windows#54565
lEWFkRAD wants to merge 2 commits into
NousResearch:mainfrom
lEWFkRAD:fix/windows-console-flash-popups

Conversation

@lEWFkRAD

@lEWFkRAD lEWFkRAD commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

On Windows, plugins/platforms/photon/adapter.py launches the Photon (iMessage) Node sidecar — and the spectrum-ts mixed-attachment patch run — via subprocess without creationflags. Each spawn opens a visible console window; because a failing sidecar is retried on a timer, that window flashes repeatedly. This adds CREATE_NO_WINDOW on win32 to both spawn sites so the sidecar runs headless. Windows-only; no-op on Linux/macOS. Mirrors the existing pattern in hermes_cli/kanban_db.py.

Related Issue

No tracking issue filed. Companion: #43933 already fixes the sibling gateway/status.py _read_process_cmdline() ps.exe console-popup, so that file is intentionally excluded here to avoid duplicating it. (#53868 also edits this adapter, but for an unrelated concern — keeping the sidecar alive when the patch fails.)

Fixes #

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • plugins/platforms/photon/adapter.py — add creationflags=subprocess.CREATE_NO_WINDOW if sys.platform == "win32" else 0 to both subprocess spawns in _start_sidecar():
    • the spectrum-ts mixed-attachment patch run (subprocess.run([...])), and
    • the persistent Node sidecar (subprocess.Popen([...])).

How to Test

  1. On Windows with the Photon (iMessage) platform configured, start the gateway.
  2. Before: a console window flashes on every sidecar (re)start — and repeatedly while the sidecar is unhealthy and the gateway retries it on a timer.
  3. After: no console window appears; the sidecar runs headless (Get-Process -Id <pid> shows MainWindowHandle = 0) and photon connects normally (✓ photon connected — sidecar on 127.0.0.1:8789).

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(photon): ...)
  • I searched for existing PRs — none add CREATE_NO_WINDOW to the Photon sidecar spawn; the related status.py fix (fix: skip ps.exe on Windows to prevent console window popups #43933) is intentionally excluded
  • My PR contains only changes related to this fix (single file)
  • I've run pytest tests/ -q and all tests pass — not run in full locally; the change is win32-guarded and mirrors hermes_cli/kanban_db.py. Verified manually on Windows 11 (see How to Test).
  • I've added tests for my changes — the spawn sits in an async sidecar-startup path that's impractical to unit-test in isolation; happy to add coverage if a maintainer points to the preferred harness.
  • I've tested on my platform: Windows 11

Documentation & Housekeeping

  • I've updated relevant documentation (inline comments at both spawn sites) — README/docs/ N/A
  • I've updated cli-config.yaml.example if I added/changed config keys — N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — N/A
  • I've considered cross-platform impact — guarded by sys.platform == "win32"; no-op on Linux/macOS
  • I've updated tool descriptions/schemas if I changed tool behavior — N/A

Screenshots / Logs

Before — the sidecar retry loop, each iteration flashing a console:

gateway.run: Reconnecting photon (attempt N)...
gateway.run: Reconnect photon failed, next retry in 300s

After — connects and runs headless:

[photon-sidecar] photon-sidecar: listening on 127.0.0.1:8789
gateway.run: ✓ photon connected

🤖 Generated with Claude Code

@lEWFkRAD
lEWFkRAD force-pushed the fix/windows-console-flash-popups branch from c871371 to 2df43ea Compare June 29, 2026 02:24
@alt-glitch alt-glitch added type/bug Something isn't working comp/gateway Gateway runner, session dispatch, delivery comp/plugins Plugin system and bundled plugins platform/windows Native Windows-specific behavior or breakage P2 Medium — degraded but workaround exists sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows labels Jun 29, 2026
@lEWFkRAD
lEWFkRAD force-pushed the fix/windows-console-flash-popups branch from 2df43ea to d8864ff Compare June 29, 2026 02:28
@lEWFkRAD lEWFkRAD changed the title Windows: stop console-window flashes from gateway liveness poll and photon sidecar fix(photon): launch the iMessage sidecar headless on Windows Jun 29, 2026
@lEWFkRAD
lEWFkRAD force-pushed the fix/windows-console-flash-popups branch from b8f1d7a to a49d068 Compare July 2, 2026 12:04
@lEWFkRAD

lEWFkRAD commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto current main and slimmed to the one fix main still needs. Dropped as already-upstream: the gateway/status.py ps.exe guard (main now has the _IS_WINDOWS gate + psutil fallback via cb982ad/9a0010fd4) and the MoA streaming/reference-cap commit (call_llm streams natively now, and main deliberately imposes no reference cap - not re-adding that). What remains: the photon adapter Popen/patch-run spawns, which were the one messaging adapter missed when discord/whatsapp got windows_hide_flags() - now wired to that same canonical helper instead of a raw CREATE_NO_WINDOW constant. tests/plugins/platforms/photon: 104 passed (4 pre-existing POSIX-only failures reproduce on pristine main); test_windows_subprocess_no_window_flags.py: 15/15.

plugins/platforms/photon/adapter.py launches the Node sidecar (and the
spectrum-ts mixed-attachment patch run) via subprocess without creationflags.
On Windows this opens a visible console window on every sidecar (re)start --
and because a failed sidecar is retried on a timer, it flashes repeatedly.

Wire windows_hide_flags() (hermes_cli/_subprocess_compat) into both spawns,
the same helper the discord and whatsapp adapters already use for their
sidecar spawns -- photon was the one platform adapter this pattern missed.
CREATE_NO_WINDOW only (no DETACHED_PROCESS) so the persistent sidecar's
stdin/stdout pipes stay usable for the supervisor.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for narrowing this to the two Photon child-process spawns. The premise remains valid on current main: plugins/platforms/photon/adapter.py:948 and :969 invoke subprocess.run and subprocess.Popen without creationflags. The proposed windows_hide_flags() use matches its documented behavior in hermes_cli/_subprocess_compat.py:186-201: CREATE_NO_WINDOW on Windows, no detachment, and preserved stdio pipes.

Problems

  • No PR test protects these two call sites. tests/plugins/platforms/photon/test_sidecar_lifecycle.py:127-171 already captures the sidecar Popen kwargs, but it does not assert creationflags and does not exercise the patch subprocess.run call.

Suggested changes

  • Extend that lifecycle test to simulate the compatibility helper's Windows mode, capture both spawns, and assert both receive windows_hide_flags().

This is an automated hermes-sweeper review.

stderr=subprocess.STDOUT,
env=env,
start_new_session=(sys.platform != "win32"),
# Windows: run the persistent sidecar headless so it does not open

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Please add a Photon-specific regression test that simulates Windows and asserts this Popen call and the patch subprocess.run call both receive creationflags=windows_hide_flags(). The existing lifecycle test already captures Popen kwargs but currently only checks stdin and the EOF-watch environment.

@teknium1 teknium1 added sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 15, 2026
teknium1 added a commit that referenced this pull request Jul 16, 2026
Widen @lEWFkRAD's sidecar-headless fix (PR #54565) to the sibling spawn
sites: the npm ci / npm install self-heal runs in _reinstall_sidecar_deps
also popped a brief console window per run on Windows. Same
windows_hide_flags() helper (CREATE_NO_WINDOW only, so capture_output
stays usable).
@teknium1

Copy link
Copy Markdown
Contributor

Merged via PR #65441 — your two commits were cherry-picked onto current main with your authorship preserved in git log (d8f7b60, d68ac90), plus a small follow-up widening the same fix to the npm dep self-heal spawn sites. You were the earliest of five contributors to fix this bug, and your implementation (shared windows_hide_flags() helper, both spawn sites, tests) was the cleanest. Thanks!

Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
Widen @lEWFkRAD's sidecar-headless fix (PR NousResearch#54565) to the sibling spawn
sites: the npm ci / npm install self-heal runs in _reinstall_sidecar_deps
also popped a brief console window per run on Windows. Same
windows_hide_flags() helper (CREATE_NO_WINDOW only, so capture_output
stays usable).
randlee pushed a commit to randlee/hermes-agent that referenced this pull request Aug 11, 2026
Widen @lEWFkRAD's sidecar-headless fix (PR NousResearch#54565) to the sibling spawn
sites: the npm ci / npm install self-heal runs in _reinstall_sidecar_deps
also popped a brief console window per run on Windows. Same
windows_hide_flags() helper (CREATE_NO_WINDOW only, so capture_output
stays usable).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery comp/plugins Plugin system and bundled plugins P2 Medium — degraded but workaround exists platform/windows Native Windows-specific behavior or breakage sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants