diff --git a/tests/tools/test_approval.py b/tests/tools/test_approval.py index 22ad88a8c..bdd2b5284 100644 --- a/tests/tools/test_approval.py +++ b/tests/tools/test_approval.py @@ -4,6 +4,7 @@ from unittest.mock import patch as mock_patch import tools.approval as approval_module from tools.approval import ( + _get_approval_mode, approve_session, clear_session, detect_dangerous_command, @@ -16,6 +17,16 @@ from tools.approval import ( ) +class TestApprovalModeParsing: + def test_unquoted_yaml_off_boolean_false_maps_to_off(self): + with mock_patch("hermes_cli.config.load_config", return_value={"approvals": {"mode": False}}): + assert _get_approval_mode() == "off" + + def test_string_off_still_maps_to_off(self): + with mock_patch("hermes_cli.config.load_config", return_value={"approvals": {"mode": "off"}}): + assert _get_approval_mode() == "off" + + class TestDetectDangerousRm: def test_rm_rf_detected(self): is_dangerous, key, desc = detect_dangerous_command("rm -rf /home/user") diff --git a/tools/approval.py b/tools/approval.py index 233df07a2..ea814e5ce 100644 --- a/tools/approval.py +++ b/tools/approval.py @@ -280,12 +280,28 @@ def prompt_dangerous_approval(command: str, description: str, sys.stdout.flush() +def _normalize_approval_mode(mode) -> str: + """Normalize approval mode values loaded from YAML/config. + + YAML 1.1 treats bare words like `off` as booleans, so a config entry like + `approvals:\n mode: off` is parsed as False unless quoted. Treat that as the + intended string mode instead of falling back to manual approvals. + """ + if isinstance(mode, bool): + return "off" if mode is False else "manual" + if isinstance(mode, str): + normalized = mode.strip().lower() + return normalized or "manual" + return "manual" + + def _get_approval_mode() -> str: """Read the approval mode from config. Returns 'manual', 'smart', or 'off'.""" try: from hermes_cli.config import load_config config = load_config() - return config.get("approvals", {}).get("mode", "manual") + mode = config.get("approvals", {}).get("mode", "manual") + return _normalize_approval_mode(mode) except Exception: return "manual"