Spaces:
Sleeping
Sleeping
| import asyncio | |
| import os | |
| import shutil | |
| import subprocess | |
| from typing import Any, Dict, List | |
| class FileExplorerAPI: | |
| """Provides file system operations for browser workspace integration.""" | |
| def __init__(self, root_dir: str = "."): | |
| self.root_dir = os.path.abspath(root_dir) | |
| def _resolve(self, relative_path: str) -> str: | |
| full_path = os.path.abspath( | |
| os.path.join(self.root_dir, relative_path) | |
| ) | |
| if not full_path.startswith(self.root_dir): | |
| raise PermissionError("Access outside workspace boundary denied") | |
| return full_path | |
| def list_files(self, relative_path: str = "") -> List[Dict[str, Any]]: | |
| target = self._resolve(relative_path) | |
| if not os.path.exists(target): | |
| return [] | |
| # Requested path is a file | |
| if os.path.isfile(target): | |
| rel = os.path.relpath(target, self.root_dir) | |
| return [{ | |
| "name": os.path.basename(target), | |
| "path": rel, | |
| "is_directory": False, | |
| "size": os.path.getsize(target), | |
| }] | |
| # Requested path is not a directory | |
| if not os.path.isdir(target): | |
| return [] | |
| entries: List[Dict[str, Any]] = [] | |
| for name in sorted(os.listdir(target)): | |
| if name.startswith("."): | |
| continue | |
| if name in ( | |
| "__pycache__", | |
| "node_modules", | |
| "venv", | |
| ".venv", | |
| ): | |
| continue | |
| item_path = os.path.join(target, name) | |
| entries.append({ | |
| "name": name, | |
| "path": os.path.relpath(item_path, self.root_dir), | |
| "is_directory": os.path.isdir(item_path), | |
| "size": ( | |
| os.path.getsize(item_path) | |
| if os.path.isfile(item_path) | |
| else 0 | |
| ), | |
| }) | |
| return entries | |
| def read_file(self, relative_path: str) -> str: | |
| target = self._resolve(relative_path) | |
| with open(target, "r", encoding="utf-8") as f: | |
| return f.read() | |
| def write_file(self, relative_path: str, content: str) -> bool: | |
| target = self._resolve(relative_path) | |
| os.makedirs(os.path.dirname(target), exist_ok=True) | |
| with open(target, "w", encoding="utf-8") as f: | |
| f.write(content) | |
| return True | |
| def delete_file(self, relative_path: str) -> bool: | |
| target = self._resolve(relative_path) | |
| if os.path.isfile(target): | |
| os.remove(target) | |
| return True | |
| if os.path.isdir(target): | |
| shutil.rmtree(target) | |
| return True | |
| return False | |
| class TerminalAPI: | |
| """Executes asynchronous terminal operations.""" | |
| def __init__(self, root_dir: str = "."): | |
| self.root_dir = os.path.abspath(root_dir) | |
| async def run_command(self, command: str) -> Dict[str, Any]: | |
| proc = await asyncio.create_subprocess_shell( | |
| command, | |
| cwd=self.root_dir, | |
| stdout=asyncio.subprocess.PIPE, | |
| stderr=asyncio.subprocess.PIPE, | |
| ) | |
| stdout, stderr = await proc.communicate() | |
| return { | |
| "exit_code": proc.returncode, | |
| "stdout": stdout.decode(errors="replace"), | |
| "stderr": stderr.decode(errors="replace"), | |
| } | |
| class GitAPI: | |
| """Git wrapper.""" | |
| def __init__(self, root_dir: str = "."): | |
| self.root_dir = os.path.abspath(root_dir) | |
| def _git(self, *args) -> Dict[str, Any]: | |
| res = subprocess.run( | |
| ["git", *args], | |
| cwd=self.root_dir, | |
| capture_output=True, | |
| text=True, | |
| ) | |
| return { | |
| "exit_code": res.returncode, | |
| "stdout": res.stdout.strip(), | |
| "stderr": res.stderr.strip(), | |
| } | |
| def status(self): | |
| return self._git("status", "--porcelain") | |
| def commit(self, message: str): | |
| self._git("add", "-A") | |
| return self._git("commit", "-m", message) | |
| def current_branch(self): | |
| result = self._git("branch", "--show-current") | |
| return result["stdout"] or "main" | |
| class BrowserWorkspaceBackend: | |
| """Workspace backend.""" | |
| def __init__(self, root_dir: str = "."): | |
| self.file_api = FileExplorerAPI(root_dir) | |
| self.terminal_api = TerminalAPI(root_dir) | |
| self.git_api = GitAPI(root_dir) | |
| def get_build_status(self): | |
| return { | |
| "status": "ready", | |
| "target": "production", | |
| } | |
| def get_preview_url(self, port: int = 3000): | |
| return f"http://localhost:{port}/preview" | |
| def deploy(self, environment: str = "staging"): | |
| return { | |
| "deployment_id": "dep_12345", | |
| "environment": environment, | |
| "status": "deployed", | |
| } | |