Skip to content

feat(host): the Rust host on Windows (#76 phase 3b) - #154

Merged
cachewraith merged 1 commit into
mainfrom
feat/rust-host-windows-20261027
Oct 27, 2026
Merged

cachewraith merged 1 commit into
mainfrom
feat/rust-host-windows-20261027

Conversation

@cachewraith

Copy link
Copy Markdown
Owner

Phase 3b of #76: the Rust pty host on Windows. With 3a (#153) it now builds for all three systems.

Panes: a ConPTY spawn of our own (host-rs/src/pty.rs, windows-sys)
portable-pty always quotes every argument on Windows, and an npm .cmd CLI (claude on Windows) arrives as a ready cmd.exe /d /s /c "…" line from platform.ts, so it couldn't go through portable-pty.

  • File and list args are quoted the way CreateProcess reads them back; a ready line is kept as is, as node-pty does.
  • The pane's stdio is cut off from the host's own (its log) with STARTF_USESTDHANDLES; otherwise it would inherit those instead of the pseudoconsole.
  • The exit code comes from the process handle; there are no signals, like node-pty.
  • Kill closes the pseudoconsole, then runs taskkill /PID … /T /F after the 2 s grace, as the Node host's Windows policy does.
  • Unix is unchanged (portable-pty + waitpid), only moved behind cfg(unix).

Host (main.rs, server.rs)

  • A named pipe server (one instance per client, remote clients refused), lock liveness via OpenProcess, token from BCryptGenRandom. A Ctrl-C hook that can't be set (the host has no console) never stops the host.
  • Host::accept takes any async stream. The ssh bridge and its plan stay Unix-only (remote machines run Linux).

App / packaging: finds wraithgrid-host.exe; dist:win builds and bundles it; Settings → Advanced "Use the Rust host" shows on every OS (still off by default).

Tests

  • New host-rs/tests/smoke.rs: starts the built host as the GUI does, connects over its socket (named pipe on Windows), runs a pane that prints and one that is typed into, then shuts the host down. On Windows it uses a ready cmd.exe /d /s /c "echo …" line, so it covers the ConPTY spawn, the raw command line and the pipe.
  • CI's Windows job now runs cargo clippy and cargo test (incl. the smoke test). The parity suite (tests/host) stays Unix-only.
  • Locally (Linux): cargo clippy -D warnings clean for Linux and x86_64-pc-windows-gnu, cargo test (19 + smoke), parity suite 40 passed, typecheck, lint, 491 unit tests.

Not done / not seen: never run in the real app on Windows, nor with a real npm claude.cmd; the Windows code is checked only by CI's smoke test. No code signing for the binary.

Refs #76

🤖 Generated with Claude Code

- pty: a ConPTY spawn of our own on Windows (windows-sys): portable-pty
  quotes every argument, and an npm .cmd CLI arrives as a ready
  `cmd.exe /d /s /c "…"` line. File and list args are quoted as
  CreateProcess reads them, a ready line is kept as is; stdio is cut off
  from the host's log (STARTF_USESTDHANDLES); the exit code comes from the
  process handle (no signals, like node-pty); kill closes the console,
  then `taskkill /T /F` after the grace. Unix keeps portable-pty + waitpid
- main: a named pipe server (one instance per client, remote clients
  refused), lock liveness via OpenProcess, token from BCryptGenRandom, a
  Ctrl-C hook that can't be set never stops the host; the ssh bridge and
  its plan stay Unix-only
- server: accept takes any AsyncRead + AsyncWrite stream
- tests/smoke.rs: the built host end to end on every OS (socket or pipe,
  a pane that prints, one typed into, shutdown); CI's Windows job runs it
  with clippy
- app: finds wraithgrid-host.exe; dist:win builds and bundles it; the
  Settings switch shows on every OS

Refs #76

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cachewraith
cachewraith merged commit 40cacff into main Oct 27, 2026
4 checks passed
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.

1 participant