skydeckai-code 0.1.23__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aidd/__init__.py +11 -0
- aidd/cli.py +141 -0
- aidd/server.py +54 -0
- aidd/tools/__init__.py +155 -0
- aidd/tools/base.py +18 -0
- aidd/tools/code_analysis.py +703 -0
- aidd/tools/code_execution.py +321 -0
- aidd/tools/directory_tools.py +289 -0
- aidd/tools/file_tools.py +784 -0
- aidd/tools/get_active_apps_tool.py +455 -0
- aidd/tools/get_available_windows_tool.py +395 -0
- aidd/tools/git_tools.py +687 -0
- aidd/tools/image_tools.py +127 -0
- aidd/tools/path_tools.py +86 -0
- aidd/tools/screenshot_tool.py +1029 -0
- aidd/tools/state.py +47 -0
- aidd/tools/system_tools.py +190 -0
- skydeckai_code-0.1.23.dist-info/METADATA +628 -0
- skydeckai_code-0.1.23.dist-info/RECORD +22 -0
- skydeckai_code-0.1.23.dist-info/WHEEL +4 -0
- skydeckai_code-0.1.23.dist-info/entry_points.txt +3 -0
- skydeckai_code-0.1.23.dist-info/licenses/LICENSE +201 -0
aidd/tools/state.py
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
import json
|
2
|
+
from pathlib import Path
|
3
|
+
|
4
|
+
|
5
|
+
|
6
|
+
# Global state management
|
7
|
+
class GlobalState:
|
8
|
+
def __init__(self):
|
9
|
+
self.config_dir = Path.home() / '.skydeckai-code'
|
10
|
+
self.config_file = self.config_dir / 'config.json'
|
11
|
+
self._ensure_config_dir()
|
12
|
+
|
13
|
+
def _ensure_config_dir(self):
|
14
|
+
"""Ensure the config directory exists."""
|
15
|
+
self.config_dir.mkdir(exist_ok=True)
|
16
|
+
|
17
|
+
def _load_config(self) -> dict:
|
18
|
+
"""Load the config file."""
|
19
|
+
if not self.config_file.exists():
|
20
|
+
return {}
|
21
|
+
try:
|
22
|
+
with open(self.config_file, 'r') as f:
|
23
|
+
return json.load(f)
|
24
|
+
except (json.JSONDecodeError, OSError):
|
25
|
+
return {}
|
26
|
+
|
27
|
+
def _save_config(self, config: dict):
|
28
|
+
"""Save the config file."""
|
29
|
+
try:
|
30
|
+
with open(self.config_file, 'w') as f:
|
31
|
+
json.dump(config, f, indent=2, sort_keys=True)
|
32
|
+
except OSError:
|
33
|
+
pass # Silently fail if we can't write the config
|
34
|
+
|
35
|
+
@property
|
36
|
+
def allowed_directory(self) -> str:
|
37
|
+
"""Get the allowed directory, falling back to Desktop if not set."""
|
38
|
+
config = self._load_config()
|
39
|
+
return config.get('allowed_directory', str(Path.home() / "Desktop"))
|
40
|
+
|
41
|
+
@allowed_directory.setter
|
42
|
+
def allowed_directory(self, value: str):
|
43
|
+
"""Set the allowed directory and persist it."""
|
44
|
+
self._save_config({'allowed_directory': value})
|
45
|
+
|
46
|
+
# Single instance to be shared across modules
|
47
|
+
state = GlobalState()
|
@@ -0,0 +1,190 @@
|
|
1
|
+
import json
|
2
|
+
import platform
|
3
|
+
import re
|
4
|
+
import subprocess
|
5
|
+
from typing import Any, Dict, List
|
6
|
+
|
7
|
+
import mcp.types as types
|
8
|
+
import psutil
|
9
|
+
|
10
|
+
from .state import state
|
11
|
+
|
12
|
+
|
13
|
+
def get_system_info_tool():
|
14
|
+
return {
|
15
|
+
"name": "get_system_info",
|
16
|
+
"description": "Get detailed system information about the host computer. "
|
17
|
+
"WHEN TO USE: When you need to understand the system environment, diagnose performance issues, "
|
18
|
+
"verify hardware specifications, check resource availability, or determine the operating environment "
|
19
|
+
"for compatibility reasons. Useful for system analysis, troubleshooting, environment verification, "
|
20
|
+
"and providing context-aware assistance. "
|
21
|
+
"WHEN NOT TO USE: When you only need the current working directory (use get_allowed_directory instead), "
|
22
|
+
"when specific file information is needed (use get_file_info instead), or when you need to interact "
|
23
|
+
"with applications rather than system information (use get_active_apps instead). "
|
24
|
+
"RETURNS: A JSON object containing comprehensive system details including: working directory path, "
|
25
|
+
"OS details (name, version, architecture), Python version, WiFi network name, CPU information "
|
26
|
+
"(cores, usage), memory statistics (total, available, usage percentage), disk information "
|
27
|
+
"(total, free, usage percentage), and on macOS, additional hardware details (model, chip, serial number).",
|
28
|
+
"inputSchema": {
|
29
|
+
"type": "object",
|
30
|
+
"properties": {},
|
31
|
+
"required": [],
|
32
|
+
},
|
33
|
+
}
|
34
|
+
|
35
|
+
def get_size(bytes: int, suffix: str = "B") -> str:
|
36
|
+
"""
|
37
|
+
Scale bytes to its proper format
|
38
|
+
e.g:
|
39
|
+
1253656 => '1.20MB'
|
40
|
+
1253656678 => '1.17GB'
|
41
|
+
"""
|
42
|
+
factor = 1024
|
43
|
+
for unit in ["", "K", "M", "G", "T", "P"]:
|
44
|
+
if bytes < factor:
|
45
|
+
return f"{bytes:.2f}{unit}{suffix}"
|
46
|
+
bytes /= factor
|
47
|
+
|
48
|
+
def get_wifi_info() -> str:
|
49
|
+
"""Get current WiFi network name across different platforms."""
|
50
|
+
try:
|
51
|
+
if platform.system() == "Darwin": # macOS
|
52
|
+
cmd = ["system_profiler", "SPAirPortDataType"]
|
53
|
+
process = subprocess.run(cmd, capture_output=True, text=True)
|
54
|
+
if process.returncode == 0:
|
55
|
+
for line in process.stdout.split('\n'):
|
56
|
+
if "Current Network Information:" in line:
|
57
|
+
next_line = next((line_text.strip() for line_text in process.stdout.split('\n')[process.stdout.split('\n').index(line)+1:] if line_text.strip()), "")
|
58
|
+
return next_line.rstrip(':')
|
59
|
+
elif platform.system() == "Linux":
|
60
|
+
cmd = ["nmcli", "-t", "-f", "active,ssid", "dev", "wifi"]
|
61
|
+
process = subprocess.run(cmd, capture_output=True, text=True)
|
62
|
+
if process.returncode == 0:
|
63
|
+
for line in process.stdout.split('\n'):
|
64
|
+
if line.startswith('yes:'):
|
65
|
+
return line.split(':')[1]
|
66
|
+
elif platform.system() == "Windows":
|
67
|
+
cmd = ["netsh", "wlan", "show", "interfaces"]
|
68
|
+
process = subprocess.run(cmd, capture_output=True, text=True)
|
69
|
+
if process.returncode == 0:
|
70
|
+
for line in process.stdout.split('\n'):
|
71
|
+
if "SSID" in line and "BSSID" not in line:
|
72
|
+
return line.split(":")[1].strip()
|
73
|
+
except Exception:
|
74
|
+
pass # Silently handle any errors and return "Not available"
|
75
|
+
return "Not available"
|
76
|
+
|
77
|
+
def get_mac_details() -> Dict[str, str]:
|
78
|
+
"""Get Mac-specific system details."""
|
79
|
+
if platform.system() != "Darwin":
|
80
|
+
return {}
|
81
|
+
|
82
|
+
mac_info = {}
|
83
|
+
try:
|
84
|
+
# Get system_profiler output
|
85
|
+
cmd = ["system_profiler", "SPHardwareDataType", "SPSoftwareDataType"]
|
86
|
+
process = subprocess.run(cmd, capture_output=True, text=True)
|
87
|
+
|
88
|
+
if process.returncode == 0:
|
89
|
+
output = process.stdout
|
90
|
+
|
91
|
+
# Extract model information
|
92
|
+
model_match = re.search(r"Model Name: (.*?)\n", output)
|
93
|
+
if model_match:
|
94
|
+
mac_info["model"] = model_match.group(1).strip()
|
95
|
+
|
96
|
+
# Extract chip information
|
97
|
+
chip_match = re.search(r"Chip: (.*?)\n", output)
|
98
|
+
if chip_match:
|
99
|
+
mac_info["chip"] = chip_match.group(1).strip()
|
100
|
+
|
101
|
+
# Extract serial number
|
102
|
+
serial_match = re.search(r"Serial Number \(system\): (.*?)\n", output)
|
103
|
+
if serial_match:
|
104
|
+
mac_info["serial_number"] = serial_match.group(1).strip()
|
105
|
+
|
106
|
+
except Exception:
|
107
|
+
pass
|
108
|
+
|
109
|
+
return mac_info
|
110
|
+
|
111
|
+
def get_system_details() -> Dict[str, Any]:
|
112
|
+
"""Gather detailed system information."""
|
113
|
+
|
114
|
+
is_mac = platform.system() == "Darwin"
|
115
|
+
|
116
|
+
# System and OS Information
|
117
|
+
system_info = {
|
118
|
+
"working_directory": state.allowed_directory,
|
119
|
+
"system": {
|
120
|
+
"os": platform.system(),
|
121
|
+
"os_version": platform.release(),
|
122
|
+
"architecture": platform.machine(),
|
123
|
+
"python_version": platform.python_version(),
|
124
|
+
},
|
125
|
+
"wifi_network": get_wifi_info(),
|
126
|
+
|
127
|
+
# CPU Information
|
128
|
+
"cpu": {
|
129
|
+
"physical_cores": psutil.cpu_count(logical=False),
|
130
|
+
"logical_cores": psutil.cpu_count(logical=True),
|
131
|
+
"total_cpu_usage": f"{psutil.cpu_percent()}%"
|
132
|
+
},
|
133
|
+
|
134
|
+
# Memory Information
|
135
|
+
"memory": {
|
136
|
+
"total": get_size(psutil.virtual_memory().total),
|
137
|
+
"available": get_size(psutil.virtual_memory().available),
|
138
|
+
"used_percentage": f"{psutil.virtual_memory().percent}%"
|
139
|
+
},
|
140
|
+
|
141
|
+
# Disk Information
|
142
|
+
"disk": {
|
143
|
+
"total": get_size(psutil.disk_usage('/').total),
|
144
|
+
"free": get_size(psutil.disk_usage('/').free),
|
145
|
+
"used_percentage": f"{psutil.disk_usage('/').percent}%"
|
146
|
+
}
|
147
|
+
}
|
148
|
+
|
149
|
+
# Add Mac-specific information if on macOS
|
150
|
+
if is_mac:
|
151
|
+
mac_details = get_mac_details()
|
152
|
+
system_info["mac_details"] = mac_details
|
153
|
+
|
154
|
+
# Example output will be much cleaner now:
|
155
|
+
# {
|
156
|
+
# "working_directory": "/Users/user/projects/myproject",
|
157
|
+
# "system": {
|
158
|
+
# "os": "Darwin",
|
159
|
+
# "os_version": "22.1.0",
|
160
|
+
# "architecture": "arm64",
|
161
|
+
# "python_version": "3.12.2",
|
162
|
+
# "wifi_network": "MyWiFi"
|
163
|
+
# },
|
164
|
+
# "cpu": {
|
165
|
+
# "physical_cores": 8,
|
166
|
+
# "logical_cores": 8,
|
167
|
+
# "total_cpu_usage": "14.3%"
|
168
|
+
# },
|
169
|
+
# "memory": {
|
170
|
+
# "total": "16.00GB",
|
171
|
+
# "available": "8.50GB",
|
172
|
+
# "used_percentage": "46.9%"
|
173
|
+
# },
|
174
|
+
# "disk": {
|
175
|
+
# "total": "465.63GB",
|
176
|
+
# "free": "208.42GB",
|
177
|
+
# "used_percentage": "55.2%"
|
178
|
+
# },
|
179
|
+
# "mac_details": { # Only present on macOS
|
180
|
+
# "model": "Mac mini",
|
181
|
+
# "chip": "Apple M2",
|
182
|
+
# "serial_number": "XXXXXX"
|
183
|
+
# }
|
184
|
+
# }
|
185
|
+
return system_info
|
186
|
+
|
187
|
+
async def handle_get_system_info(arguments: dict) -> List[types.TextContent]:
|
188
|
+
"""Handle getting system information."""
|
189
|
+
system_info = get_system_details()
|
190
|
+
return [types.TextContent(type="text", text=json.dumps(system_info, indent=2))]
|