import os import subprocess from typing import Optional, List, Dict, Any from pathlib import Path from .config import Config from .models import Project from .project import ProjectDetector class ContextExtractor: def __init__(self, config: Optional[Config] = None): self.config = config or Config() self.project_detector = ProjectDetector(config) def get_current_context(self) -> Dict[str, Any]: working_dir = os.getcwd() project = self.project_detector.detect(working_dir) context = { "working_directory": working_dir, "project": project.to_dict() if project else None, "git_branch": self._get_git_branch(), "git_status": self._get_git_status(), "user": os.getenv("USER", "unknown"), "hostname": os.getenv("HOSTNAME", "unknown"), "timestamp": str(datetime.utcnow()), } return context def _get_git_branch(self) -> Optional[str]: try: result = subprocess.run( ["git", "rev-parse", "--abbrev-ref", "HEAD"], capture_output=True, text=True, timeout=5, ) if result.returncode == 0: return result.stdout.strip() except (subprocess.SubprocessError, FileNotFoundError): pass return None def _get_git_status(self) -> Dict[str, Any]: try: result = subprocess.run( ["git", "status", "--porcelain"], capture_output=True, text=True, timeout=5, ) if result.returncode == 0: lines = result.stdout.strip().split("\n") if result.stdout.strip() else [] return { "modified": len([l for l in lines if l.startswith(" M") or l.startswith("M ")]), "staged": len([l for l in lines if l.startswith("M ") or l.startswith("A ")]), "untracked": len([l for l in lines if l.startswith("??")]), } except (subprocess.SubprocessError, FileNotFoundError): pass return {"modified": 0, "staged": 0, "untracked": 0} def get_project_context_commands(self, project: Project) -> List[str]: commands = [] if project.git_remote: commands.append(f"git remote get-url origin # {project.git_remote}") for tech in project.tech_stack: if tech == "Python": commands.append("python -m pip install -r requirements.txt") elif tech == "Node.js": commands.append("npm install") elif tech == "Docker": commands.append("docker-compose up -d") return commands def extract_context_from_path(self, path: str) -> Dict[str, Any]: project = self.project_detector.detect(path) return { "path": path, "project": project.to_dict() if project else None, "exists": os.path.exists(path), "is_directory": os.path.isdir(path) if os.path.exists(path) else False, }