mirror of
https://github.com/SuperClaude-Org/SuperClaude_Framework.git
synced 2025-12-29 16:16:08 +00:00
- Move pm_init components to dedicated packages - context/: PM mode initialization and contracts - memory/: Reflexion memory system - Remove deprecated superclaude/core/pm_init/ Breaking change: Import paths updated - Old: superclaude.core.pm_init.context_contract - New: superclaude.context.contract 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
140 lines
4.7 KiB
Python
140 lines
4.7 KiB
Python
"""Context Contract System
|
|
|
|
Auto-generates project-specific rules that must be enforced:
|
|
- Infrastructure patterns (Kong, Traefik, Infisical)
|
|
- Security policies (.env禁止, 秘密値管理)
|
|
- Runtime requirements
|
|
- Validation requirements
|
|
"""
|
|
|
|
from pathlib import Path
|
|
from typing import Dict, Any, List
|
|
import yaml
|
|
|
|
|
|
class ContextContract:
|
|
"""Manages project-specific Context Contract"""
|
|
|
|
def __init__(self, git_root: Path, structure: Dict[str, Any]):
|
|
self.git_root = git_root
|
|
self.structure = structure
|
|
self.contract_path = git_root / "docs" / "memory" / "context-contract.yaml"
|
|
|
|
def detect_principles(self) -> Dict[str, Any]:
|
|
"""Detect project-specific principles from structure"""
|
|
principles = {}
|
|
|
|
# Infisical detection
|
|
if self.structure.get("infrastructure", {}).get("infisical"):
|
|
principles["use_infisical_only"] = True
|
|
principles["no_env_files"] = True
|
|
else:
|
|
principles["use_infisical_only"] = False
|
|
principles["no_env_files"] = False
|
|
|
|
# Kong detection
|
|
if self.structure.get("infrastructure", {}).get("kong"):
|
|
principles["outbound_through"] = "kong"
|
|
# Traefik detection
|
|
elif self.structure.get("infrastructure", {}).get("traefik"):
|
|
principles["outbound_through"] = "traefik"
|
|
else:
|
|
principles["outbound_through"] = None
|
|
|
|
# Supabase detection
|
|
if self.structure.get("infrastructure", {}).get("supabase"):
|
|
principles["supabase_integration"] = True
|
|
else:
|
|
principles["supabase_integration"] = False
|
|
|
|
return principles
|
|
|
|
def detect_runtime(self) -> Dict[str, Any]:
|
|
"""Detect runtime requirements"""
|
|
runtime = {}
|
|
|
|
# Node.js
|
|
if "package.json" in self.structure.get("package_managers", {}).get("node", []):
|
|
if "pnpm-lock.yaml" in self.structure.get("package_managers", {}).get("node", []):
|
|
runtime["node"] = {
|
|
"manager": "pnpm",
|
|
"source": "lockfile-defined"
|
|
}
|
|
else:
|
|
runtime["node"] = {
|
|
"manager": "npm",
|
|
"source": "package-json-defined"
|
|
}
|
|
|
|
# Python
|
|
if "pyproject.toml" in self.structure.get("package_managers", {}).get("python", []):
|
|
if "uv.lock" in self.structure.get("package_managers", {}).get("python", []):
|
|
runtime["python"] = {
|
|
"manager": "uv",
|
|
"source": "lockfile-defined"
|
|
}
|
|
else:
|
|
runtime["python"] = {
|
|
"manager": "pip",
|
|
"source": "pyproject-defined"
|
|
}
|
|
|
|
return runtime
|
|
|
|
def detect_validators(self) -> List[str]:
|
|
"""Detect required validators"""
|
|
validators = [
|
|
"deps_exist_on_registry",
|
|
"tests_must_run"
|
|
]
|
|
|
|
principles = self.detect_principles()
|
|
|
|
if principles.get("use_infisical_only"):
|
|
validators.append("no_env_file_creation")
|
|
validators.append("no_hardcoded_secrets")
|
|
|
|
if principles.get("outbound_through"):
|
|
validators.append("outbound_through_proxy")
|
|
|
|
return validators
|
|
|
|
def generate_contract(self) -> Dict[str, Any]:
|
|
"""Generate Context Contract from detected structure"""
|
|
return {
|
|
"version": "1.0.0",
|
|
"generated_at": "auto",
|
|
"principles": self.detect_principles(),
|
|
"runtime": self.detect_runtime(),
|
|
"validators": self.detect_validators(),
|
|
"structure_snapshot": self.structure
|
|
}
|
|
|
|
def load_contract(self) -> Dict[str, Any]:
|
|
"""Load existing Context Contract"""
|
|
if not self.contract_path.exists():
|
|
return {}
|
|
|
|
with open(self.contract_path, "r") as f:
|
|
return yaml.safe_load(f)
|
|
|
|
def save_contract(self, contract: Dict[str, Any]) -> None:
|
|
"""Save Context Contract to disk"""
|
|
self.contract_path.parent.mkdir(parents=True, exist_ok=True)
|
|
with open(self.contract_path, "w") as f:
|
|
yaml.dump(contract, f, default_flow_style=False, sort_keys=False)
|
|
|
|
def generate_or_load(self) -> Dict[str, Any]:
|
|
"""Generate or load Context Contract"""
|
|
# Try to load existing
|
|
existing = self.load_contract()
|
|
|
|
# If exists and version matches, return it
|
|
if existing and existing.get("version") == "1.0.0":
|
|
return existing
|
|
|
|
# Otherwise, generate new contract
|
|
contract = self.generate_contract()
|
|
self.save_contract(contract)
|
|
return contract
|