# core/workspace_manager.py """ Gestionnaire de l’espace de travail VORTEX. Permet de lire, écrire, lister et exécuter des fichiers dans un dossier dédié. """ import os import subprocess import tempfile from pathlib import Path WORKSPACE = Path(os.environ.get("VORTEX_WORKSPACE", "/app/workspace")) WORKSPACE.mkdir(parents=True, exist_ok=True) class WorkspaceManager: @staticmethod def read_file(path: str) -> str: """Lit un fichier et retourne son contenu.""" full_path = WORKSPACE / path if not full_path.exists(): return f"[Erreur] Fichier {path} introuvable." try: return full_path.read_text(encoding="utf-8") except Exception as e: return f"[Erreur] {e}" @staticmethod def write_file(path: str, content: str) -> str: """Écrit ou écrase un fichier.""" full_path = WORKSPACE / path full_path.parent.mkdir(parents=True, exist_ok=True) full_path.write_text(content, encoding="utf-8") return f"✅ Fichier {path} écrit ({len(content)} caractères)." @staticmethod def list_files(extension: str = "") -> list: """Liste les fichiers du workspace (filtre optionnel par extension).""" pattern = f"*{extension}" if extension else "*" return [str(p.relative_to(WORKSPACE)) for p in WORKSPACE.glob(pattern) if p.is_file()] @staticmethod def run_file(path: str, timeout: int = 30) -> dict: """Exécute un fichier Python dans le workspace et retourne le résultat.""" full_path = WORKSPACE / path if not full_path.exists(): return {"success": False, "error": f"Fichier {path} introuvable."} try: proc = subprocess.run( ["python3", str(full_path)], capture_output=True, text=True, timeout=timeout, cwd=str(WORKSPACE) ) return { "success": proc.returncode == 0, "stdout": proc.stdout[:2000], "stderr": proc.stderr[:500] } except subprocess.TimeoutExpired: return {"success": False, "error": "Timeout"} except Exception as e: return {"success": False, "error": str(e)}