feat(desktop): discover and spawn ACP harnesses installed in WSL on Windows - #3679
Open
spfcraze wants to merge 1 commit into
Open
feat(desktop): discover and spawn ACP harnesses installed in WSL on Windows#3679spfcraze wants to merge 1 commit into
spfcraze wants to merge 1 commit into
Conversation
…indows When a preset or custom harness command is missing from the Windows PATH, harness discovery now probes the default WSL distribution (~/.local/bin, ~/bin, /usr/local/bin, then the distro PATH) and marks the harness Available with a wsl:// binary path. At spawn, Desktop hands the in-distro path to buzz-acp (BUZZ_ACP_AGENT_WSL_PATH, optional BUZZ_ACP_AGENT_WSL_DISTRO), which wraps the agent launch through wsl.exe -e and forwards all agent-intended env vars across the boundary via a computed WSLENV merge. BUZZ_ACP_AGENT_COMMAND keeps the bare command identity so per-runtime defaults (e.g. HERMES_ACP_SKIP_CONFIGURED_MCP) apply unchanged. This unblocks running Hermes Agent (Linux-first install, hermes-acp) from Buzz Desktop on Windows without a hand-authored custom harness. Docs: docs/windows-wsl-harnesses.md Signed-off-by: Frank Saunders <frank@users.noreply.github.com>
spfcraze
force-pushed
the
feat/windows-wsl-harness-fallback
branch
from
July 30, 2026 12:35
d2afdfa to
0458c49
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
On Windows, Buzz Desktop discovers ACP harnesses by resolving their command
on the Windows PATH. Several supported harnesses are commonly installed
inside WSL, not on the Windows host — Hermes Agent (
hermes-acp) is thecanonical case: it is a Linux-first install, so on a Windows machine running
Hermes in WSL, Doctor reports Not installed and the harness cannot be
started, even though it works perfectly inside the distro.
There was no WSL story anywhere in the harness discovery/spawn path (the only
WSL awareness in the tree is
is_windows_apps_alias, which exists to avoidWindowsApps stub launchers, issue #2328).
What this PR does
Buzz now falls back to the default WSL distribution when a preset or
custom harness command is missing from the Windows PATH:
Discovery (
managed_agents/wsl.rs, new) — probes the default distrovia
wsl.exe -e sh -c …, checking~/.local/bin,~/bin,/usr/local/bin, then the distro PATH (command -v). Positive resultsmark the harness Available with a
wsl://…binary path in Doctor.Resolutions are cached for the app lifetime (mirrors
resolve_command'scache contract). Only bare command names are ever probed — paths are
rejected up front (no injection surface, no nonsense lookups).
Spawn contract (
runtime.rs→buzz-acp) — when the host PATHresolution failed but the WSL probe succeeded, Desktop sets
BUZZ_ACP_AGENT_WSL_PATH(absolute in-distro path) and optionallyBUZZ_ACP_AGENT_WSL_DISTROon thebuzz-acpchild.BUZZ_ACP_AGENT_COMMANDkeeps the original bare identity(
hermes-acp), so all per-runtime defaults keyed on the command name(
default_agent_env,default_agent_args) apply unchanged.Spawn wrapping (
buzz-acp/src/acp.rs) —AcpClient::spawnreads thecontract and launches
wsl.exe [-d distro] -e <linux_path> <args>insteadof the bare command. WSL interop bridges the stdio pipes; the ACP/NDJSON
channel is byte-transparent. Contract values are validated (absolute POSIX
path required); a set contract on a non-Windows host is ignored with a
warning.
Environment forwarding — wsl.exe children only import Windows-side
variables listed in
WSLENV.buzz-acpbuilds the forward list fromevery agent-intended key (per-runtime defaults like
HERMES_ACP_SKIP_CONFIGURED_MCP=1, persona env likeGOOSE_PROVIDER,merged
CODEX_CONFIG), merging into any pre-existingWSLENVwithoutduplicating flagged entries (
GOPATH/pstyle). Without this, agents inWSL silently lose their env — for Hermes specifically this re-introduces
the [Bug] Hermes model discovery times out in Buzz Desktop v0.5.0 #3355 startup-stall the skip flag exists to prevent.
Verification (real, on a Windows 11 + WSL2 machine)
Environment: Windows 11, WSL2
Ubuntu, Hermes Agent v0.19.0 at/home/userspace/.local/bin/hermes-acp, Buzz Desktop installed atC:\Users\user1\AppData\Local\Buzz\.hermes-acpabsent from Windows PATH → Doctor showsHermes Not installed.
C:\Windows\System32\wsl.exe -e /home/userspace/.local/bin/hermes-acpfrom aWindows parent with piped stdio returns a byte-clean ACP
initializeresponse (
agentInfo: hermes-agent 0.19.0,protocolVersion: 1).WSLENV,hermes-acphangs beforeinitialize(the [Bug] Hermes model discovery times out in Buzz Desktop v0.5.0 #3355 MCP-startup stall). WithHERMES_ACP_SKIP_CONFIGURED_MCP=1set Windows-side and forwarded viaWSLENV, initialize answers immediately.documented in
docs/windows-wsl-harnesses.md(same mechanism this PRautomates) loads and works on the current released build.
Tests
buzz-acp: 8 new unit tests (build_wsl_wrapvalidation,prefix_args,merge_wslenvorder/dup/flag handling).cargo test -p buzz-acp: 648passed, 0 failed (full suite, Linux).
cargo clippy -p buzz-acp --all-targets: clean.wsl.rs: 6 unit tests (probe script contract pins~/.local/binbefore PATH, no login shell; stdout parsing; display path;
probeable-command validation incl. metacharacter rejection; negative-result
caching) — pass on Linux. Process-spawning probes are
cfg(windows)-gated;the Windows-only code paths (
resolve_wsl_exe, probe spawn) werecompile-verified for
x86_64-pc-windows-msvc.cargo check(Linux) ondesktop/src-tauri: green, zero warnings.cargo test managed_agents::ondesktop/src-tauri: 906 passed, 0failed (includes the 6 new
wsl.rstests + all pre-existing discovery,custom-harness, spawn-hash, and readiness tests).
x86_64-pc-windows-msvcworkspace check was not runnable in the devcontainer (crypto
-syscrates need a Windows C toolchain); Windows CIcovers it. Every Windows-gated line added by this PR is either
std-only Rust (verified via the standalone msvc-target compile described
above) or mirrors existing patterns in
git_bash.rs.preset_catalog_entry) —unchanged, still green.
Notes for reviewers
install scripts) still assume host-native installs — a follow-up could
extend the same cached-resolution mechanism to their probes.
on both the discovery and spawn paths. WSL-unavailable machines
short-circuit on
wsl.exeresolution.WslCommandResolution.distrois plumbed through the wholecontract but always
Nonetoday (default distro only) — multi-distrodiscovery needs no contract change.
pub(crate)/ private). Docs added:docs/windows-wsl-harnesses.md.