diff --git a/bot_bottle/contrib/claude/Dockerfile b/bot_bottle/contrib/claude/Dockerfile index 4c30481..4abc514 100644 --- a/bot_bottle/contrib/claude/Dockerfile +++ b/bot_bottle/contrib/claude/Dockerfile @@ -25,6 +25,7 @@ RUN apt-get update \ git \ ca-certificates \ curl \ + openssh-client \ podman \ ripgrep \ iproute2 \ diff --git a/bot_bottle/contrib/codex/Dockerfile b/bot_bottle/contrib/codex/Dockerfile index 36d9507..16414c2 100644 --- a/bot_bottle/contrib/codex/Dockerfile +++ b/bot_bottle/contrib/codex/Dockerfile @@ -10,6 +10,7 @@ RUN apt-get update \ git \ ca-certificates \ curl \ + openssh-client \ podman \ procps \ ripgrep \ diff --git a/bot_bottle/contrib/pi/Dockerfile b/bot_bottle/contrib/pi/Dockerfile index 9036c92..aa24671 100644 --- a/bot_bottle/contrib/pi/Dockerfile +++ b/bot_bottle/contrib/pi/Dockerfile @@ -10,6 +10,7 @@ RUN apt-get update \ ca-certificates \ curl \ fd-find \ + openssh-client \ podman \ ripgrep \ && ln -s /usr/bin/fdfind /usr/local/bin/fd \ diff --git a/docs/prds/prd-new-modernize-built-in-agent-images.md b/docs/prds/prd-new-modernize-built-in-agent-images.md index 4a5d3fd..788b552 100644 --- a/docs/prds/prd-new-modernize-built-in-agent-images.md +++ b/docs/prds/prd-new-modernize-built-in-agent-images.md @@ -24,6 +24,7 @@ modify the bottle or cannot run at all. - Every Dockerfile under `bot_bottle/contrib/*/Dockerfile` explicitly inherits `node:22-trixie-slim`, based on Debian 13 (the current stable release). - Every built-in agent image installs Podman from Debian stable. +- Every built-in agent image retains an SSH client for Git-over-SSH workflows. - A shared test enforces both requirements for current and future built-in providers. diff --git a/tests/integration/test_sandbox_escape.py b/tests/integration/test_sandbox_escape.py index 29b7608..de52e5f 100644 --- a/tests/integration/test_sandbox_escape.py +++ b/tests/integration/test_sandbox_escape.py @@ -172,7 +172,7 @@ class TestSandboxEscape(unittest.TestCase): # base image without producing five confusing # command-not-found failures down the suite. missing: list[str] = [] - for tool in ("curl", "git", "dig"): + for tool in ("curl", "git", "dig", "ssh"): r = cls._bottle.exec(f"command -v {tool} >/dev/null 2>&1") if r.returncode != 0: missing.append(tool) diff --git a/tests/unit/test_builtin_agent_images.py b/tests/unit/test_builtin_agent_images.py index 45c5024..df9ab68 100644 --- a/tests/unit/test_builtin_agent_images.py +++ b/tests/unit/test_builtin_agent_images.py @@ -29,6 +29,14 @@ class TestBuiltinAgentImages(unittest.TestCase): re.compile(r"(?m)^\s*podman(?:\s|\\|$)"), ) + def test_all_install_ssh_client(self): + for dockerfile in _AGENT_DOCKERFILES: + with self.subTest(provider=dockerfile.parent.name): + self.assertRegex( + dockerfile.read_text(), + re.compile(r"(?m)^\s*openssh-client(?:\s|\\|$)"), + ) + if __name__ == "__main__": unittest.main()