86 lines
3.1 KiB
Python
86 lines
3.1 KiB
Python
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,
|
|
}
|