refactor(ssh): extract shared _is_ssh_remote_tilde_cwd predicate

Follow-up to the salvaged SSH-tilde-cwd fix. The predicate
"backend == ssh and (cwd == ~ or cwd.startswith(~/))" was inlined at
each expanduser guard site, which is how the test simulator drifted from
production (it grew an SSH guard on a top-level-alias branch that has no
production counterpart).

- Add tools/terminal_tool._is_ssh_remote_tilde_cwd(backend, cwd) as the
  single source of truth (case/whitespace-tolerant).
- Use it in _get_env_config and the gateway config bridge.
- Test simulator imports the real helper instead of re-implementing the
  predicate; revert the phantom SSH guard on the top-level-alias branch
  (production maps top-level cwd: to a plain env var, not TERMINAL_CWD via
  an SSH-guarded path — that branch tested nothing real).
This commit is contained in:
kshitijk4poor 2026-07-04 14:03:32 +05:30 committed by kshitij
parent 83fb8ec277
commit 4651ac64a1
3 changed files with 26 additions and 21 deletions

View file

@ -1481,13 +1481,11 @@ if _config_path.exists():
# never receives a literal "~/" which the kernel rejects.
# SSH cwd is interpreted by the remote shell, so preserve
# "~" / "~/..." for the SSH backend instead of expanding it
# to the Hermes host/container HOME (often /opt/data).
# to the Hermes host/container HOME (often /opt/data). Shared
# predicate with terminal_tool so the two sites can't drift.
if _cfg_key == "cwd" and isinstance(_val, str):
_raw_cwd = _val.strip()
if not (
_terminal_backend == "ssh"
and (_raw_cwd == "~" or _raw_cwd.startswith("~/"))
):
from tools.terminal_tool import _is_ssh_remote_tilde_cwd
if not _is_ssh_remote_tilde_cwd(_terminal_backend, _val.strip()):
_val = os.path.expanduser(_val)
if isinstance(_val, (list, dict)):
os.environ[_env_var] = json.dumps(_val)

View file

@ -12,6 +12,8 @@ asserting the expected env var outcomes.
import os
import json
from tools.terminal_tool import _is_ssh_remote_tilde_cwd
def _simulate_config_bridge(cfg: dict, initial_env: dict | None = None):
"""Simulate the gateway config bridge logic from gateway/run.py.
@ -51,12 +53,9 @@ def _simulate_config_bridge(cfg: dict, initial_env: dict | None = None):
# Expand shell tilde for local/container backends so subprocess.Popen
# never receives a literal "~/" which the kernel rejects. SSH cwd is
# interpreted by the remote shell, so preserve "~" / "~/..." there.
# Uses the same production predicate as gateway/run.py.
if cfg_key == "cwd" and isinstance(val, str):
raw_cwd = val.strip()
if not (
terminal_backend == "ssh"
and (raw_cwd == "~" or raw_cwd.startswith("~/"))
):
if not _is_ssh_remote_tilde_cwd(terminal_backend, val.strip()):
val = os.path.expanduser(val)
if isinstance(val, list):
env[env_var] = json.dumps(val)
@ -73,15 +72,7 @@ def _simulate_config_bridge(cfg: dict, initial_env: dict | None = None):
alias_val = cfg.get(alias_key)
if isinstance(alias_val, str) and alias_val.strip():
if alias_key == "cwd":
alias_backend = str(
cfg.get("backend") or env.get("TERMINAL_ENV") or ""
).strip().lower()
raw_cwd = alias_val.strip()
if not (
alias_backend == "ssh"
and (raw_cwd == "~" or raw_cwd.startswith("~/"))
):
alias_val = os.path.expanduser(alias_val)
alias_val = os.path.expanduser(alias_val)
env[alias_env] = alias_val.strip()
# --- Replicate lines 144-147: MESSAGING_CWD fallback ---

View file

@ -1216,6 +1216,22 @@ _HOST_CWD_PREFIXES = ("/Users/", "/home/", "C:\\", "C:/")
_CONTAINER_BACKENDS = frozenset({"docker", "singularity", "modal", "daytona"})
def _is_ssh_remote_tilde_cwd(backend: str, cwd: str) -> bool:
"""Return True when *cwd* is a tilde path that the remote SSH shell must
expand itself, so the Hermes host/container must NOT ``expanduser`` it.
SSH ``cwd`` is interpreted by the *remote* shell (``cd ~`` / ``cd ~/x``
over ``ssh ... bash -c``). Expanding ``~`` locally would rewrite it to the
Hermes host HOME (often ``/opt/data`` under Docker) and inject a
nonexistent path into the remote session. Only ``~`` / ``~/...`` on the
``ssh`` backend qualify; absolute remote paths still pass through
unchanged, and every other backend keeps expanding locally.
"""
if (backend or "").strip().lower() != "ssh":
return False
return cwd == "~" or cwd.startswith("~/")
def _is_unusable_container_cwd(cwd: str) -> bool:
"""Return True if *cwd* is a host/relative path that won't work as the
working directory inside a container sandbox.
@ -1286,7 +1302,7 @@ def _get_env_config() -> Dict[str, Any]:
# /workspace and track the original host path separately. Otherwise keep the
# normal sandbox behavior and discard host paths.
cwd = os.getenv("TERMINAL_CWD", default_cwd)
if cwd and not (env_type == "ssh" and (cwd == "~" or cwd.startswith("~/"))):
if cwd and not _is_ssh_remote_tilde_cwd(env_type, cwd):
cwd = os.path.expanduser(cwd)
host_cwd = None
if env_type == "docker" and mount_docker_cwd: