Revert "fix(cli): CLI/TUI on local backend always uses launch directory, ignores terminal.cwd (#19242)" (#19329)

This reverts commit 9eaddfafa3.
This commit is contained in:
Siddharth Balyan 2026-05-04 00:43:58 +05:30 committed by GitHub
parent 9eaddfafa3
commit 167b5648ea
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 72 additions and 122 deletions

View file

@ -1,12 +1,12 @@
"""Tests that load_cli_config() CWD resolution works correctly.
"""Tests that load_cli_config() guards against lazy-import TERMINAL_CWD clobbering.
The rule:
- CLI/TUI on local backend: ALWAYS use os.getcwd() (config ignored).
- Gateway (TERMINAL_CWD pre-set to absolute path): respect it.
- Non-local backends with placeholder: pop cwd for backend default.
- Non-local backends with explicit path: keep it.
When the gateway resolves TERMINAL_CWD at startup and cli.py is later
imported lazily (via delegate_tool CLI_CONFIG), load_cli_config() must
not overwrite the already-resolved value with os.getcwd().
See issues #19214, #4672, #10225, #10817.
config.yaml terminal.cwd is the canonical source of truth.
.env TERMINAL_CWD and MESSAGING_CWD are deprecated.
See issue #10817.
"""
import os
@ -20,29 +20,21 @@ _CWD_PLACEHOLDERS = (".", "auto", "cwd")
def _resolve_terminal_cwd(terminal_config: dict, defaults: dict, env: dict):
"""Simulate the CWD resolution logic from load_cli_config().
This mirrors the code in cli.py that handles the CWD resolution
based on mode (CLI vs gateway) and backend type.
This mirrors the code in cli.py that checks for a pre-resolved
TERMINAL_CWD before falling back to os.getcwd().
"""
_existing_cwd = env.get("TERMINAL_CWD", "")
_is_gateway_import = (
_existing_cwd
and _existing_cwd not in _CWD_PLACEHOLDERS
and os.path.isabs(_existing_cwd)
)
effective_backend = terminal_config.get("env_type", "local")
if _is_gateway_import:
# Gateway already resolved a real path — keep it.
terminal_config["cwd"] = _existing_cwd
defaults["terminal"]["cwd"] = _existing_cwd
elif effective_backend == "local":
# CLI/TUI on local backend: always use launch directory.
terminal_config["cwd"] = "/fake/getcwd" # stand-in for os.getcwd()
defaults["terminal"]["cwd"] = terminal_config["cwd"]
elif terminal_config.get("cwd") in _CWD_PLACEHOLDERS:
# Non-local backend with placeholder — pop for backend default.
terminal_config.pop("cwd", None)
# else: non-local backend with explicit path — keep as-is
if terminal_config.get("cwd") in _CWD_PLACEHOLDERS:
_existing_cwd = env.get("TERMINAL_CWD", "")
if _existing_cwd and _existing_cwd not in _CWD_PLACEHOLDERS and os.path.isabs(_existing_cwd):
terminal_config["cwd"] = _existing_cwd
defaults["terminal"]["cwd"] = _existing_cwd
else:
effective_backend = terminal_config.get("env_type", "local")
if effective_backend == "local":
terminal_config["cwd"] = "/fake/getcwd" # stand-in for os.getcwd()
defaults["terminal"]["cwd"] = terminal_config["cwd"]
else:
terminal_config.pop("cwd", None)
# Simulate the bridging loop: write terminal_config["cwd"] to env
_file_has_terminal = defaults.get("_file_has_terminal", False)
@ -74,36 +66,18 @@ class TestLazyImportGuard:
result = _resolve_terminal_cwd(terminal_config, defaults, env)
assert result == "/home/user/workspace"
def test_gateway_resolved_cwd_survives_even_with_explicit_config(self):
"""Gateway pre-set TERMINAL_CWD wins even when config has explicit path.
This is the key scenario: config.yaml has terminal.cwd: /home/user
(from hermes setup), but the gateway already resolved TERMINAL_CWD.
The gateway's value must win.
"""
env = {"TERMINAL_CWD": "/home/user/workspace"}
terminal_config = {"cwd": "/home/user", "env_type": "local"}
defaults = {"terminal": {"cwd": "/home/user"}, "_file_has_terminal": True}
class TestConfigCwdResolution:
"""config.yaml terminal.cwd is the canonical source of truth."""
result = _resolve_terminal_cwd(terminal_config, defaults, env)
assert result == "/home/user/workspace"
class TestCliAlwaysUsesGetcwd:
"""CLI/TUI on local backend always uses os.getcwd(), ignoring config."""
def test_explicit_config_cwd_ignored_on_local_cli(self):
"""terminal.cwd: /explicit/path is IGNORED for CLI on local backend.
This is the #19214 fix — 'hermes setup' may have written an absolute
path, but CLI always uses os.getcwd() (the user's launch directory).
"""
env = {} # No pre-set TERMINAL_CWD = CLI mode
terminal_config = {"cwd": "/explicit/path", "env_type": "local"}
def test_explicit_config_cwd_wins(self):
"""terminal.cwd: /explicit/path always wins."""
env = {"TERMINAL_CWD": "/old/gateway/value"}
terminal_config = {"cwd": "/explicit/path"}
defaults = {"terminal": {"cwd": "/explicit/path"}, "_file_has_terminal": True}
result = _resolve_terminal_cwd(terminal_config, defaults, env)
assert result == "/fake/getcwd" # os.getcwd(), NOT /explicit/path
assert result == "/explicit/path"
def test_dot_cwd_resolves_to_getcwd_when_no_prior(self):
"""With no pre-set TERMINAL_CWD, "." resolves to os.getcwd()."""
@ -114,20 +88,7 @@ class TestCliAlwaysUsesGetcwd:
result = _resolve_terminal_cwd(terminal_config, defaults, env)
assert result == "/fake/getcwd"
def test_home_dir_config_ignored_on_local_cli(self):
"""terminal.cwd: ~ (home dir from setup) is ignored for CLI."""
env = {}
terminal_config = {"cwd": "/home/daimon", "env_type": "local"}
defaults = {"terminal": {"cwd": "/home/daimon"}, "_file_has_terminal": True}
result = _resolve_terminal_cwd(terminal_config, defaults, env)
assert result == "/fake/getcwd"
class TestNonLocalBackends:
"""Non-local backends use config or per-backend defaults."""
def test_remote_backend_pops_placeholder_cwd(self):
def test_remote_backend_pops_cwd(self):
"""Remote backend + placeholder cwd → popped for backend default."""
env = {}
terminal_config = {"cwd": ".", "env_type": "docker"}
@ -136,15 +97,6 @@ class TestNonLocalBackends:
result = _resolve_terminal_cwd(terminal_config, defaults, env)
assert result == "" # cwd popped, no env var set
def test_remote_backend_keeps_explicit_path(self):
"""Remote backend + explicit path → kept (e.g. SSH cwd: /srv/app)."""
env = {}
terminal_config = {"cwd": "/srv/myproject", "env_type": "ssh"}
defaults = {"terminal": {"cwd": "/srv/myproject"}, "_file_has_terminal": True}
result = _resolve_terminal_cwd(terminal_config, defaults, env)
assert result == "/srv/myproject"
def test_remote_backend_with_prior_cwd_preserves(self):
"""Remote backend + pre-resolved TERMINAL_CWD → adopted."""
env = {"TERMINAL_CWD": "/project"}