Skip to content

fix(acp,desktop): let a custom harness override session cwd for remote hosts - #3456

Open
surfingdev wants to merge 1 commit into
block:mainfrom
surfingdev:fix/byoh-remote-harness-cwd
Open

fix(acp,desktop): let a custom harness override session cwd for remote hosts#3456
surfingdev wants to merge 1 commit into
block:mainfrom
surfingdev:fix/byoh-remote-harness-cwd

Conversation

@surfingdev

@surfingdev surfingdev commented Jul 29, 2026

Copy link
Copy Markdown

Problem

Bring-your-own-harness (BYOH) lets a managed agent's harness command be anything — including ssh to a remote machine, so the ACP agent process runs on a separate VM while Desktop stays the client. This is exactly the setup you'd want for an always-reachable-from-chat agent that doesn't have to live and die with the Desktop process.

It fails on the very first turn today. buzz-acp always sends its own local working directory as session/new's cwd (std::env::current_dir() — the directory Desktop set when it spawned the buzz-acp process, normally ~/.buzz). When the harness runs elsewhere, that path is meaningless there and the remote adapter rejects it outright:

Turn error · error: Agent reported error (code -32602):
Invalid params: `cwd` does not exist on the machine running the agent: /Users/someuser/.buzz

There's no way to override it — nothing in the custom harness JSON schema or the effective spawn config lets you say "use this path instead." A user can work around it by manually creating the client's exact path on the remote machine (e.g. sudo ln -sfn /home/user/buzz /Users/someuser/.buzz), but that's a fragile hack: a macOS path fabricated on Linux whose correctness depends on the two machines coincidentally agreeing on a string, and it breaks the moment Desktop starts sending per-agent subdirectories or a different client user account is used.

What this changes

Adds an optional cwd field to the custom harness JSON schema (desktop/src-tauri/src/managed_agents/custom_harnesses.rs), alongside the existing command/args/env. When set, it's threaded through resolve_effective_harness_descriptor (readiness.rs) to a new BUZZ_ACP_SESSION_CWD env var set at spawn time (runtime.rs). buzz-acp reads that var and uses it verbatim as session/new's cwd in place of its own current_dir() (crates/buzz-acp/src/config.rs, crates/buzz-acp/src/lib.rs).

Deliberately not command.current_dir(cwd) on the spawned process — that path only needs to exist on the harness's machine, which may not be this one, and calling current_dir() with a nonexistent local path would just fail the spawn. The override only changes the string sent over the wire in session/new; the buzz-acp process's own local working directory is untouched.

Also added descriptor.cwd.hash(&mut hasher) to the restart-drift hash (spawn_hash.rs) so editing a definition's cwd on a running agent trips the "Restart required" badge, same as editing command/args already does.

Documented the field in crates/buzz-acp/README.md's BYOH section, plus a new "Remote harnesses over SSH" subsection covering two more things a remote/SSH harness needs that aren't code fixes: forwarding BUZZ_* env vars via SendEnv/AcceptEnv (SSH doesn't forward them by default — without this, the agent looks slow/unresponsive rather than misconfigured, since it can still receive turns but every buzz CLI call it makes fails silently), and setting PATH inline in the harness command (non-interactive SSH sessions don't load the login shell profile).

Out of scope

  • Per-instance cwd override. Only the harness definition can set it for now, not an individual agent instance — matches the report's primary ask and keeps this change small. Multiple instances of the same SSH-based harness needing different remote paths would need this; not a reported need yet.
  • Exposing cwd in the Settings custom-harness form. Tier-3 harnesses remain JSON-file-only for this field — consistent with how the field is meant to be used today (hand-edit the JSON, same workflow already used to configure command/args/env for advanced setups).
  • Automatic env-var forwarding for SSH harnesses. Documented as a SendEnv/AcceptEnv pattern rather than automated, since "forward these vars" is meaningful only for an SSH-shaped harness command, not harness commands generically.

Test plan

  • cargo test -p buzz-acp --lib — 634/634 pass (11 new: session_cwd_* ×2, normalize_session_cwd_* ×2, resolve_session_cwd_tests::* ×2, plus existing suite)
  • cargo clippy -p buzz-acp --all-targets -- -D warnings — clean
  • cargo fmt -p buzz-acp -- --check — clean
  • cargo build -p sprig (the only other workspace crate depending on buzz-acp) — clean
  • cargo clippy -p sprig --all-targets -- -D warnings — clean
  • cargo fmt --all -- --check — clean
  • Desktop-tauri Rust changes (custom_harnesses.rs, readiness.rs, runtime.rs, spawn_hash.rs, discovery.rs) could not be locally compiled or tested — this sandbox has no GTK/WebKitGTK/pkg-config installed and no passwordless sudo to add them (the Linux prerequisites CONTRIBUTING.md lists for just desktop-tauri-*). cargo fmt --check on the touched files passed (valid syntax), and I manually re-verified every HarnessDefinition/EffectiveHarnessDescriptor struct-literal construction site and the borrow/move ordering in resolve_effective_harness_descriptor, but this is not a substitute for cargo test --manifest-path desktop/src-tauri/Cargo.toml and just desktop-tauri-fmt/clippy — needed before merge.
  • Manual verification: register a custom harness with "command": "ssh" and a "cwd" pointing at a real path on a remote host, confirm the first turn succeeds instead of failing with the cwd does not exist error.

🤖 Written by Claude, running as an agent inside Buzz (buzz-acp) — not the Claude Code CLI.

…e hosts

A harness whose command executes on another machine (e.g. `ssh` to a Linux
VM) can't complete its first turn today: buzz-acp always sends its own local
working directory as session/new's cwd, which the remote adapter rejects
since that path doesn't exist there.

Add an optional `cwd` field to the custom harness JSON schema, threaded
through the effective harness descriptor to a new BUZZ_ACP_SESSION_CWD env
var that buzz-acp uses in place of its own current_dir() when set.

Signed-off-by: Ivan Itzcovich <surfingdevs@gmail.com>
@surfingdev
surfingdev requested a review from a team as a code owner July 29, 2026 03:13
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