Files
SuperClaude/superclaude/core/pm_init/init_hook.py

135 lines
4.2 KiB
Python
Raw Normal View History

"""PM Mode Initialization Hook
Runs automatically at session start to:
1. Detect repository root and structure
2. Generate Context Contract
3. Load Reflexion Memory
4. Set up PM Mode as default
"""
import os
import subprocess
from pathlib import Path
from typing import Optional, Dict, Any
import yaml
from .context_contract import ContextContract
from .reflexion_memory import ReflexionMemory
class PMInitializer:
"""Initializes PM Mode with project context"""
def __init__(self, cwd: Optional[Path] = None):
self.cwd = cwd or Path.cwd()
self.git_root: Optional[Path] = None
self.config: Dict[str, Any] = {}
def detect_git_root(self) -> Optional[Path]:
"""Detect Git repository root"""
try:
result = subprocess.run(
["git", "rev-parse", "--show-toplevel"],
cwd=self.cwd,
capture_output=True,
text=True,
check=False
)
if result.returncode == 0:
return Path(result.stdout.strip())
except Exception:
pass
return None
def scan_project_structure(self) -> Dict[str, Any]:
"""Lightweight scan of project structure (paths only, no content)"""
if not self.git_root:
return {}
structure = {
"docker_compose": [],
"infrastructure": {
"traefik": [],
"kong": [],
"supabase": [],
"infisical": []
},
"package_managers": {
"node": [],
"python": []
},
"config_files": []
}
# Docker Compose files
for pattern in ["docker-compose*.yml", "docker-compose*.yaml"]:
structure["docker_compose"].extend([
str(p.relative_to(self.git_root))
for p in self.git_root.glob(pattern)
])
# Infrastructure directories
for infra_type in ["traefik", "kong", "supabase", "infisical"]:
infra_path = self.git_root / "infra" / infra_type
if infra_path.exists():
structure["infrastructure"][infra_type].append(str(infra_path.relative_to(self.git_root)))
# Package managers
if (self.git_root / "package.json").exists():
structure["package_managers"]["node"].append("package.json")
if (self.git_root / "pnpm-lock.yaml").exists():
structure["package_managers"]["node"].append("pnpm-lock.yaml")
if (self.git_root / "pyproject.toml").exists():
structure["package_managers"]["python"].append("pyproject.toml")
if (self.git_root / "uv.lock").exists():
structure["package_managers"]["python"].append("uv.lock")
return structure
def initialize(self) -> Dict[str, Any]:
"""Main initialization routine"""
# Step 1: Detect Git root
self.git_root = self.detect_git_root()
if not self.git_root:
return {
"status": "not_git_repo",
"message": "Not a Git repository - PM Mode running in standalone mode"
}
# Step 2: Scan project structure (lightweight)
structure = self.scan_project_structure()
# Step 3: Generate or load Context Contract
contract = ContextContract(self.git_root, structure)
contract_data = contract.generate_or_load()
# Step 4: Load Reflexion Memory
memory = ReflexionMemory(self.git_root)
memory_data = memory.load()
# Step 5: Return initialization data
return {
"status": "initialized",
"git_root": str(self.git_root),
"structure": structure,
"context_contract": contract_data,
"reflexion_memory": memory_data,
"message": "PM Mode initialized successfully"
}
def initialize_pm_mode(cwd: Optional[Path] = None) -> Dict[str, Any]:
"""
Initialize PM Mode as default.
This function runs automatically at session start.
Args:
cwd: Current working directory (defaults to os.getcwd())
Returns:
Initialization status and configuration
"""
initializer = PMInitializer(cwd)
return initializer.initialize()