# Migration to Clean Plugin Architecture **Date**: 2025-10-21 **Status**: Planning โ†’ Implementation **Goal**: Zero-footprint pytest plugin + Optional skills system --- ## ๐ŸŽฏ Design Philosophy ### Before (Polluting Design) ```yaml Problem: - Installs to ~/.claude/superclaude/ (pollutes Claude Code) - Complex Component/Installer infrastructure (468-line base class) - Skills vs Commandsๆททๅœจ (2ใคใฎใƒกใ‚ซใƒ‹ใ‚บใƒ ) - setup.py packaging (deprecated) Impact: - Claude Code directory pollution - Difficult to maintain - Not pip-installable cleanly - Confusing for users ``` ### After (Clean Design) ```yaml Solution: - Python package in site-packages/ only - pytest plugin via entry points (auto-discovery) - Optional Skills (user choice to install) - PEP 517 src/ layout (modern packaging) Benefits: โœ… Zero ~/.claude/ pollution (unless user wants skills) โœ… pip install superclaude โ†’ pytest auto-loads โœ… Standard pytest plugin architecture โœ… Clear separation: core vs user config โœ… Tests stay in project root (not installed) ``` --- ## ๐Ÿ“‚ New Directory Structure ``` superclaude/ โ”œโ”€โ”€ src/ # PEP 517 source layout โ”‚ โ””โ”€โ”€ superclaude/ # Actual package โ”‚ โ”œโ”€โ”€ __init__.py # Package metadata โ”‚ โ”œโ”€โ”€ __version__.py # Version info โ”‚ โ”œโ”€โ”€ pytest_plugin.py # โญ pytest entry point โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ pm_agent/ # PM Agent core logic โ”‚ โ”‚ โ”œโ”€โ”€ __init__.py โ”‚ โ”‚ โ”œโ”€โ”€ confidence.py # Pre-execution confidence check โ”‚ โ”‚ โ”œโ”€โ”€ self_check.py # Post-implementation validation โ”‚ โ”‚ โ”œโ”€โ”€ reflexion.py # Error learning pattern โ”‚ โ”‚ โ”œโ”€โ”€ token_budget.py # Budget-aware operations โ”‚ โ”‚ โ””โ”€โ”€ parallel.py # Parallel-with-reflection โ”‚ โ”‚ โ”‚ โ”œโ”€โ”€ cli/ # CLI commands โ”‚ โ”‚ โ”œโ”€โ”€ __init__.py โ”‚ โ”‚ โ”œโ”€โ”€ main.py # Entry point โ”‚ โ”‚ โ”œโ”€โ”€ install_skill.py # superclaude install-skill โ”‚ โ”‚ โ””โ”€โ”€ doctor.py # superclaude doctor โ”‚ โ”‚ โ”‚ โ””โ”€โ”€ skills/ # Skill templates (not installed by default) โ”‚ โ””โ”€โ”€ pm/ # PM Agent skill โ”‚ โ”œโ”€โ”€ implementation.md โ”‚ โ””โ”€โ”€ modules/ โ”‚ โ”œโ”€โ”€ git-status.md โ”‚ โ”œโ”€โ”€ token-counter.md โ”‚ โ””โ”€โ”€ pm-formatter.md โ”‚ โ”œโ”€โ”€ tests/ # Test suite (NOT installed) โ”‚ โ”œโ”€โ”€ conftest.py # pytest config + fixtures โ”‚ โ”œโ”€โ”€ test_confidence_check.py โ”‚ โ”œโ”€โ”€ test_self_check_protocol.py โ”‚ โ”œโ”€โ”€ test_token_budget.py โ”‚ โ”œโ”€โ”€ test_reflexion_pattern.py โ”‚ โ””โ”€โ”€ test_pytest_plugin.py # Plugin integration tests โ”‚ โ”œโ”€โ”€ docs/ # Documentation โ”‚ โ”œโ”€โ”€ architecture/ โ”‚ โ”‚ โ””โ”€โ”€ MIGRATION_TO_CLEAN_ARCHITECTURE.md (this file) โ”‚ โ””โ”€โ”€ research/ โ”‚ โ”œโ”€โ”€ scripts/ # Utility scripts (not installed) โ”‚ โ”œโ”€โ”€ analyze_workflow_metrics.py โ”‚ โ””โ”€โ”€ ab_test_workflows.py โ”‚ โ”œโ”€โ”€ pyproject.toml # โญ PEP 517 packaging + entry points โ”œโ”€โ”€ README.md โ””โ”€โ”€ LICENSE ``` --- ## ๐Ÿ”ง Entry Points Configuration ### pyproject.toml (New) ```toml [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [project] name = "superclaude" version = "0.4.0" description = "AI-enhanced development framework for Claude Code" readme = "README.md" license = {file = "LICENSE"} authors = [ {name = "Kazuki Nakai"} ] requires-python = ">=3.10" dependencies = [ "pytest>=7.0.0", "pytest-cov>=4.0.0", ] [project.optional-dependencies] dev = [ "pytest-benchmark>=4.0.0", "scipy>=1.10.0", # For A/B testing ] # โญ pytest plugin auto-discovery [project.entry-points.pytest11] superclaude = "superclaude.pytest_plugin" # โญ CLI commands [project.entry-points.console_scripts] superclaude = "superclaude.cli.main:main" [tool.pytest.ini_options] testpaths = ["tests"] python_files = ["test_*.py"] python_classes = ["Test*"] python_functions = ["test_*"] addopts = [ "-v", "--strict-markers", "--tb=short", ] markers = [ "unit: Unit tests", "integration: Integration tests", "hallucination: Hallucination detection tests", "performance: Performance benchmark tests", ] [tool.hatch.build.targets.wheel] packages = ["src/superclaude"] ``` --- ## ๐ŸŽจ Core Components ### 1. pytest Plugin Entry Point **File**: `src/superclaude/pytest_plugin.py` ```python """ SuperClaude pytest plugin Auto-loaded when superclaude is installed. Provides PM Agent fixtures and hooks for enhanced testing. """ import pytest from pathlib import Path from typing import Dict, Any from .pm_agent.confidence import ConfidenceChecker from .pm_agent.self_check import SelfCheckProtocol from .pm_agent.reflexion import ReflexionPattern from .pm_agent.token_budget import TokenBudgetManager def pytest_configure(config): """Register SuperClaude plugin and markers""" config.addinivalue_line( "markers", "confidence_check: Pre-execution confidence assessment" ) config.addinivalue_line( "markers", "self_check: Post-implementation validation" ) config.addinivalue_line( "markers", "reflexion: Error learning and prevention" ) @pytest.fixture def confidence_checker(): """Fixture for confidence checking""" return ConfidenceChecker() @pytest.fixture def self_check_protocol(): """Fixture for self-check protocol""" return SelfCheckProtocol() @pytest.fixture def reflexion_pattern(): """Fixture for reflexion pattern""" return ReflexionPattern() @pytest.fixture def token_budget(request): """Fixture for token budget management""" # Get test complexity from marker marker = request.node.get_closest_marker("complexity") complexity = marker.args[0] if marker else "medium" return TokenBudgetManager(complexity=complexity) @pytest.fixture def pm_context(tmp_path): """ Fixture providing PM Agent context for testing Creates temporary memory directory structure: - docs/memory/pm_context.md - docs/memory/last_session.md - docs/memory/next_actions.md """ memory_dir = tmp_path / "docs" / "memory" memory_dir.mkdir(parents=True) return { "memory_dir": memory_dir, "pm_context": memory_dir / "pm_context.md", "last_session": memory_dir / "last_session.md", "next_actions": memory_dir / "next_actions.md", } def pytest_runtest_setup(item): """ Pre-test hook for confidence checking If test is marked with @pytest.mark.confidence_check, run pre-execution confidence assessment. """ marker = item.get_closest_marker("confidence_check") if marker: checker = ConfidenceChecker() confidence = checker.assess(item) if confidence < 0.7: pytest.skip(f"Confidence too low: {confidence:.0%}") def pytest_runtest_makereport(item, call): """ Post-test hook for self-check and reflexion Records test outcomes for reflexion learning. """ if call.when == "call": marker = item.get_closest_marker("reflexion") if marker and call.excinfo is not None: # Test failed - apply reflexion pattern reflexion = ReflexionPattern() reflexion.record_error( test_name=item.name, error=call.excinfo.value, traceback=call.excinfo.traceback ) ``` ### 2. PM Agent Core Modules **File**: `src/superclaude/pm_agent/confidence.py` ```python """ Pre-execution confidence check Prevents wrong-direction execution by assessing confidence BEFORE starting. """ from typing import Dict, Any class ConfidenceChecker: """ Pre-implementation confidence assessment Usage: checker = ConfidenceChecker() confidence = checker.assess(context) if confidence >= 0.9: # High confidence - proceed elif confidence >= 0.7: # Medium confidence - present options else: # Low confidence - stop and request clarification """ def assess(self, context: Any) -> float: """ Assess confidence level (0.0 - 1.0) Checks: - Official documentation verified? - Existing patterns identified? - Implementation path clear? Returns: float: Confidence score (0.0 = no confidence, 1.0 = absolute) """ score = 0.0 checks = [] # Check 1: Documentation verified (40%) if self._has_official_docs(context): score += 0.4 checks.append("โœ… Official documentation") else: checks.append("โŒ Missing documentation") # Check 2: Existing patterns (30%) if self._has_existing_patterns(context): score += 0.3 checks.append("โœ… Existing patterns found") else: checks.append("โŒ No existing patterns") # Check 3: Clear implementation path (30%) if self._has_clear_path(context): score += 0.3 checks.append("โœ… Implementation path clear") else: checks.append("โŒ Implementation unclear") return score def _has_official_docs(self, context: Any) -> bool: """Check if official documentation exists""" # Placeholder - implement actual check return True def _has_existing_patterns(self, context: Any) -> bool: """Check if existing patterns can be followed""" # Placeholder - implement actual check return True def _has_clear_path(self, context: Any) -> bool: """Check if implementation path is clear""" # Placeholder - implement actual check return True ``` **File**: `src/superclaude/pm_agent/self_check.py` ```python """ Post-implementation self-check protocol Hallucination prevention through evidence-based validation. """ from typing import Dict, List, Tuple class SelfCheckProtocol: """ Post-implementation validation The Four Questions: 1. ใƒ†ใ‚นใƒˆใฏๅ…จใฆpassใ—ใฆใ‚‹๏ผŸ 2. ่ฆไปถใ‚’ๅ…จใฆๆบ€ใŸใ—ใฆใ‚‹๏ผŸ 3. ๆ€ใ„่พผใฟใงๅฎŸ่ฃ…ใ—ใฆใชใ„๏ผŸ 4. ่จผๆ‹ ใฏใ‚ใ‚‹๏ผŸ """ def validate(self, implementation: Dict) -> Tuple[bool, List[str]]: """ Run self-check validation Args: implementation: Implementation details Returns: Tuple of (passed: bool, issues: List[str]) """ issues = [] # Question 1: Tests passing? if not self._check_tests_passing(implementation): issues.append("โŒ Tests not passing") # Question 2: Requirements met? if not self._check_requirements_met(implementation): issues.append("โŒ Requirements not fully met") # Question 3: Assumptions verified? if not self._check_assumptions_verified(implementation): issues.append("โŒ Unverified assumptions detected") # Question 4: Evidence provided? if not self._check_evidence_exists(implementation): issues.append("โŒ Missing evidence") return len(issues) == 0, issues def _check_tests_passing(self, impl: Dict) -> bool: """Verify all tests pass""" # Placeholder - check test results return impl.get("tests_passed", False) def _check_requirements_met(self, impl: Dict) -> bool: """Verify all requirements satisfied""" # Placeholder - check requirements return impl.get("requirements_met", False) def _check_assumptions_verified(self, impl: Dict) -> bool: """Verify assumptions checked against docs""" # Placeholder - check assumptions return impl.get("assumptions_verified", True) def _check_evidence_exists(self, impl: Dict) -> bool: """Verify evidence provided""" # Placeholder - check evidence return impl.get("evidence_provided", False) ``` ### 3. CLI Commands **File**: `src/superclaude/cli/main.py` ```python """ SuperClaude CLI Commands: superclaude install-skill pm-agent # Install PM Agent skill to ~/.claude/skills/ superclaude doctor # Check installation health """ import click from pathlib import Path @click.group() @click.version_option() def main(): """SuperClaude - AI-enhanced development framework""" pass @main.command() @click.argument("skill_name") @click.option("--target", default="~/.claude/skills", help="Installation directory") def install_skill(skill_name: str, target: str): """ Install a SuperClaude skill to Claude Code Example: superclaude install-skill pm-agent """ from ..skills import install_skill as install_fn target_path = Path(target).expanduser() click.echo(f"Installing skill '{skill_name}' to {target_path}...") if install_fn(skill_name, target_path): click.echo("โœ… Skill installed successfully") else: click.echo("โŒ Skill installation failed", err=True) @main.command() def doctor(): """Check SuperClaude installation health""" click.echo("๐Ÿ” SuperClaude Doctor\n") # Check pytest plugin loaded import pytest config = pytest.Config.fromdictargs({}, []) plugins = config.pluginmanager.list_plugin_distinfo() superclaude_loaded = any( "superclaude" in str(plugin[0]) for plugin in plugins ) if superclaude_loaded: click.echo("โœ… pytest plugin loaded") else: click.echo("โŒ pytest plugin not loaded") # Check skills installed skills_dir = Path("~/.claude/skills").expanduser() if skills_dir.exists(): skills = list(skills_dir.glob("*/implementation.md")) click.echo(f"โœ… {len(skills)} skills installed") else: click.echo("โš ๏ธ No skills installed (optional)") click.echo("\nโœ… SuperClaude is healthy") if __name__ == "__main__": main() ``` --- ## ๐Ÿ“‹ Migration Checklist ### Phase 1: Restructure (Day 1) - [ ] Create `src/superclaude/` directory - [ ] Move current `superclaude/` โ†’ `src/superclaude/` - [ ] Create `src/superclaude/pytest_plugin.py` - [ ] Extract PM Agent logic from Skills: - [ ] `pm_agent/confidence.py` - [ ] `pm_agent/self_check.py` - [ ] `pm_agent/reflexion.py` - [ ] `pm_agent/token_budget.py` - [ ] Create `cli/` directory: - [ ] `cli/main.py` - [ ] `cli/install_skill.py` - [ ] Update `pyproject.toml` with entry points - [ ] Remove old `setup.py` - [ ] Remove `setup/` directory (Component/Installer infrastructure) ### Phase 2: Test Migration (Day 2) - [ ] Update `tests/conftest.py` for new structure - [ ] Migrate tests to use pytest plugin fixtures - [ ] Add `test_pytest_plugin.py` integration tests - [ ] Use `pytester` fixture for plugin testing - [ ] Run: `pytest tests/ -v` โ†’ All tests pass - [ ] Verify entry_points.txt generation ### Phase 3: Clean Installation (Day 3) - [ ] Test: `pip install -e .` (editable mode) - [ ] Verify: `pytest --trace-config` shows superclaude plugin - [ ] Verify: `~/.claude/` remains clean (no pollution) - [ ] Test: `superclaude doctor` command works - [ ] Test: `superclaude install-skill pm-agent` - [ ] Verify: Skill installed to `~/.claude/skills/pm/` ### Phase 4: Documentation Update (Day 4) - [ ] Update README.md with new installation instructions - [ ] Document pytest plugin usage - [ ] Document CLI commands - [ ] Update CLAUDE.md (project instructions) - [ ] Create migration guide for users --- ## ๐Ÿงช Testing Strategy ### Unit Tests (Existing) ```bash pytest tests/test_confidence_check.py -v pytest tests/test_self_check_protocol.py -v pytest tests/test_token_budget.py -v pytest tests/test_reflexion_pattern.py -v ``` ### Integration Tests (New) ```python # tests/test_pytest_plugin.py def test_plugin_loads(pytester): """Test that superclaude plugin loads correctly""" pytester.makeconftest(""" pytest_plugins = ['superclaude.pytest_plugin'] """) result = pytester.runpytest("--trace-config") result.stdout.fnmatch_lines(["*superclaude*"]) def test_confidence_checker_fixture(pytester): """Test confidence_checker fixture availability""" pytester.makepyfile(""" def test_example(confidence_checker): assert confidence_checker is not None confidence = confidence_checker.assess({}) assert 0.0 <= confidence <= 1.0 """) result = pytester.runpytest() result.assert_outcomes(passed=1) ``` ### Installation Tests ```bash # Clean install pip uninstall superclaude -y pip install -e . # Verify plugin loaded pytest --trace-config | grep superclaude # Verify CLI superclaude --version superclaude doctor # Verify ~/.claude/ clean ls ~/.claude/ # Should not have superclaude/ unless skill installed ``` --- ## ๐Ÿš€ Installation Instructions (New) ### For Users ```bash # Install from PyPI (future) pip install superclaude # Install from source (development) git clone https://github.com/SuperClaude-Org/SuperClaude_Framework.git cd SuperClaude_Framework pip install -e . # Verify installation superclaude doctor # Optional: Install PM Agent skill superclaude install-skill pm-agent ``` ### For Developers ```bash # Clone repository git clone https://github.com/SuperClaude-Org/SuperClaude_Framework.git cd SuperClaude_Framework # Install in editable mode with dev dependencies pip install -e ".[dev]" # Run tests pytest tests/ -v # Check pytest plugin pytest --trace-config ``` --- ## ๐Ÿ“Š Benefits Summary | Aspect | Before | After | |--------|--------|-------| | **~/.claude/ pollution** | โŒ Always polluted | โœ… Clean (unless skill installed) | | **Packaging** | โŒ setup.py (deprecated) | โœ… PEP 517 pyproject.toml | | **pytest integration** | โŒ Manual | โœ… Auto-discovery via entry points | | **Installation** | โŒ Custom installer | โœ… Standard pip install | | **Test location** | โŒ Installed to site-packages | โœ… Stays in project root | | **Complexity** | โŒ 468-line Component base | โœ… Simple pytest plugin | | **User choice** | โŒ Forced installation | โœ… Optional skills | --- ## ๐ŸŽฏ Success Criteria - [ ] `pip install superclaude` works cleanly - [ ] pytest auto-discovers superclaude plugin - [ ] `~/.claude/` remains untouched after `pip install` - [ ] All existing tests pass with new structure - [ ] `superclaude doctor` reports healthy - [ ] Skills install optionally: `superclaude install-skill pm-agent` - [ ] Documentation updated and accurate --- **Status**: Ready to implement โœ… **Next**: Phase 1 - Restructure to src/ layout