Skip to content

fix(broker): unbreak Windows build#785

Merged
willwashburn merged 3 commits intomainfrom
fix/broker-windows-build
Apr 24, 2026
Merged

fix(broker): unbreak Windows build#785
willwashburn merged 3 commits intomainfrom
fix/broker-windows-build

Conversation

@willwashburn
Copy link
Copy Markdown
Member

@willwashburn willwashburn commented Apr 24, 2026

Summary

The Publish Package workflow failed on its Windows broker build because three unix-only APIs were called unconditionally:

  • tokio::signal::unix::signal(SignalKind::window_change) — SIGWINCH — in src/wrap.rs and src/pty_worker.rs
  • tokio::signal::unix::signal(SignalKind::terminate) — SIGTERM — in src/main.rs::run_init
  • get_terminal_size() was #[cfg(unix)] but invoked without cfg guards from pty_worker.rs:935 and wrap.rs:1305

On Windows, tokio::signal::unix doesn't exist, leaving sigwinch/sigterm with unresolved types that cascaded through the giant tokio::select! blocks as E0277: the size for values of type [u8] cannot be known at compilation time errors. get_terminal_size surfaced as E0425: cannot find function ... in this scope.

Fixes — functional parity, not cfg-skips

  • get_terminal_size() now uses crossterm::terminal::size() (TIOCGWINSZ on unix, GetConsoleScreenBufferInfo on Windows). Dropped the #[cfg(unix)] gate.
  • wrap.rs polls get_terminal_size() every 200ms to detect resize. crossterm::event::EventStream was not viable — it reads /dev/tty/CONIN$ and would steal keystrokes from the stdin passthrough that forwards user input to the child PTY. Polling uses a pure size query, no input consumption, imperceptible latency.
  • pty_worker.rs removes the SIGWINCH handler entirely. The worker's stdout is a pipe, so get_terminal_size() always returned None and the arm was already a no-op on unix. Resize already flows in correctly via the resize_pty protocol frame from the broker (handled at the existing frame dispatcher).
  • run_init splits SIGTERM: unix keeps SignalKind::terminate(); Windows uses tokio::signal::windows::ctrl_shutdown(). Ctrl+C continues to work cross-platform via the existing tokio::signal::ctrl_c() arm.

Test plan

  • cargo check --target x86_64-pc-windows-gnu — clean (was: 9 errors)
  • cargo build on darwin — clean
  • cargo test --lib — 232 passed
  • CI Windows MSVC build passes
  • Manual: resize terminal while running agent-relay-broker wrap ... on macOS/Linux, verify child process sees new dimensions within ~200ms

🤖 Generated with Claude Code


Open in Devin Review

The broker failed to compile on x86_64-pc-windows-msvc because three
unix-only APIs were invoked unconditionally:

- `tokio::signal::unix::signal(SignalKind::window_change)` (SIGWINCH)
  in src/wrap.rs and src/pty_worker.rs
- `tokio::signal::unix::signal(SignalKind::terminate)` (SIGTERM)
  in src/main.rs::run_init
- `get_terminal_size()` gated `#[cfg(unix)]` but called without
  cfg guards from pty_worker.rs and wrap.rs

On Windows, tokio::signal::unix doesn't exist, leaving `sigwinch` /
`sigterm` with unresolved types that cascaded through the giant
`tokio::select!` blocks as E0277 errors on `[u8]`. `get_terminal_size`
surfaced as E0425 (not found in scope).

Fixes — functional parity, not cfg-skips:

* `get_terminal_size()` now uses `crossterm::terminal::size()`
  (TIOCGWINSZ on unix, GetConsoleScreenBufferInfo on Windows). No
  cfg gate.
* `wrap.rs` polls `get_terminal_size()` every 200ms to detect resize.
  EventStream wasn't viable — it reads /dev/tty/CONIN$ and would steal
  keystrokes from the stdin passthrough.
* `pty_worker.rs` removes the SIGWINCH handler entirely: the worker's
  stdout is a pipe, so `get_terminal_size()` always returned None and
  the arm was already a no-op. Resize already flows in correctly via
  the `resize_pty` protocol frame (handled at line 391).
* `run_init` splits SIGTERM: unix keeps `SignalKind::terminate()`,
  Windows uses `tokio::signal::windows::ctrl_shutdown()`. Ctrl+C
  continues to work cross-platform via the existing arm.

Verified with `cargo check --target x86_64-pc-windows-gnu` and
`cargo test --lib` on darwin.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
barryollama
barryollama previously approved these changes Apr 24, 2026
Previous attempt polled terminal size from the main tokio::select!
loop on all platforms. On unix this was a regression — SIGWINCH is
event-driven, zero-CPU when idle. Restore the signal handler on unix.

On Windows, true event-driven resize isn't viable because reading
CONIN$ (via crossterm EventStream or ReadConsoleInput) consumes
keypresses that our stdin passthrough needs to forward to the child
PTY. Move polling to a dedicated std::thread that calls
crossterm::terminal::size() every 100ms and notifies the main loop
via a tokio channel only when the size changes. Main select! stays
event-driven; polling sits off the hot path.

Both platforms now forward resize the moment the PTY rebroadcasts its
new dimensions to the child.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

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

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 4 additional findings.

Open in Devin Review

@willwashburn willwashburn merged commit 2566ea2 into main Apr 24, 2026
45 checks passed
@willwashburn willwashburn deleted the fix/broker-windows-build branch April 24, 2026 15:34
Copy link
Copy Markdown

@xkonjin xkonjin left a comment

Choose a reason for hiding this comment

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

Code Review: fix(broker): unbreak Windows build

Solid cross-platform fixes. A few notes:

  1. crossterm::terminal::size() swap — good. The platform abstraction is cleaner than the raw libc/unsafe block.
  2. pty_worker.rs — removing SIGWINCH is the right call. The worker stdout is a pipe, so the signal arm was already dead code on all platforms. The resize_pty protocol frame is the correct mechanism.
  3. wrap.rs — the 100ms Windows polling thread is pragmatic. Consider bumping to 200ms to match the PR description (says 200ms, but code is 100ms). Either works, but consistency would be nice.
  4. Typo in PR description: mentions wrap.rs polling at 200ms, but the code uses 100ms. Not blocking, but fix one or the other.
  5. Missing: No tests added for the Windows path. The manual test checklist is fine, but automated regression coverage would be stronger against future platform breakage.

Overall: ship it after a minor test gap fix.

@willwashburn willwashburn restored the fix/broker-windows-build branch April 24, 2026 16:10
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.

3 participants