"""Shell command execution tool with safety checks.""" from __future__ import annotations import subprocess from . import tool # Commands that are always blocked BLOCKED_PATTERNS = [ "rm -rf /", "format c:", ":(){:|:&};:", "dd if=/dev/zero", "mkfs.", "> /dev/sda", ] @tool("run_command", "Execute a shell command and return output", category="shell") def run_command(command: str, timeout: int = 30, ctx: dict | None = None) -> str: # Check require_approval setting if ctx and ctx.get("config") and ctx["config"].shell.require_approval: return ( "Shell commands require approval. Use the `delegate_task` tool instead — " "it routes through the execution brain which has its own safety controls." ) # Safety check cmd_lower = command.lower().strip() for pattern in BLOCKED_PATTERNS: if pattern in cmd_lower: return f"Blocked: command matches dangerous pattern '{pattern}'" try: result = subprocess.run( command, shell=True, capture_output=True, text=True, timeout=min(timeout, 120), encoding="utf-8", errors="replace", ) output = "" if result.stdout: output += result.stdout if result.stderr: output += f"\n[stderr]\n{result.stderr}" if result.returncode != 0: output += f"\n[exit code: {result.returncode}]" if len(output) > 10000: output = output[:10000] + "\n... (truncated)" return output.strip() or "(no output)" except subprocess.TimeoutExpired: return f"Command timed out after {timeout}s" except Exception as e: return f"Error running command: {e}"