From d70f0f1dc03fd5bd204c705093cfbc41d7f8f98b Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Tue, 21 Apr 2026 08:29:33 +0300 Subject: [PATCH] fix(docker): allow entrypoint to pass-through non-hermes commands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 8254b820 ("--init for zombie reaping + sleep infinity for idle-based lifetime") made the Docker terminal backend launch sandbox containers with `sleep infinity` as the command, so the lifetime is controlled by an external idle reaper instead of a fixed timeout. But `docker/entrypoint.sh` unconditionally wraps its args with `hermes`: exec hermes "$@" Result: `hermes sleep infinity` → argparse rejects `sleep` as a subcommand and the container exits immediately with code 2: hermes: error: argument command: invalid choice: 'sleep' (choose from chat, model, gateway, setup, ...) Every sandbox container launched by the docker backend dies at startup, breaking terminal/file tool execution end-to-end. Fix: dispatch at the tail of the entrypoint. If the first arg is an executable on PATH (sleep, bash, sh, etc.) run it raw; otherwise preserve the legacy `hermes ` wrapping behavior. Both invocation styles below keep working: docker run -> hermes (interactive) docker run chat -q "hi" -> hermes chat -q "hi" docker run sleep infinity -> sleep infinity docker run bash -> bash Co-Authored-By: Claude Opus 4.7 (1M context) --- docker/entrypoint.sh | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index c46497dcc..18f8fff4e 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -68,4 +68,19 @@ if [ -d "$INSTALL_DIR/skills" ]; then python3 "$INSTALL_DIR/tools/skills_sync.py" fi +# Final exec: two supported invocation patterns. +# +# docker run -> exec `hermes` with no args (legacy default) +# docker run chat -q "..." -> exec `hermes chat -q "..."` (legacy wrap) +# docker run sleep infinity -> exec `sleep infinity` directly +# docker run bash -> exec `bash` directly +# +# If the first positional arg resolves to an executable on PATH, we assume the +# caller wants to run it directly (needed by the launcher which runs long-lived +# `sleep infinity` sandbox containers — see tools/environments/docker.py). +# Otherwise we treat the args as a hermes subcommand and wrap with `hermes`, +# preserving the documented `docker run ` behavior. +if [ $# -gt 0 ] && command -v "$1" >/dev/null 2>&1; then + exec "$@" +fi exec hermes "$@"