Terminal
8.1. Terminal — Executing Shell Commands
Seven backends to choose from
Local, Docker, SSH, Singularity, Modal, Daytona, and Vercel Sandbox. Daytona and Modal have “serverless persistence” — the environment sleeps when idle and wakes on demand, costing almost nothing between uses.
terminal:
backend: docker
Whether shell state persists — depends on the backend
With Local and SSH, persistent_shell: true (the default) keeps a single bash process alive across many commands — cd, environment variables, and aliases all survive between calls. Docker works very differently: Hermes starts one long-lived container (docker run -d ... sleep infinity), and every terminal/file/execute_code command is routed through docker exec into that same container — a package pip installed once is still there on the next call, and a directory you cded into is preserved across /new, /reset, and even sub-agents spawned from delegate_task.
Two background-running modes
process(action="wait") # wait for a background command to finish
process(action="poll") # check progress without blocking
For interactive CLI tools that need a pseudo-terminal (Python REPL, Claude Code…), use pty=true.
Notes
- For untrusted content (unknown repos, unverified MCP servers), always switch to the Docker/Daytona backend — the container then becomes the security boundary, and since the dangerous-command checks in chapter 6.3 are bypassed, the container must genuinely be well isolated.
- PTY mode has
\rvs\nissues with apps built onprompt_toolkit— prefertmuxfor spawning interactive processes rather than using a direct PTY. - The Docker backend does not mount the host’s current working directory into the container by default — you must opt in explicitly via
docker_volumesif you want the agent to work directly on host files.