diff --git a/nanobot/agent/tools/shell.py b/nanobot/agent/tools/shell.py index 2e0b606ab..e6e9ac0f5 100644 --- a/nanobot/agent/tools/shell.py +++ b/nanobot/agent/tools/shell.py @@ -96,6 +96,9 @@ class ExecTool(Tool): env = self._build_env() + if self.path_append: + command = f'export PATH="$PATH:{self.path_append}"; {command}' + bash = shutil.which("bash") or "/bin/bash" try: @@ -164,15 +167,11 @@ class ExecTool(Tool): secrets in env vars from leaking to LLM-generated commands. """ home = os.environ.get("HOME", "/tmp") - env: dict[str, str] = { + return { "HOME": home, "LANG": os.environ.get("LANG", "C.UTF-8"), "TERM": os.environ.get("TERM", "dumb"), } - if self.path_append: - # Seed PATH so the login shell can append to it. - env["PATH"] = self.path_append - return env def _guard_command(self, command: str, cwd: str) -> str | None: """Best-effort safety guard for potentially destructive commands.""" diff --git a/tests/tools/test_exec_env.py b/tests/tools/test_exec_env.py index 30358e688..e5c0f48bb 100644 --- a/tests/tools/test_exec_env.py +++ b/tests/tools/test_exec_env.py @@ -28,3 +28,11 @@ async def test_exec_path_append(): tool = ExecTool(path_append="/opt/custom/bin") result = await tool.execute(command="echo $PATH") assert "/opt/custom/bin" in result + + +@pytest.mark.asyncio +async def test_exec_path_append_preserves_system_path(): + """pathAppend must not clobber standard system paths.""" + tool = ExecTool(path_append="/opt/custom/bin") + result = await tool.execute(command="ls /") + assert "Exit code: 0" in result