""" Command line execution tool for Clover - A terminal assistant for AI-powered project management """ import shlex import subprocess import sys import os from pathlib import Path # Whitelist of allowed commands for safe execution ALLOWED_COMMANDS = { "ls", "cat", "echo", "pwd", "date", "whoami", "id", "git", "python", "python3", "node", "npm", "pip", "pip3", "mkdir", "cp", "mv", "rm", "touch", "chmod", "chown", "grep", "find", "head", "tail", "wc", "sort", "uniq", "diff", "make", "cmake", "cargo", "go", "rustc", "docker", "docker-compose", "curl", "wget", "ps", "top", "df", "free", "uname", "which", "whereis", "type", "test", "stat", "file", "bash", "sh", "zsh", "vim", "nano", "less", "more", "tar", "zip", "unzip", "gzip", "gunzip", "sed", "awk", "tr", "cut", "paste", "join", "comm", "xargs", "tee", "yes", "seq", "bc", } def commandline(command, allow_execution=True): """ Execute a system command with user permission. Uses shell=False with shlex.split() to prevent command injection. The first word of the command must be in the ALLOWED_COMMANDS whitelist. Args: command (str): The command to execute allow_execution (bool): Whether execution is allowed (default: True) Returns: str: Output of the command or permission prompt Raises: PermissionError: If execution is not permitted or command not whitelisted subprocess.CalledProcessError: If command execution fails """ if not allow_execution: return f"Command execution denied. Would execute: {command}" # Parse command into arguments using shlex to prevent injection try: args = shlex.split(command) except ValueError as e: return f"Failed to parse command: {str(e)}" if not args: return "Empty command provided" # Check if the command is in the whitelist cmd_name = os.path.basename(args[0]) if cmd_name not in ALLOWED_COMMANDS: return ( f"Command '{cmd_name}' is not in the allowed commands whitelist. " f"Allowed commands: {', '.join(sorted(ALLOWED_COMMANDS))}" ) try: print(f"Executing command: {command}") # Execute the command with shell=False to prevent injection result = subprocess.run( args, shell=False, check=True, text=True, capture_output=True, timeout=300, # 5 minute timeout ) return result.stdout except subprocess.CalledProcessError as e: error_msg = f"Command failed with return code {e.returncode}\n" if e.stderr: error_msg += f"Error output: {e.stderr}" return error_msg except subprocess.TimeoutExpired: return "Command timed out after 300 seconds" except Exception as e: return f"Error executing command '{command}': {str(e)}" def safe_execute(command, permission_prompt=True): """ Safely execute a system command with optional permission prompt. Args: command (str): The command to execute permission_prompt (bool): Whether to prompt for permission Returns: str: Command output or permission denial message """ if permission_prompt: print(f"Permission needed to run: {command}") response = input("Allow execution? (y/N): ") if response.lower() not in ["y", "yes"]: return "Execution denied by user" return commandline(command) # Example usage function def example_usage(): """ Example of how to use the command line tool. """ print("Command Line Tool Examples:") # Example 1: Safe execution with prompt result = safe_execute("echo 'Hello, Clover!'") print(f"Result: {result}") # Example 2: Direct execution result = commandline("ls -la") print(f"Directory listing: {result}") if __name__ == "__main__": example_usage()