import os import re from typing import List, Dict, Any, Optional class WebIDEBackend: def __init__(self, root_dir: str = "."): self.root_dir = os.path.abspath(root_dir) def search_workspace(self, query: str, max_results: int = 50) -> List[Dict[str, Any]]: """Fast regex/string search across workspace code files.""" results = [] if not query: return results pattern = re.compile(re.escape(query), re.IGNORECASE) skip_dirs = {".git", ".venv", "__pycache__", "node_modules", ".pytest_cache", "builds"} for root, dirs, files in os.walk(self.root_dir): dirs[:] = [d for d in dirs if d not in skip_dirs] for file in files: if len(results) >= max_results: break filepath = os.path.join(root, file) rel_path = os.path.relpath(filepath, self.root_dir) try: with open(filepath, "r", encoding="utf-8", errors="ignore") as f: for line_no, line in enumerate(f, start=1): if pattern.search(line): results.append({ "filepath": rel_path, "line_number": line_no, "content": line.strip() }) if len(results) >= max_results: break except Exception: continue return results def get_completions(self, filepath: str, line: int, column: int, prefix: str) -> List[Dict[str, Any]]: """Monaco editor symbol auto-completion provider.""" keywords = ["def", "class", "import", "from", "return", "async", "await", "try", "except", "FastAPI", "BaseModel"] completions = [] for kw in keywords: if not prefix or kw.startswith(prefix): completions.append({ "label": kw, "kind": "Keyword", "insertText": kw, "detail": f"Python keyword / standard symbol: {kw}" }) return completions ide_backend = WebIDEBackend()