computer-helper-win

August 25, 2026 · View on GitHub

Windows backend for agents computer — C#/.NET 10 daemon, sibling of the Swift native/computer-mac. Same JSON-RPC wire protocol, same result shapes; one TS client (cli/src/lib/computer/computer-rpc.ts) drives both.

This file is a map. Read the code (and README.md) for current detail.

Layout

Program.cs      Entry point (top-level statements) — TCP listener, auth, RPC loop
Rpc.cs          Method dispatch table (19 methods)
Automation.cs   UI Automation tree walk + SendInput (click/type/key/scroll/drag) + window focus
Screenshot.cs   Graphics.CopyFromScreen over the virtual screen
Apps.cs         Process/window enumeration; launch_app via PATH + App Paths registry
LaunchTarget.cs Pure path safety for launch_app (UNC/protocol rejection; RUSH-1763)
ElementCache.cs @eN element handle cache
smoke/smoke.mjs Smoke test (Unicode-typing regression loops for #554/#581)
computer-helper-win.csproj   net10.0-windows, WPF + WinForms enabled
tests/LaunchTarget.Tests.csproj  net10.0 xunit tests for LaunchTarget (cross-platform)

Build

bash ../../cli/scripts/build-win.sh   # dotnet publish -r win-x64 --self-contained -p:PublishSingleFile

Output: dist/computer-helper-win.exe (gitignored; staged into the npm tarball at release). Needs the .NET 10 SDK; cross-publishes from macOS/Linux (EnableWindowsTargeting).

How the CLI reaches it

cli/src/lib/computer/ssh-tunnel.tsresolveWinHelperExe() looks for native/computer-win/dist/computer-helper-win.exe (dev checkout, 5 hops up from cli/dist/lib/computer) or the bundled npm copy. setupRemoteHelper() scp's the exe to %LOCALAPPDATA%\agents\, registers a Task Scheduler task (AgentsComputerHelper, -AtLogOn, interactive), and starts it. The CLI connects over an ssh -L tunnel to the daemon's loopback TCP port (8765).

Key differences from computer-mac (don't assume mac semantics)

  • Transport is loopback TCP + SSH tunnel, not a Unix socket. The tunnel is the sole ingress; an optional --token-file shared secret is defense-in-depth.
  • No TCC / no permission model. Windows UIA needs no per-process grant — trust_status always returns trusted=true. There is no allow-list, computer-policy.json, or peer-auth file. Access control = the SSH tunnel.
  • Lifecycle is Task Scheduler, not launchd — it must run in the interactive desktop session (not Session 0) for UIA + screen capture to work.
  • Single-file needs native-lib self-extraction (IncludeNativeLibrariesForSelfExtract) or UIA throws on the first tree walk (#519).
  • bundle_id = process image name (notepad), not reverse-DNS.
  • notify is pass-through only — no Windows Toast; Rush intercepts the return.