Add reference documentation for three new TUI features: - docs/reference/tui_shell_safety.md: Full reference for the shell danger detection subsystem (DangerousPatternDetector, ShellDangerLevel, DangerousPattern, DangerousCommandWarning, DEFAULT_PATTERNS registry). Covers all built-in patterns across CRITICAL/HIGH/MEDIUM/LOW levels, usage examples, and custom pattern extension. - docs/reference/tui_permission_question.md: Full reference for the inline PermissionQuestionWidget (issue #997). Documents InlinePermissionQuestion, PermissionRequestType, PermissionDecision, render_permission_question(), PermissionDecisionEvent, and PermissionQuestionWidget with key bindings and usage examples. - docs/reference/tui.md: Extended with First-Run Experience section (ActorSelectionOverlay, first_run helpers), Inline Permission Questions section, shell danger detection note in Shell Mode, updated module table, and links to new reference pages.
9.0 KiB
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 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
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 |
`:(){ : | :& };:` |
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
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
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 in the TUI reference for the full
shell mode documentation.
Related Documentation
- TUI Reference — overall TUI architecture and shell mode
- TUI Permissions Screen — full-screen permission overlay
- TUI Permission Question Widget — inline permission widget