Feature: TUI Shell Danger Detection As a TUI user I want dangerous shell commands to be detected and warned about So that I can avoid accidentally running destructive commands Background: Given the shell safety module is imported # ── Danger level enum ──────────────────────────────────────────────────── Scenario: ShellDangerLevel enum has four levels Then the ShellDangerLevel enum should have levels LOW MEDIUM HIGH CRITICAL Scenario: ShellDangerLevel levels are ordered by severity Then LOW should be less severe than MEDIUM And MEDIUM should be less severe than HIGH And HIGH should be less severe than CRITICAL # ── DangerousPattern value object ──────────────────────────────────────── Scenario: DangerousPattern matches a dangerous command Given a DangerousPattern named "test_rm" with pattern "rm -rf" at CRITICAL level When I check if "rm -rf /" matches the pattern Then the pattern should match Scenario: DangerousPattern does not match a safe command Given a DangerousPattern named "test_rm" with pattern "rm -rf" at CRITICAL level When I check if "ls -la" matches the pattern Then the pattern should not match Scenario: DangerousPattern is case-insensitive by default Given a DangerousPattern named "test_rm" with pattern "rm -rf" at CRITICAL level When I check if "RM -RF /" matches the pattern Then the pattern should match # ── DangerousCommandWarning value object ───────────────────────────────── Scenario: DangerousCommandWarning is created from a pattern Given a DangerousPattern named "rm_root" with pattern "rm -rf /" at CRITICAL level When I create a warning for command "rm -rf /" from the pattern Then the warning command should be "rm -rf /" And the warning danger level should be CRITICAL And the warning message should contain "Critical" And the warning message should contain "Dangerous command detected" Scenario: DangerousCommandWarning message includes pattern description Given a DangerousPattern named "fork_bomb" with pattern ":(){" at CRITICAL level and description "Fork bomb" When I create a warning for command ":(){ :|:& };:" from the pattern Then the warning message should contain "Fork bomb" # ── DangerousPatternDetector ───────────────────────────────────────────── Scenario: Detector uses default patterns when none provided Given a DangerousPatternDetector with default patterns Then the detector should have patterns registered Scenario: Detector detects rm -rf root as CRITICAL Given a DangerousPatternDetector with default patterns When I check the command "rm -rf /" Then the command should be detected as dangerous And the max danger level should be CRITICAL Scenario: Detector detects rm -rf wildcard as CRITICAL Given a DangerousPatternDetector with default patterns When I check the command "rm -rf /*" Then the command should be detected as dangerous And the max danger level should be CRITICAL Scenario: Detector detects fork bomb as CRITICAL Given a DangerousPatternDetector with default patterns When I check the command ":(){ :|:& };:" Then the command should be detected as dangerous And the max danger level should be CRITICAL Scenario: Detector detects dd if= as HIGH Given a DangerousPatternDetector with default patterns When I check the command "dd if=/dev/zero of=/dev/sda" Then the command should be detected as dangerous And the max danger level should be HIGH Scenario: Detector detects mkfs as HIGH Given a DangerousPatternDetector with default patterns When I check the command "mkfs.ext4 /dev/sdb1" Then the command should be detected as dangerous And the max danger level should be HIGH Scenario: Detector detects chmod 777 as MEDIUM Given a DangerousPatternDetector with default patterns When I check the command "chmod 777 /etc/passwd" Then the command should be detected as dangerous And the max danger level should be MEDIUM Scenario: Detector detects sudo rm as MEDIUM Given a DangerousPatternDetector with default patterns When I check the command "sudo rm file.txt" Then the command should be detected as dangerous And the max danger level should be MEDIUM Scenario: Detector detects wget piped to sh as MEDIUM Given a DangerousPatternDetector with default patterns When I check the command "wget http://example.com/install.sh | sh" Then the command should be detected as dangerous And the max danger level should be MEDIUM Scenario: Detector detects curl piped to sh as MEDIUM Given a DangerousPatternDetector with default patterns When I check the command "curl http://example.com/install.sh | sh" Then the command should be detected as dangerous And the max danger level should be MEDIUM Scenario: Detector detects curl piped to bash as MEDIUM Given a DangerousPatternDetector with default patterns When I check the command "curl https://get.example.com | bash" Then the command should be detected as dangerous And the max danger level should be MEDIUM Scenario: Detector detects git push force as LOW Given a DangerousPatternDetector with default patterns When I check the command "git push --force origin main" Then the command should be detected as dangerous And the max danger level should be LOW Scenario: Safe commands pass through without warnings Given a DangerousPatternDetector with default patterns When I check the command "ls -la" Then the command should not be detected as dangerous Scenario: Safe commands - echo passes through Given a DangerousPatternDetector with default patterns When I check the command "echo hello world" Then the command should not be detected as dangerous Scenario: Safe commands - git status passes through Given a DangerousPatternDetector with default patterns When I check the command "git status" Then the command should not be detected as dangerous Scenario: Safe commands - python script passes through Given a DangerousPatternDetector with default patterns When I check the command "python script.py" Then the command should not be detected as dangerous Scenario: check_first returns the first matching warning Given a DangerousPatternDetector with default patterns When I call check_first on "rm -rf /" Then check_first should return a warning And the first warning danger level should be CRITICAL Scenario: check_first returns None for safe commands Given a DangerousPatternDetector with default patterns When I call check_first on "ls -la" Then check_first should return None Scenario: check returns all matching warnings Given a DangerousPatternDetector with default patterns When I call check on "rm -rf /" Then check should return at least one warning Scenario: Pattern registry is configurable - add pattern Given a DangerousPatternDetector with default patterns When I add a custom pattern named "custom_test" with pattern "evil_command" at HIGH level And I check the command "evil_command --destroy" Then the command should be detected as dangerous Scenario: Pattern registry is configurable - remove pattern Given a DangerousPatternDetector with default patterns When I remove the pattern named "git_push_force" And I check the command "git push --force origin main" Then the command should not be detected as dangerous Scenario: Pattern registry is configurable - replace patterns Given a DangerousPatternDetector with default patterns When I replace all patterns with a single pattern named "only_one" matching "special_cmd" at LOW level And I check the command "rm -rf /" Then the command should not be detected as dangerous When I check the command "special_cmd" Then the command should be detected as dangerous Scenario: Detector patterns property returns current registry Given a DangerousPatternDetector with default patterns Then the detector patterns property should return a tuple # ── ShellSafetyService ─────────────────────────────────────────────────── Scenario: ShellSafetyService allows safe commands Given a ShellSafetyService with default settings When I check the safety of command "ls -la" Then the safety check result should be allowed And the safety check warning should be None Scenario: ShellSafetyService blocks dangerous commands above block level Given a ShellSafetyService with default settings When I check the safety of command "rm -rf /" Then the safety check result should be blocked And the safety check warning should not be None Scenario: ShellSafetyService uses warn_callback when provided Given a ShellSafetyService with a warn_callback that returns True When I check the safety of command "rm -rf /" Then the safety check result should be allowed And the warn_callback should have been called Scenario: ShellSafetyService blocks when warn_callback returns False Given a ShellSafetyService with a warn_callback that returns False When I check the safety of command "rm -rf /" Then the safety check result should be blocked And the warn_callback should have been called Scenario: ShellSafetyService is_safe returns True for safe commands Given a ShellSafetyService with default settings When I call is_safe on "echo hello" Then is_safe should return True Scenario: ShellSafetyService is_safe returns False for dangerous commands Given a ShellSafetyService with default settings When I call is_safe on "rm -rf /" Then is_safe should return False Scenario: ShellSafetyService exposes detector property Given a ShellSafetyService with default settings Then the service detector property should be a DangerousPatternDetector Scenario: ShellSafetyService exposes block_level property Given a ShellSafetyService with default settings Then the service block_level should be MEDIUM Scenario: ShellSafetyService accepts extra_patterns Given a ShellSafetyService with an extra pattern "custom_danger" matching "forbidden_cmd" at HIGH level When I check the safety of command "forbidden_cmd --run" Then the safety check result should be blocked Scenario: SafetyCheckResult repr includes command and allowed status Given a ShellSafetyService with default settings When I check the safety of command "ls -la" Then the safety check result repr should contain "ls -la" And the safety check result repr should contain "allowed=True"