From 64fa41d49c33e8d50cb86f701cfc8b7568231eec Mon Sep 17 00:00:00 2001 From: "Y.U.K.I." Date: Sat, 18 Apr 2026 01:01:03 +0800 Subject: [PATCH] fix(tools): respect configured terminal cwd during init --- tests/tools/test_base_environment.py | 21 +++++++++++++++++++++ tools/environments/base.py | 10 ++++++++++ 2 files changed, 31 insertions(+) diff --git a/tests/tools/test_base_environment.py b/tests/tools/test_base_environment.py index 913ad0387c54..ba866edb79ef 100644 --- a/tests/tools/test_base_environment.py +++ b/tests/tools/test_base_environment.py @@ -141,6 +141,27 @@ def failing_run_bash(*args, **kwargs): assert env._snapshot_ready is False + def test_init_session_bootstraps_into_configured_cwd(self): + env = _TestableEnv(cwd="/custom/workspace") + calls = [] + + def mock_run_bash(cmd, *, login=False, timeout=120, stdin_data=None): + calls.append({"cmd": cmd, "login": login, "timeout": timeout}) + mock = MagicMock() + mock.poll.return_value = 0 + mock.returncode = 0 + mock.stdout = iter([]) + return mock + + env._run_bash = mock_run_bash + env._wait_for_process = lambda proc, timeout=120: {"output": f"\n{env._cwd_marker}/custom/workspace{env._cwd_marker}\n", "returncode": 0} + env.init_session() + + assert len(calls) == 1 + assert calls[0]["login"] is True + assert "cd /custom/workspace || exit 126" in calls[0]["cmd"] + assert env.cwd == "/custom/workspace" + def test_login_flag_when_snapshot_not_ready(self): """When _snapshot_ready=False, execute() should pass login=True to _run_bash.""" env = _TestableEnv() diff --git a/tools/environments/base.py b/tools/environments/base.py index 8e990792369f..350e51532d4d 100644 --- a/tools/environments/base.py +++ b/tools/environments/base.py @@ -320,6 +320,15 @@ def init_session(self): instead of running with ``bash -l``. """ # Full capture: env vars, functions (filtered), aliases, shell options. + # IMPORTANT: cd to the configured cwd before recording pwd. Otherwise the + # initial session cwd silently becomes the parent Python process cwd + # (e.g. a systemd WorkingDirectory or the shell dir that launched Hermes), + # which overrides TERMINAL_CWD / terminal.cwd for local sessions. + quoted_cwd = ( + shlex.quote(self.cwd) + if self.cwd != "~" and not self.cwd.startswith("~/") + else self.cwd + ) bootstrap = ( f"export -p > {self._snapshot_path}\n" f"declare -f | grep -vE '^_[^_]' >> {self._snapshot_path}\n" @@ -327,6 +336,7 @@ def init_session(self): f"echo 'shopt -s expand_aliases' >> {self._snapshot_path}\n" f"echo 'set +e' >> {self._snapshot_path}\n" f"echo 'set +u' >> {self._snapshot_path}\n" + f"cd {quoted_cwd} || exit 126\n" f"pwd -P > {self._cwd_file} 2>/dev/null || true\n" f"printf '\\n{self._cwd_marker}%s{self._cwd_marker}\\n' \"$(pwd -P)\"\n" )