-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathshell_tools.py
More file actions
104 lines (81 loc) · 3.06 KB
/
shell_tools.py
File metadata and controls
104 lines (81 loc) · 3.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import subprocess
import os
from typing import Dict, Any
ALLOWED_COMMANDS = [
# Basic file & directory operations
"ls", "pwd", "cd", "mkdir", "touch", "rm", "cp", "mv", "cat", "head", "tail",
"echo", "find", "grep", "wc", "less", "more",
# Git commands
"git", "git status", "git add", "git commit", "git push", "git pull", "git checkout",
"git branch", "git log", "git diff", "git clone", "git fetch", "git merge",
"git stash", "git reset",
# Python related
"python", "python3", "pip", "pip3", "pytest", "venv",
# Node related
"node", "npm", "npx", "yarn",
# System info
"ps", "top", "htop", "df", "du", "free", "whoami", "which", "whereis",
# Network
"curl", "wget", "ping", "netstat", "ssh",
# Package managers
"apt", "apt-get", "brew", "yum", "dnf"
]
def is_command_allowed(command_str: str) -> bool:
"""Check if the command is allowed to run."""
# Extract the base command (before any spaces or special chars)
parts = command_str.split()
if not parts:
return False
base_command = parts[0]
# Handle git commands (special case)
if base_command == "git" and len(parts) > 1:
git_subcommand = f"git {parts[1]}"
if git_subcommand in ALLOWED_COMMANDS:
return True
# Check if base command is in allowed list
return base_command in ALLOWED_COMMANDS
def execute_bash(params: Dict[str, Any]) -> str:
"""Execute bash commands in a shell session with confirmation."""
command = params.get("command", "")
if not command:
return "Error: No command provided"
if not is_command_allowed(command):
return f"Error: Command '{command.split()[0]}' is not allowed for security reasons. Allowed commands include: {', '.join(ALLOWED_COMMANDS)}"
# Get confirmation
print(f"\n\033[93m⚠️ BASH COMMAND CONFIRMATION ⚠️\033[0m")
print(f"Command: {command}")
confirmation = input("Type 'y' to execute or anything else to cancel: ")
if confirmation.lower() != 'y':
return "Command execution cancelled by user."
# Execute command
try:
result = subprocess.run(
command,
shell=True,
capture_output=True,
text=True,
timeout=30 # 30 second timeout
)
output = result.stdout
error = result.stderr
exit_code = result.returncode
response = f"Exit Code: {exit_code}\n"
if output:
response += f"\nOutput:\n{output}"
if error:
response += f"\nError:\n{error}"
return response
except subprocess.TimeoutExpired:
return "Error: Command execution timed out after 30 seconds"
except Exception as e:
return f"Error executing command: {str(e)}"
BASH_SCHEMA = {
"type": "object",
"properties": {
"command": {
"type": "string",
"description": "The bash command to execute"
}
},
"required": ["command"]
}