From a26692612d361ad3ca53ebcca1606b6af406c168 Mon Sep 17 00:00:00 2001 From: Lee Jackson <130007945+Imagineer99@users.noreply.github.com> Date: Thu, 23 Jul 2026 23:54:09 +0100 Subject: [PATCH] Normalize PWD for POSIX agent launches (#7110) Keep the child process environment consistent with the cwd used to launch native POSIX coding agents. Some Node-based agents use PWD during project-root discovery, so inheriting a stale PWD can make them edit files in a parent or unrelated directory even when the wrapper process cwd is correct. Only apply this normalization for native POSIX launches. WSL-launched Windows shims stay on the existing WSLENV bridge path so path translation behavior is unchanged. Add regression coverage that launches an agent with a deliberately stale inherited PWD and asserts the child environment is normalized to os.getcwd(). Co-authored-by: Leo Borcherding --- unsloth_cli/commands/start.py | 5 +++++ unsloth_cli/tests/test_start.py | 21 +++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/unsloth_cli/commands/start.py b/unsloth_cli/commands/start.py index 01dffa0634..7c768d16f5 100644 --- a/unsloth_cli/commands/start.py +++ b/unsloth_cli/commands/start.py @@ -2110,6 +2110,11 @@ def _launch( for name in unset_env: child_env.pop(name, None) child_env.update(env) + if os.name != "nt" and not wsl_env_bridge: + # Keep POSIX child processes from seeing a stale inherited PWD when + # subprocess cwd was changed by the caller. Some Node CLIs use PWD for + # project-root discovery instead of process.cwd(). + child_env["PWD"] = os.getcwd() # Ctrl+C cancels a turn inside the agent; don't let it kill this wrapper. previous = signal.signal(signal.SIGINT, signal.SIG_IGN) try: diff --git a/unsloth_cli/tests/test_start.py b/unsloth_cli/tests/test_start.py index e76ae24f8b..36a5e51938 100644 --- a/unsloth_cli/tests/test_start.py +++ b/unsloth_cli/tests/test_start.py @@ -874,6 +874,27 @@ def test_connect_claude_compact_window_omitted_without_context(fake_studio, monk assert "CLAUDE_AUTOCOMPACT_PCT_OVERRIDE" not in result.output +def test_launch_native_posix_child_gets_current_pwd(fake_studio, monkeypatch, tmp_path): + captured = {} + monkeypatch.chdir(tmp_path) + monkeypatch.setenv("PWD", "/stale/outer/repo") + monkeypatch.setattr(start.shutil, "which", lambda _: "/usr/local/bin/opencode") + + def run(command, env): + captured["command"] = command + captured["env"] = env + return SimpleNamespace(returncode = 0) + + monkeypatch.setattr(start.subprocess, "run", run) + + result = CliRunner().invoke(start.start_app, ["opencode"]) + + assert result.exit_code == 0, result.output + assert captured["command"][0] == "/usr/local/bin/opencode" + if os.name != "nt": + assert captured["env"]["PWD"] == os.getcwd() + + def test_connect_claude_launch_scrubs_conflicting_auth_env(fake_studio, monkeypatch): captured = {} monkeypatch.setenv("ANTHROPIC_API_KEY", "sk-anthropic-stale")