# TUI — Shell Danger Detection The shell safety subsystem detects dangerous command patterns before execution in the TUI shell mode (`!` prefix). When a dangerous pattern is matched, the TUI surfaces a warning overlay so the user can confirm or abort before the command runs. Introduced in the [Unreleased] milestone (issue #1003). See also [`tui.md`](tui.md) for the overall TUI architecture. **Module**: `cleveragents.tui.shell_safety` --- ## Overview When the user types a shell command in the TUI (prefixed with `!`), the `DangerousPatternDetector` scans the command against a configurable registry of patterns before execution. If any patterns match, a warning is displayed with the danger level and a description of the risk. ``` ┌─────────────────────────────────────────────────────────────────┐ │ ⚠ Dangerous command detected │ │ │ │ [Critical] rm -rf / recursively deletes the entire filesystem │ │ root. This will destroy the operating system and all data. │ │ │ │ Command: rm -rf / │ │ │ │ [c] Cancel [p] Proceed anyway │ └─────────────────────────────────────────────────────────────────┘ ``` --- ## Domain Models ### `ShellDangerLevel` **Module**: `cleveragents.tui.shell_safety.danger_level` `IntEnum` classifying the severity of a dangerous shell command. Levels are ordered so that numeric comparisons work naturally (`level >= ShellDangerLevel.HIGH`). | Value | Int | Description | |-------|-----|-------------| | `LOW` | 1 | Minor risk — generally recoverable side-effects (e.g. `chmod 777` on a single file) | | `MEDIUM` | 2 | Moderate risk — can cause data loss or security exposure in common scenarios | | `HIGH` | 3 | High risk — significant, hard-to-reverse damage (e.g. `dd if=`, `mkfs`) | | `CRITICAL` | 4 | Critical risk — can destroy the entire system or create a fork bomb | ### `DangerousPattern` **Module**: `cleveragents.tui.shell_safety.dangerous_pattern` Immutable frozen dataclass describing a single dangerous shell pattern. | Field | Type | Default | Description | |-------|------|---------|-------------| | `name` | `str` | — | Short human-readable identifier (e.g. `"rm_rf_root"`) | | `pattern` | `str` | — | Regular expression matching the dangerous command text | | `level` | `ShellDangerLevel` | — | Danger severity classification | | `description` | `str` | — | Human-readable explanation of the risk | | `case_sensitive` | `bool` | `False` | When `True`, the regex is compiled without `re.IGNORECASE` | **Methods:** | Method | Returns | Description | |--------|---------|-------------| | `matches(command)` | `bool` | `True` if `command` matches this pattern | ### `DangerousCommandWarning` **Module**: `cleveragents.tui.shell_safety.warning` Immutable frozen dataclass produced by `DangerousPatternDetector` when a dangerous command is detected. | Field | Type | Description | |-------|------|-------------| | `command` | `str` | The original command string that triggered the warning | | `matched_pattern` | `DangerousPattern` | The pattern that matched | | `danger_level` | `ShellDangerLevel` | Convenience alias for `matched_pattern.level` | | `message` | `str` | Human-readable warning message for display | **Class methods:** | Method | Returns | Description | |--------|---------|-------------| | `from_pattern(command, pattern)` | `DangerousCommandWarning` | Construct a warning from a command and the matching pattern | --- ## `DangerousPatternDetector` **Module**: `cleveragents.tui.shell_safety.pattern_detector` Domain service that checks shell commands against a configurable registry of dangerous patterns. Ships with built-in `DEFAULT_PATTERNS` but supports full customisation. ### Constructor ```python DangerousPatternDetector(patterns: list[DangerousPattern] | None = None) ``` When `patterns` is `None`, the built-in `DEFAULT_PATTERNS` are used. ### Registry Management | Method | Returns | Description | |--------|---------|-------------| | `add_pattern(pattern)` | `None` | Append a pattern to the registry (checked in insertion order) | | `remove_pattern(name)` | `bool` | Remove the pattern with the given name; returns `True` if removed | | `replace_patterns(patterns)` | `None` | Replace the entire registry with a new list | | `patterns` *(property)* | `tuple[DangerousPattern, ...]` | Read-only view of the current registry | ### Detection | Method | Returns | Description | |--------|---------|-------------| | `check(command)` | `list[DangerousCommandWarning]` | All warnings for `command` (may be empty); ordered by insertion order | | `check_first(command)` | `DangerousCommandWarning \| None` | First (highest-priority) warning, or `None` | | `is_dangerous(command)` | `bool` | `True` if `command` matches any registered pattern | | `max_danger_level(command)` | `ShellDangerLevel \| None` | Highest danger level matched, or `None` | --- ## Default Pattern Registry **Module**: `cleveragents.tui.shell_safety.pattern_registry` The `DEFAULT_PATTERNS` tuple ships with the following built-in patterns: ### Critical | Name | Pattern | Description | |------|---------|-------------| | `rm_rf_root` | `rm -rf /` | Recursively deletes the entire filesystem root | | `rm_rf_wildcard` | `rm -rf /*` or `rm -rf *` | Deletes large portions of the filesystem | | `fork_bomb` | `:(){ :|:& };:` | Exhausts the process table, requiring a hard reboot | ### High | Name | Pattern | Description | |------|---------|-------------| | `dd_if_device` | `dd if=` | Can overwrite disk devices or fill storage | | `mkfs` | `mkfs` | Formats a filesystem, permanently erasing all data | | `shred_device` | `shred /dev/` or `shred --remove` | Overwrites data in an unrecoverable way | ### Medium | Name | Pattern | Description | |------|---------|-------------| | `chmod_777` | `chmod 777` | Grants world-readable/writable/executable permissions | | `sudo_rm` | `sudo rm` | Runs `rm` with elevated privileges | | `wget_pipe_sh` | `wget … \| sh` | Executes arbitrary remote code without inspection | | `curl_pipe_sh` | `curl … \| sh` | Executes arbitrary remote code without inspection | | `wget_pipe_bash` | `wget … \| bash` | Executes arbitrary remote code without inspection | | `curl_pipe_bash` | `curl … \| bash` | Executes arbitrary remote code without inspection | ### Low | Name | Pattern | Description | |------|---------|-------------| | `git_push_force` | `git push --force` | Overwrites remote history, causing data loss for collaborators | | `chmod_recursive_permissive` | `chmod -R 6xx/7xx` | Exposes sensitive files to unintended access | --- ## Usage Examples ### Basic detection ```python from cleveragents.tui.shell_safety.pattern_detector import DangerousPatternDetector detector = DangerousPatternDetector() # Check a command warnings = detector.check("rm -rf /") if warnings: print(warnings[0].message) # [Critical] Dangerous command detected: rm -rf / recursively deletes ... # Quick boolean check if detector.is_dangerous("sudo rm -rf /var/log"): print("Dangerous!") # Highest danger level level = detector.max_danger_level("wget http://example.com/script.sh | bash") print(level) # ShellDangerLevel.MEDIUM ``` ### Custom patterns ```python from cleveragents.tui.shell_safety.danger_level import ShellDangerLevel from cleveragents.tui.shell_safety.dangerous_pattern import DangerousPattern from cleveragents.tui.shell_safety.pattern_detector import DangerousPatternDetector detector = DangerousPatternDetector() # Add a custom pattern detector.add_pattern( DangerousPattern( name="drop_database", pattern=r"\bDROP\s+DATABASE\b", level=ShellDangerLevel.CRITICAL, description="DROP DATABASE permanently deletes the entire database.", case_sensitive=False, ) ) # Remove a built-in pattern detector.remove_pattern("git_push_force") ``` --- ## Integration with Shell Mode The `DangerousPatternDetector` is invoked by the TUI shell mode handler (`cleveragents.tui.input.shell_exec`) before any subprocess is started. If `check_first()` returns a warning, the TUI presents a confirmation overlay before proceeding. The shell mode is entered by typing `!` at the prompt. See [Shell Mode](tui.md#shell-mode) in the TUI reference for the full shell mode documentation. --- ## Related Documentation - [TUI Reference](tui.md) — overall TUI architecture and shell mode - [TUI Permissions Screen](tui_permissions.md) — full-screen permission overlay - [TUI Permission Question Widget](tui_permission_question.md) — inline permission widget