From 01ddc1435408f988142e3a76bab97a7edde25396 Mon Sep 17 00:00:00 2001 From: kazuki Date: Fri, 17 Oct 2025 07:24:01 +0900 Subject: [PATCH] refactor: consolidate MCP integration to unified gateway MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Changes**: - Remove individual MCP server docs (superclaude/mcp/*.md) - Remove MCP server configs (superclaude/mcp/configs/*.json) - Delete MCP docs component (setup/components/mcp_docs.py) - Simplify installer (setup/core/installer.py) - Update components for unified gateway approach **Rationale**: - Unified gateway (airis-mcp-gateway) provides all MCP servers - Individual docs/configs no longer needed (managed centrally) - Reduces maintenance burden and file count - Simplifies installation process **Files Removed**: 17 MCP files (docs + configs) **Installer Changes**: Removed legacy MCP installation logic 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- setup/cli/commands/install.py | 45 +-- setup/cli/commands/uninstall.py | 14 +- setup/cli/commands/update.py | 3 - setup/components/__init__.py | 2 - setup/components/agents.py | 87 ++--- setup/components/commands.py | 112 +++--- setup/components/framework_docs.py | 87 ++--- setup/components/mcp_docs.py | 374 --------------------- setup/components/modes.py | 69 ++++ setup/core/installer.py | 77 +---- setup/data/features.json | 9 - superclaude/cli/commands/doctor.py | 8 - superclaude/cli/commands/install.py | 11 +- superclaude/mcp/MCP_Chrome-DevTools.md | 32 -- superclaude/mcp/MCP_Context7.md | 30 -- superclaude/mcp/MCP_Magic.md | 31 -- superclaude/mcp/MCP_Morphllm.md | 31 -- superclaude/mcp/MCP_Playwright.md | 32 -- superclaude/mcp/MCP_Sequential.md | 33 -- superclaude/mcp/MCP_Serena.md | 32 -- superclaude/mcp/MCP_Tavily.md | 285 ---------------- superclaude/mcp/__init__.py | 0 superclaude/mcp/configs/context7.json | 9 - superclaude/mcp/configs/magic.json | 12 - superclaude/mcp/configs/morphllm.json | 13 - superclaude/mcp/configs/playwright.json | 8 - superclaude/mcp/configs/sequential.json | 9 - superclaude/mcp/configs/serena-docker.json | 14 - superclaude/mcp/configs/serena.json | 13 - superclaude/mcp/configs/tavily.json | 13 - 30 files changed, 253 insertions(+), 1242 deletions(-) delete mode 100644 setup/components/mcp_docs.py delete mode 100644 superclaude/mcp/MCP_Chrome-DevTools.md delete mode 100644 superclaude/mcp/MCP_Context7.md delete mode 100644 superclaude/mcp/MCP_Magic.md delete mode 100644 superclaude/mcp/MCP_Morphllm.md delete mode 100644 superclaude/mcp/MCP_Playwright.md delete mode 100644 superclaude/mcp/MCP_Sequential.md delete mode 100644 superclaude/mcp/MCP_Serena.md delete mode 100644 superclaude/mcp/MCP_Tavily.md delete mode 100644 superclaude/mcp/__init__.py delete mode 100644 superclaude/mcp/configs/context7.json delete mode 100644 superclaude/mcp/configs/magic.json delete mode 100644 superclaude/mcp/configs/morphllm.json delete mode 100644 superclaude/mcp/configs/playwright.json delete mode 100644 superclaude/mcp/configs/sequential.json delete mode 100644 superclaude/mcp/configs/serena-docker.json delete mode 100644 superclaude/mcp/configs/serena.json delete mode 100644 superclaude/mcp/configs/tavily.json diff --git a/setup/cli/commands/install.py b/setup/cli/commands/install.py index efcf16a..48b1692 100644 --- a/setup/cli/commands/install.py +++ b/setup/cli/commands/install.py @@ -138,12 +138,12 @@ def get_components_to_install( # Explicit components specified if args.components: if "all" in args.components: - components = ["framework_docs", "commands", "agents", "modes", "mcp", "mcp_docs"] + components = ["framework_docs", "commands", "agents", "modes", "mcp"] else: components = args.components - # If mcp or mcp_docs is specified, handle MCP server selection - if ("mcp" in components or "mcp_docs" in components) and not args.yes: + # If mcp is specified, handle MCP server selection + if "mcp" in components and not args.yes: selected_servers = select_mcp_servers(registry) if not hasattr(config_manager, "_installation_context"): config_manager._installation_context = {} @@ -151,26 +151,16 @@ def get_components_to_install( selected_servers ) - # If the user selected some servers, ensure both mcp and mcp_docs are included + # If the user selected some servers, ensure mcp is included if selected_servers: if "mcp" not in components: components.append("mcp") logger.debug( f"Auto-added 'mcp' component for selected servers: {selected_servers}" ) - if "mcp_docs" not in components: - components.append("mcp_docs") - logger.debug( - f"Auto-added 'mcp_docs' component for selected servers: {selected_servers}" - ) logger.info(f"Final components to install: {components}") - # If mcp_docs was explicitly requested but no servers selected, allow auto-detection - elif not selected_servers and "mcp_docs" in components: - logger.info("mcp_docs component will auto-detect existing MCP servers") - logger.info("Documentation will be installed for any detected servers") - return components # Interactive two-stage selection @@ -227,7 +217,7 @@ def select_mcp_servers(registry: ComponentRegistry) -> List[str]: try: # Get MCP component to access server list mcp_instance = registry.get_component_instance( - "mcp", get_home_directory() / ".claude" + "mcp", DEFAULT_INSTALL_DIR ) if not mcp_instance or not hasattr(mcp_instance, "mcp_servers"): logger.error("Could not access MCP server information") @@ -325,16 +315,7 @@ def select_framework_components( component_options.append(f"{component_name} - {description}") component_info[component_name] = metadata - # Add MCP documentation option - if selected_mcp_servers: - mcp_docs_desc = f"MCP documentation for {', '.join(selected_mcp_servers)} (auto-selected)" - component_options.append(f"mcp_docs - {mcp_docs_desc}") - auto_selected_mcp_docs = True - else: - component_options.append( - "mcp_docs - MCP server documentation (none selected)" - ) - auto_selected_mcp_docs = False + # MCP documentation is integrated into airis-mcp-gateway, no separate component needed print(f"\n{Colors.CYAN}{Colors.BRIGHT}{'='*51}{Colors.RESET}") print( @@ -358,21 +339,12 @@ def select_framework_components( selected_components = ["framework_docs"] else: selected_components = [] - all_components = framework_components + ["mcp_docs"] + all_components = framework_components for i in selections: if i < len(all_components): selected_components.append(all_components[i]) - # Auto-select MCP docs if not explicitly deselected and we have MCP servers - if auto_selected_mcp_docs and "mcp_docs" not in selected_components: - # Check if user explicitly deselected it - mcp_docs_index = len(framework_components) # Index of mcp_docs in the menu - if mcp_docs_index not in selections: - # User didn't select it, but we auto-select it - selected_components.append("mcp_docs") - logger.info("Auto-selected MCP documentation for configured servers") - # Always include MCP component if servers were selected if selected_mcp_servers and "mcp" not in selected_components: selected_components.append("mcp") @@ -601,9 +573,6 @@ def perform_installation( if summary["installed"]: logger.info(f"Installed components: {', '.join(summary['installed'])}") - if summary["backup_path"]: - logger.info(f"Backup created: {summary['backup_path']}") - else: logger.error( f"Installation completed with errors in {duration:.1f} seconds" diff --git a/setup/cli/commands/uninstall.py b/setup/cli/commands/uninstall.py index fa7d18f..95b20be 100644 --- a/setup/cli/commands/uninstall.py +++ b/setup/cli/commands/uninstall.py @@ -79,14 +79,6 @@ def verify_superclaude_file(file_path: Path, component: str) -> bool: "MODE_Task_Management.md", "MODE_Token_Efficiency.md", ], - "mcp_docs": [ - "MCP_Context7.md", - "MCP_Sequential.md", - "MCP_Magic.md", - "MCP_Playwright.md", - "MCP_Morphllm.md", - "MCP_Serena.md", - ], } # For commands component, verify it's in the sc/ subdirectory @@ -427,8 +419,7 @@ def _custom_component_selection( "core": "Core Framework Files (CLAUDE.md, FLAGS.md, PRINCIPLES.md, etc.)", "commands": "superclaude Commands (commands/sc/*.md)", "agents": "Specialized Agents (agents/*.md)", - "mcp": "MCP Server Configurations", - "mcp_docs": "MCP Documentation", + "mcp": "MCP Server Configurations (airis-mcp-gateway)", "modes": "superclaude Modes", } @@ -568,9 +559,8 @@ def display_component_details(component: str, info: Dict[str, Any]) -> Dict[str, }, "mcp": { "files": "MCP server configurations in .claude.json", - "description": "MCP server configurations", + "description": "MCP server configurations (airis-mcp-gateway)", }, - "mcp_docs": {"files": "MCP/*.md", "description": "MCP documentation files"}, "modes": {"files": "MODE_*.md", "description": "superclaude operational modes"}, } diff --git a/setup/cli/commands/update.py b/setup/cli/commands/update.py index d456cf0..d75569b 100644 --- a/setup/cli/commands/update.py +++ b/setup/cli/commands/update.py @@ -389,9 +389,6 @@ def perform_update( if summary.get("updated"): logger.info(f"Updated components: {', '.join(summary['updated'])}") - if summary.get("backup_path"): - logger.info(f"Backup created: {summary['backup_path']}") - else: logger.error(f"Update completed with errors in {duration:.1f} seconds") diff --git a/setup/components/__init__.py b/setup/components/__init__.py index c9a5d7b..8f97312 100644 --- a/setup/components/__init__.py +++ b/setup/components/__init__.py @@ -5,7 +5,6 @@ from .commands import CommandsComponent from .mcp import MCPComponent from .agents import AgentsComponent from .modes import ModesComponent -from .mcp_docs import MCPDocsComponent __all__ = [ "FrameworkDocsComponent", @@ -13,5 +12,4 @@ __all__ = [ "MCPComponent", "AgentsComponent", "ModesComponent", - "MCPDocsComponent", ] diff --git a/setup/components/agents.py b/setup/components/agents.py index c32df5d..15bf20d 100644 --- a/setup/components/agents.py +++ b/setup/components/agents.py @@ -25,6 +25,13 @@ class AgentsComponent(Component): "category": "agents", } + def is_reinstallable(self) -> bool: + """ + Agents should always be synced to latest version. + SuperClaude agent files always overwrite existing files. + """ + return True + def get_metadata_modifications(self) -> Dict[str, Any]: """Get metadata modifications for agents""" return { @@ -64,14 +71,14 @@ class AgentsComponent(Component): self.settings_manager.update_metadata(metadata_mods) self.logger.info("Updated metadata with agents configuration") - # Add component registration + # Add component registration (with file list for sync) self.settings_manager.add_component_registration( "agents", { "version": __version__, "category": "agents", "agents_count": len(self.component_files), - "agents_list": self.component_files, + "files": list(self.component_files), # Track for sync/deletion }, ) @@ -129,57 +136,51 @@ class AgentsComponent(Component): return ["framework_docs"] def update(self, config: Dict[str, Any]) -> bool: - """Update agents component""" + """ + Sync agents component (overwrite + delete obsolete files). + No backup needed - SuperClaude source files are always authoritative. + """ try: - self.logger.info("Updating SuperClaude agents component...") + self.logger.info("Syncing SuperClaude agents component...") - # Check current version - current_version = self.settings_manager.get_component_version("agents") - target_version = self.get_metadata()["version"] - - if current_version == target_version: - self.logger.info( - f"Agents component already at version {target_version}" - ) - return True - - self.logger.info( - f"Updating agents component from {current_version} to {target_version}" + # Get previously installed files from metadata + metadata = self.settings_manager.load_metadata() + previous_files = set( + metadata.get("components", {}).get("agents", {}).get("files", []) ) - # Create backup of existing agents - backup_files = [] - for filename in self.component_files: + # Get current files from source + current_files = set(self.component_files) + + # Files to delete (were installed before, but no longer in source) + files_to_delete = previous_files - current_files + + # Delete obsolete files + deleted_count = 0 + for filename in files_to_delete: file_path = self.install_component_subdir / filename if file_path.exists(): - backup_path = self.file_manager.backup_file(file_path) - if backup_path: - backup_files.append(backup_path) - self.logger.debug(f"Backed up agent: {filename}") - - # Perform installation (will overwrite existing files) - if self._install(config): - self.logger.success( - f"Agents component updated to version {target_version}" - ) - return True - else: - # Restore backups on failure - self.logger.error("Agents update failed, restoring backups...") - for backup_path in backup_files: try: - original_path = ( - self.install_component_subdir - / backup_path.name.replace(".backup", "") - ) - self.file_manager.copy_file(backup_path, original_path) - self.logger.debug(f"Restored {original_path.name}") + file_path.unlink() + deleted_count += 1 + self.logger.info(f"Deleted obsolete agent: {filename}") except Exception as e: - self.logger.warning(f"Could not restore {backup_path}: {e}") - return False + self.logger.warning(f"Could not delete {filename}: {e}") + + # Install/overwrite current files (no backup) + success = self._install(config) + + if success: + self.logger.success( + f"Agents synced: {len(current_files)} files, {deleted_count} obsolete files removed" + ) + else: + self.logger.error("Agents sync failed") + + return success except Exception as e: - self.logger.exception(f"Unexpected error during agents update: {e}") + self.logger.exception(f"Unexpected error during agents sync: {e}") return False def _get_source_dir(self) -> Path: diff --git a/setup/components/commands.py b/setup/components/commands.py index 2715c2e..e8746b2 100644 --- a/setup/components/commands.py +++ b/setup/components/commands.py @@ -14,6 +14,15 @@ class CommandsComponent(Component): def __init__(self, install_dir: Optional[Path] = None): """Initialize commands component""" + if install_dir is None: + install_dir = Path.home() / ".claude" + + # Commands are installed directly to ~/.claude/commands/sc/ + # not under superclaude/ subdirectory (Claude Code official location) + if "superclaude" in str(install_dir): + # ~/.claude/superclaude -> ~/.claude + install_dir = install_dir.parent + super().__init__(install_dir, Path("commands/sc")) def get_metadata(self) -> Dict[str, str]: @@ -25,6 +34,13 @@ class CommandsComponent(Component): "category": "commands", } + def is_reinstallable(self) -> bool: + """ + Commands should always be synced to latest version. + SuperClaude command files always overwrite existing files. + """ + return True + def get_metadata_modifications(self) -> Dict[str, Any]: """Get metadata modifications for commands component""" return { @@ -54,13 +70,14 @@ class CommandsComponent(Component): self.settings_manager.update_metadata(metadata_mods) self.logger.info("Updated metadata with commands configuration") - # Add component registration to metadata + # Add component registration to metadata (with file list for sync) self.settings_manager.add_component_registration( "commands", { "version": __version__, "category": "commands", "files_count": len(self.component_files), + "files": list(self.component_files), # Track for sync/deletion }, ) self.logger.info("Updated metadata with commands component registration") @@ -68,6 +85,16 @@ class CommandsComponent(Component): self.logger.error(f"Failed to update metadata: {e}") return False + # Clean up old commands directory in superclaude/ (from previous versions) + try: + old_superclaude_commands = Path.home() / ".claude" / "superclaude" / "commands" + if old_superclaude_commands.exists(): + import shutil + shutil.rmtree(old_superclaude_commands) + self.logger.info("Removed old commands directory from superclaude/") + except Exception as e: + self.logger.debug(f"Could not remove old commands directory: {e}") + return True def uninstall(self) -> bool: @@ -156,66 +183,63 @@ class CommandsComponent(Component): return ["framework_docs"] def update(self, config: Dict[str, Any]) -> bool: - """Update commands component""" + """ + Sync commands component (overwrite + delete obsolete files). + No backup needed - SuperClaude source files are always authoritative. + """ try: - self.logger.info("Updating SuperClaude commands component...") + self.logger.info("Syncing SuperClaude commands component...") - # Check current version - current_version = self.settings_manager.get_component_version("commands") - target_version = self.get_metadata()["version"] - - if current_version == target_version: - self.logger.info( - f"Commands component already at version {target_version}" - ) - return True - - self.logger.info( - f"Updating commands component from {current_version} to {target_version}" + # Get previously installed files from metadata + metadata = self.settings_manager.load_metadata() + previous_files = set( + metadata.get("components", {}).get("commands", {}).get("files", []) ) - # Create backup of existing command files + # Get current files from source + current_files = set(self.component_files) + + # Files to delete (were installed before, but no longer in source) + files_to_delete = previous_files - current_files + + # Delete obsolete files + deleted_count = 0 commands_dir = self.install_dir / "commands" / "sc" - backup_files = [] + for filename in files_to_delete: + file_path = commands_dir / filename + if file_path.exists(): + try: + file_path.unlink() + deleted_count += 1 + self.logger.info(f"Deleted obsolete command: {filename}") + except Exception as e: + self.logger.warning(f"Could not delete {filename}: {e}") - if commands_dir.exists(): - for filename in self.component_files: - file_path = commands_dir / filename - if file_path.exists(): - backup_path = self.file_manager.backup_file(file_path) - if backup_path: - backup_files.append(backup_path) - self.logger.debug(f"Backed up {filename}") - - # Perform installation (overwrites existing files) + # Install/overwrite current files (no backup) success = self.install(config) if success: - # Remove backup files on successful update - for backup_path in backup_files: - try: - backup_path.unlink() - except Exception: - pass # Ignore cleanup errors + # Update metadata with current file list + self.settings_manager.add_component_registration( + "commands", + { + "version": __version__, + "category": "commands", + "files_count": len(current_files), + "files": list(current_files), # Track installed files + }, + ) self.logger.success( - f"Commands component updated to version {target_version}" + f"Commands synced: {len(current_files)} files, {deleted_count} obsolete files removed" ) else: - # Restore from backup on failure - self.logger.warning("Update failed, restoring from backup...") - for backup_path in backup_files: - try: - original_path = backup_path.with_suffix("") - backup_path.rename(original_path) - self.logger.debug(f"Restored {original_path.name}") - except Exception as e: - self.logger.error(f"Could not restore {backup_path}: {e}") + self.logger.error("Commands sync failed") return success except Exception as e: - self.logger.exception(f"Unexpected error during commands update: {e}") + self.logger.exception(f"Unexpected error during commands sync: {e}") return False def validate_installation(self) -> Tuple[bool, List[str]]: diff --git a/setup/components/framework_docs.py b/setup/components/framework_docs.py index 31793c1..675efe7 100644 --- a/setup/components/framework_docs.py +++ b/setup/components/framework_docs.py @@ -28,6 +28,13 @@ class FrameworkDocsComponent(Component): "category": "documentation", } + def is_reinstallable(self) -> bool: + """ + Framework docs should always be updated to latest version. + SuperClaude-related documentation should always overwrite existing files. + """ + return True + def get_metadata_modifications(self) -> Dict[str, Any]: """Get metadata modifications for SuperClaude""" return { @@ -59,13 +66,14 @@ class FrameworkDocsComponent(Component): self.settings_manager.update_metadata(metadata_mods) self.logger.info("Updated metadata with framework configuration") - # Add component registration to metadata + # Add component registration to metadata (with file list for sync) self.settings_manager.add_component_registration( "framework_docs", { "version": __version__, "category": "documentation", "files_count": len(self.component_files), + "files": list(self.component_files), # Track for sync/deletion }, ) @@ -144,61 +152,64 @@ class FrameworkDocsComponent(Component): return [] def update(self, config: Dict[str, Any]) -> bool: - """Update framework docs component""" + """ + Sync framework docs component (overwrite + delete obsolete files). + No backup needed - SuperClaude source files are always authoritative. + """ try: - self.logger.info("Updating SuperClaude framework docs component...") + self.logger.info("Syncing SuperClaude framework docs component...") - # Check current version - current_version = self.settings_manager.get_component_version("framework_docs") - target_version = self.get_metadata()["version"] - - if current_version == target_version: - self.logger.info(f"Framework docs component already at version {target_version}") - return True - - self.logger.info( - f"Updating framework docs component from {current_version} to {target_version}" + # Get previously installed files from metadata + metadata = self.settings_manager.load_metadata() + previous_files = set( + metadata.get("components", {}) + .get("framework_docs", {}) + .get("files", []) ) - # Create backup of existing files - backup_files = [] - for filename in self.component_files: + # Get current files from source + current_files = set(self.component_files) + + # Files to delete (were installed before, but no longer in source) + files_to_delete = previous_files - current_files + + # Delete obsolete files + deleted_count = 0 + for filename in files_to_delete: file_path = self.install_dir / filename if file_path.exists(): - backup_path = self.file_manager.backup_file(file_path) - if backup_path: - backup_files.append(backup_path) - self.logger.debug(f"Backed up {filename}") + try: + file_path.unlink() + deleted_count += 1 + self.logger.info(f"Deleted obsolete file: {filename}") + except Exception as e: + self.logger.warning(f"Could not delete {filename}: {e}") - # Perform installation (overwrites existing files) + # Install/overwrite current files (no backup) success = self.install(config) if success: - # Remove backup files on successful update - for backup_path in backup_files: - try: - backup_path.unlink() - except Exception: - pass # Ignore cleanup errors + # Update metadata with current file list + self.settings_manager.add_component_registration( + "framework_docs", + { + "version": __version__, + "category": "documentation", + "files_count": len(current_files), + "files": list(current_files), # Track installed files + }, + ) self.logger.success( - f"Framework docs component updated to version {target_version}" + f"Framework docs synced: {len(current_files)} files, {deleted_count} obsolete files removed" ) else: - # Restore from backup on failure - self.logger.warning("Update failed, restoring from backup...") - for backup_path in backup_files: - try: - original_path = backup_path.with_suffix("") - shutil.move(str(backup_path), str(original_path)) - self.logger.debug(f"Restored {original_path.name}") - except Exception as e: - self.logger.error(f"Could not restore {backup_path}: {e}") + self.logger.error("Framework docs sync failed") return success except Exception as e: - self.logger.exception(f"Unexpected error during framework docs update: {e}") + self.logger.exception(f"Unexpected error during framework docs sync: {e}") return False def validate_installation(self) -> Tuple[bool, List[str]]: diff --git a/setup/components/mcp_docs.py b/setup/components/mcp_docs.py deleted file mode 100644 index 2792176..0000000 --- a/setup/components/mcp_docs.py +++ /dev/null @@ -1,374 +0,0 @@ -""" -MCP Documentation component for SuperClaude MCP server documentation -""" - -from typing import Dict, List, Tuple, Optional, Any -from pathlib import Path - -from ..core.base import Component -from setup import __version__ -from ..services.claude_md import CLAUDEMdService - - -class MCPDocsComponent(Component): - """MCP documentation component - installs docs for selected MCP servers""" - - def __init__(self, install_dir: Optional[Path] = None): - """Initialize MCP docs component""" - # Initialize attributes before calling parent constructor - # because parent calls _discover_component_files() which needs these - self.selected_servers: List[str] = [] - - # Map server names to documentation files - self.server_docs_map = { - "context7": "MCP_Context7.md", - "sequential": "MCP_Sequential.md", - "sequential-thinking": "MCP_Sequential.md", # Handle both naming conventions - "magic": "MCP_Magic.md", - "playwright": "MCP_Playwright.md", - "serena": "MCP_Serena.md", - "morphllm": "MCP_Morphllm.md", - "morphllm-fast-apply": "MCP_Morphllm.md", # Handle both naming conventions - "tavily": "MCP_Tavily.md", - } - - super().__init__(install_dir, Path("")) - - def get_metadata(self) -> Dict[str, str]: - """Get component metadata""" - return { - "name": "mcp_docs", - "version": __version__, - "description": "MCP server documentation and usage guides", - "category": "documentation", - } - - def is_reinstallable(self) -> bool: - """ - Allow mcp_docs to be reinstalled to handle different server selections. - This enables users to add or change MCP server documentation. - """ - return True - - def set_selected_servers(self, selected_servers: List[str]) -> None: - """Set which MCP servers were selected for documentation installation""" - self.selected_servers = selected_servers - self.logger.debug(f"MCP docs will be installed for: {selected_servers}") - - def get_files_to_install(self) -> List[Tuple[Path, Path]]: - """ - Return list of files to install based on selected MCP servers - - Returns: - List of tuples (source_path, target_path) - """ - source_dir = self._get_source_dir() - files = [] - - if source_dir and self.selected_servers: - for server_name in self.selected_servers: - if server_name in self.server_docs_map: - doc_file = self.server_docs_map[server_name] - source = source_dir / doc_file - target = self.install_dir / doc_file - if source.exists(): - files.append((source, target)) - self.logger.debug( - f"Will install documentation for {server_name}: {doc_file}" - ) - else: - self.logger.warning( - f"Documentation file not found for {server_name}: {doc_file}" - ) - - return files - - def _discover_component_files(self) -> List[str]: - """ - Override parent method to dynamically discover files based on selected servers - """ - files = [] - # Check if selected_servers is not empty - if self.selected_servers: - for server_name in self.selected_servers: - if server_name in self.server_docs_map: - files.append(self.server_docs_map[server_name]) - return files - - def _detect_existing_mcp_servers_from_config(self) -> List[str]: - """Detect existing MCP servers from Claude Desktop config""" - detected_servers = [] - - try: - # Try to find Claude Desktop config file - config_paths = [ - self.install_dir / "claude_desktop_config.json", - Path.home() / ".claude" / "claude_desktop_config.json", - Path.home() / ".claude.json", # Claude CLI config - Path.home() - / "AppData" - / "Roaming" - / "Claude" - / "claude_desktop_config.json", # Windows - Path.home() - / "Library" - / "Application Support" - / "Claude" - / "claude_desktop_config.json", # macOS - ] - - config_file = None - for path in config_paths: - if path.exists(): - config_file = path - break - - if not config_file: - self.logger.debug("No Claude Desktop config file found") - return detected_servers - - import json - - with open(config_file, "r") as f: - config = json.load(f) - - # Extract MCP server names from mcpServers section - mcp_servers = config.get("mcpServers", {}) - for server_name in mcp_servers.keys(): - # Map common name variations to our doc file names - normalized_name = self._normalize_server_name(server_name) - if normalized_name and normalized_name in self.server_docs_map: - detected_servers.append(normalized_name) - - if detected_servers: - self.logger.info( - f"Detected existing MCP servers from config: {detected_servers}" - ) - - except Exception as e: - self.logger.warning(f"Could not read Claude Desktop config: {e}") - - return detected_servers - - def _normalize_server_name(self, server_name: str) -> Optional[str]: - """Normalize server name to match our documentation mapping""" - if not server_name: - return None - - server_name = server_name.lower().strip() - - # Map common variations to our server_docs_map keys - name_mappings = { - "context7": "context7", - "sequential-thinking": "sequential-thinking", - "sequential": "sequential-thinking", - "magic": "magic", - "playwright": "playwright", - "serena": "serena", - "morphllm": "morphllm", - "morphllm-fast-apply": "morphllm", - "morph": "morphllm", - } - - return name_mappings.get(server_name) - - def _install(self, config: Dict[str, Any]) -> bool: - """Install MCP documentation component with auto-detection""" - self.logger.info("Installing MCP server documentation...") - - # Auto-detect existing servers - self.logger.info("Auto-detecting existing MCP servers for documentation...") - detected_servers = self._detect_existing_mcp_servers_from_config() - - # Get selected servers from config - selected_servers = config.get("selected_mcp_servers", []) - - # Get previously documented servers from metadata - previous_servers = self.settings_manager.get_metadata_setting( - "components.mcp_docs.servers_documented", [] - ) - - # Merge all server lists - all_servers = list(set(detected_servers + selected_servers + previous_servers)) - - # Filter to only servers we have documentation for - valid_servers = [s for s in all_servers if s in self.server_docs_map] - - if not valid_servers: - self.logger.info( - "No MCP servers detected or selected for documentation installation" - ) - # Still proceed to update metadata - self.set_selected_servers([]) - self.component_files = [] - return self._post_install() - - self.logger.info( - f"Installing documentation for MCP servers: {', '.join(valid_servers)}" - ) - if detected_servers: - self.logger.info(f" - Detected from config: {detected_servers}") - if selected_servers: - self.logger.info(f" - Newly selected: {selected_servers}") - if previous_servers: - self.logger.info(f" - Previously documented: {previous_servers}") - - # Set the servers for which we'll install documentation - self.set_selected_servers(valid_servers) - self.component_files = self._discover_component_files() - - # Validate installation - success, errors = self.validate_prerequisites() - if not success: - for error in errors: - self.logger.error(error) - return False - - # Get files to install - files_to_install = self.get_files_to_install() - - if not files_to_install: - self.logger.warning("No MCP documentation files found to install") - return False - - # Copy documentation files - success_count = 0 - successfully_copied_files = [] - - for source, target in files_to_install: - self.logger.debug(f"Copying {source.name} to {target}") - - if self.file_manager.copy_file(source, target): - success_count += 1 - successfully_copied_files.append(source.name) - self.logger.debug(f"Successfully copied {source.name}") - else: - self.logger.error(f"Failed to copy {source.name}") - - if success_count != len(files_to_install): - self.logger.error( - f"Only {success_count}/{len(files_to_install)} documentation files copied successfully" - ) - return False - - # Update component_files to only include successfully copied files - self.component_files = successfully_copied_files - self.logger.success( - f"MCP documentation installed successfully ({success_count} files for {len(valid_servers)} servers)" - ) - - return self._post_install() - - def _post_install(self) -> bool: - """Post-installation tasks""" - try: - # Update metadata - metadata_mods = { - "components": { - "mcp_docs": { - "version": __version__, - "installed": True, - "files_count": len(self.component_files), - "servers_documented": self.selected_servers, - } - } - } - self.settings_manager.update_metadata(metadata_mods) - self.logger.info("Updated metadata with MCP docs component registration") - - # Update CLAUDE.md with MCP documentation imports - try: - manager = CLAUDEMdService(self.install_dir) - manager.add_imports(self.component_files, category="MCP Documentation") - self.logger.info("Updated CLAUDE.md with MCP documentation imports") - except Exception as e: - self.logger.warning( - f"Failed to update CLAUDE.md with MCP documentation imports: {e}" - ) - # Don't fail the whole installation for this - - return True - except Exception as e: - self.logger.error(f"Failed to update metadata: {e}") - return False - - def uninstall(self) -> bool: - """Uninstall MCP documentation component""" - try: - self.logger.info("Uninstalling MCP documentation component...") - - # Remove all MCP documentation files - removed_count = 0 - source_dir = self._get_source_dir() - - if source_dir and source_dir.exists(): - # Remove all possible MCP doc files - for doc_file in self.server_docs_map.values(): - file_path = self.install_component_subdir / doc_file - if self.file_manager.remove_file(file_path): - removed_count += 1 - self.logger.debug(f"Removed {doc_file}") - - # Remove mcp directory if empty - try: - if self.install_component_subdir.exists(): - remaining_files = list(self.install_component_subdir.iterdir()) - if not remaining_files: - self.install_component_subdir.rmdir() - self.logger.debug("Removed empty mcp directory") - except Exception as e: - self.logger.warning(f"Could not remove mcp directory: {e}") - - # Update settings.json - try: - if self.settings_manager.is_component_installed("mcp_docs"): - self.settings_manager.remove_component_registration("mcp_docs") - self.logger.info("Removed MCP docs component from settings.json") - except Exception as e: - self.logger.warning(f"Could not update settings.json: {e}") - - self.logger.success( - f"MCP documentation uninstalled ({removed_count} files removed)" - ) - return True - - except Exception as e: - self.logger.exception( - f"Unexpected error during MCP docs uninstallation: {e}" - ) - return False - - def get_dependencies(self) -> List[str]: - """Get dependencies""" - return ["framework_docs"] - - def _get_source_dir(self) -> Optional[Path]: - """Get source directory for MCP documentation files""" - # Assume we're in superclaude/setup/components/mcp_docs.py - # and MCP docs are in superclaude/superclaude/MCP/ - project_root = Path(__file__).parent.parent.parent - mcp_dir = project_root / "superclaude" / "mcp" - - # Return None if directory doesn't exist to prevent warning - if not mcp_dir.exists(): - return None - - return mcp_dir - - def get_size_estimate(self) -> int: - """Get estimated installation size""" - source_dir = self._get_source_dir() - total_size = 0 - - if source_dir and source_dir.exists() and self.selected_servers: - for server_name in self.selected_servers: - if server_name in self.server_docs_map: - doc_file = self.server_docs_map[server_name] - file_path = source_dir / doc_file - if file_path.exists(): - total_size += file_path.stat().st_size - - # Minimum size estimate - total_size = max(total_size, 10240) # At least 10KB - - return total_size diff --git a/setup/components/modes.py b/setup/components/modes.py index 570fb2c..86997f0 100644 --- a/setup/components/modes.py +++ b/setup/components/modes.py @@ -26,6 +26,13 @@ class ModesComponent(Component): "category": "modes", } + def is_reinstallable(self) -> bool: + """ + Modes should always be synced to latest version. + SuperClaude mode files always overwrite existing files. + """ + return True + def _install(self, config: Dict[str, Any]) -> bool: """Install modes component""" self.logger.info("Installing SuperClaude behavioral modes...") @@ -77,6 +84,7 @@ class ModesComponent(Component): "version": __version__, "installed": True, "files_count": len(self.component_files), + "files": list(self.component_files), # Track for sync/deletion } } } @@ -142,6 +150,67 @@ class ModesComponent(Component): """Get dependencies""" return ["framework_docs"] + def update(self, config: Dict[str, Any]) -> bool: + """ + Sync modes component (overwrite + delete obsolete files). + No backup needed - SuperClaude source files are always authoritative. + """ + try: + self.logger.info("Syncing SuperClaude modes component...") + + # Get previously installed files from metadata + metadata = self.settings_manager.load_metadata() + previous_files = set( + metadata.get("components", {}).get("modes", {}).get("files", []) + ) + + # Get current files from source + current_files = set(self.component_files) + + # Files to delete (were installed before, but no longer in source) + files_to_delete = previous_files - current_files + + # Delete obsolete files + deleted_count = 0 + for filename in files_to_delete: + file_path = self.install_dir / filename + if file_path.exists(): + try: + file_path.unlink() + deleted_count += 1 + self.logger.info(f"Deleted obsolete mode: {filename}") + except Exception as e: + self.logger.warning(f"Could not delete {filename}: {e}") + + # Install/overwrite current files (no backup) + success = self.install(config) + + if success: + # Update metadata with current file list + metadata_mods = { + "components": { + "modes": { + "version": __version__, + "installed": True, + "files_count": len(current_files), + "files": list(current_files), # Track installed files + } + } + } + self.settings_manager.update_metadata(metadata_mods) + + self.logger.success( + f"Modes synced: {len(current_files)} files, {deleted_count} obsolete files removed" + ) + else: + self.logger.error("Modes sync failed") + + return success + + except Exception as e: + self.logger.exception(f"Unexpected error during modes sync: {e}") + return False + def _get_source_dir(self) -> Optional[Path]: """Get source directory for mode files""" # Assume we're in superclaude/setup/components/modes.py diff --git a/setup/core/installer.py b/setup/core/installer.py index 58e1127..9a89162 100644 --- a/setup/core/installer.py +++ b/setup/core/installer.py @@ -37,7 +37,6 @@ class Installer: self.failed_components: Set[str] = set() self.skipped_components: Set[str] = set() - self.backup_path: Optional[Path] = None self.logger = get_logger() def register_component(self, component: Component) -> None: @@ -132,59 +131,6 @@ class Installer: return len(errors) == 0, errors - def create_backup(self) -> Optional[Path]: - """ - Create backup of existing installation - - Returns: - Path to backup archive or None if no existing installation - """ - if not self.install_dir.exists(): - return None - - if self.dry_run: - return self.install_dir / "backup_dryrun.tar.gz" - - # Create backup directory - backup_dir = self.install_dir / "backups" - backup_dir.mkdir(exist_ok=True) - - # Create timestamped backup - timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") - backup_name = f"superclaude_backup_{timestamp}" - backup_path = backup_dir / f"{backup_name}.tar.gz" - - # Create temporary directory for backup - with tempfile.TemporaryDirectory() as temp_dir: - temp_backup = Path(temp_dir) / backup_name - - # Ensure temp backup directory exists - temp_backup.mkdir(parents=True, exist_ok=True) - - # Copy all files except backups and local directories - for item in self.install_dir.iterdir(): - if item.name not in ["backups", "local"]: - try: - if item.is_file(): - shutil.copy2(item, temp_backup / item.name) - elif item.is_dir(): - shutil.copytree(item, temp_backup / item.name) - except Exception as e: - # Log warning but continue backup process - self.logger.warning(f"Could not backup {item.name}: {e}") - - # Always create an archive, even if empty, to ensure it's a valid tarball - base_path = backup_dir / backup_name - shutil.make_archive(str(base_path), "gztar", temp_backup) - - if not any(temp_backup.iterdir()): - self.logger.warning( - f"No files to backup, created empty backup archive: {backup_path.name}" - ) - - self.backup_path = backup_path - return backup_path - def install_component(self, component_name: str, config: Dict[str, Any]) -> bool: """ Install a single component @@ -201,9 +147,9 @@ class Installer: component = self.components[component_name] - # Framework components (agents, commands, modes, core, mcp_docs) are ALWAYS updated to latest version + # Framework components are ALWAYS updated to latest version # These are SuperClaude implementation files, not user configurations - framework_components = {'agents', 'commands', 'modes', 'core', 'mcp_docs', 'mcp'} + framework_components = {'framework_docs', 'agents', 'commands', 'modes', 'core', 'mcp'} if component_name in framework_components: # Always update framework components to latest version @@ -233,13 +179,17 @@ class Installer: self.failed_components.add(component_name) return False - # Perform installation + # Perform installation or update try: if self.dry_run: self.logger.info(f"[DRY RUN] Would install {component_name}") success = True else: - success = component.install(config) + # If component is already installed and this is a framework component, call update() instead of install() + if component_name in self.installed_components and component_name in framework_components: + success = component.update(config) + else: + success = component.install(config) if success: self.installed_components.add(component_name) @@ -284,15 +234,6 @@ class Installer: self.logger.error(f" - {error}") return False - # Create backup if updating - if self.install_dir.exists() and not self.dry_run: - self.logger.info("Creating backup of existing installation...") - try: - self.create_backup() - except Exception as e: - self.logger.error(f"Failed to create backup: {e}") - return False - # Install each component all_success = True for name in ordered_names: @@ -352,7 +293,6 @@ class Installer: "installed": list(self.installed_components), "failed": list(self.failed_components), "skipped": list(self.skipped_components), - "backup_path": str(self.backup_path) if self.backup_path else None, "install_dir": str(self.install_dir), "dry_run": self.dry_run, } @@ -361,5 +301,4 @@ class Installer: return { "updated": list(self.updated_components), "failed": list(self.failed_components), - "backup_path": str(self.backup_path) if self.backup_path else None, } diff --git a/setup/data/features.json b/setup/data/features.json index fa3d7f7..bbbb303 100644 --- a/setup/data/features.json +++ b/setup/data/features.json @@ -36,15 +36,6 @@ "enabled": true, "required_tools": [] }, - "mcp_docs": { - "name": "mcp_docs", - "version": "4.1.5", - "description": "MCP server documentation and usage guides", - "category": "documentation", - "dependencies": ["core"], - "enabled": true, - "required_tools": [] - }, "agents": { "name": "agents", "version": "4.1.5", diff --git a/superclaude/cli/commands/doctor.py b/superclaude/cli/commands/doctor.py index a9ccb8c..4d9262c 100644 --- a/superclaude/cli/commands/doctor.py +++ b/superclaude/cli/commands/doctor.py @@ -90,7 +90,6 @@ def run_diagnostics() -> dict: if install_dir.exists(): components = { "CLAUDE.md": "Core framework entry point", - "MCP_*.md": "MCP documentation files", "MODE_*.md": "Behavioral mode files", } @@ -100,13 +99,6 @@ def run_diagnostics() -> dict: "message": "Installed" if claude_md.exists() else "Not installed", } - # Count MCP docs - mcp_docs = list(install_dir.glob("MCP_*.md")) - results["MCP Documentation"] = { - "status": len(mcp_docs) > 0, - "message": f"{len(mcp_docs)} servers documented" if mcp_docs else "None installed", - } - # Count modes mode_files = list(install_dir.glob("MODE_*.md")) results["Behavioral Modes"] = { diff --git a/superclaude/cli/commands/install.py b/superclaude/cli/commands/install.py index a8ee00a..8f7a7a4 100644 --- a/superclaude/cli/commands/install.py +++ b/superclaude/cli/commands/install.py @@ -9,6 +9,7 @@ from rich.panel import Panel from rich.prompt import Confirm from rich.progress import Progress, SpinnerColumn, TextColumn from superclaude.cli._console import console +from setup import DEFAULT_INSTALL_DIR # Create install command group app = typer.Typer( @@ -33,7 +34,7 @@ def install_callback( help="Installation profile: api (with API keys), noapi (without), or custom", ), install_dir: Path = typer.Option( - Path.home() / ".claude", + DEFAULT_INSTALL_DIR, "--install-dir", help="Installation directory", ), @@ -82,7 +83,7 @@ def install_all( help="Installation profile: api (with API keys), noapi (without), or custom", ), install_dir: Path = typer.Option( - Path.home() / ".claude", + DEFAULT_INSTALL_DIR, "--install-dir", help="Installation directory", ), @@ -148,7 +149,7 @@ def _run_installation( verbose=verbose, quiet=False, yes=True, # Always non-interactive - components=["framework_docs", "modes", "commands", "agents", "mcp_docs"], # Full install + components=["framework_docs", "modes", "commands", "agents"], # Full install (mcp integrated into airis-mcp-gateway) no_backup=False, list_components=False, diagnose=False, @@ -197,7 +198,7 @@ def install_components( help="Component names to install (e.g., core modes commands agents)", ), install_dir: Path = typer.Option( - Path.home() / ".claude", + DEFAULT_INSTALL_DIR, "--install-dir", help="Installation directory", ), @@ -221,7 +222,7 @@ def install_components( - commands: Slash commands (26 commands) - agents: Specialized agents (17 agents) - mcp: MCP server integrations - - mcp_docs: MCP documentation + - mcp: MCP server configurations (airis-mcp-gateway) """ console.print( Panel.fit( diff --git a/superclaude/mcp/MCP_Chrome-DevTools.md b/superclaude/mcp/MCP_Chrome-DevTools.md deleted file mode 100644 index a77448a..0000000 --- a/superclaude/mcp/MCP_Chrome-DevTools.md +++ /dev/null @@ -1,32 +0,0 @@ -# Chrome DevTools MCP Server - -**Purpose**: Performance analysis, debugging, and real-time browser inspection - -## Triggers -- Performance auditing and analysis requests -- Debugging of layout issues (e.g., CLS) -- Investigation of slow loading times (e.g., LCP) -- Analysis of console errors and network requests -- Real-time inspection of the DOM and CSS - -## Choose When -- **For deep performance analysis**: When you need to understand performance bottlenecks. -- **For live debugging**: To inspect the runtime state of a web page and debug live issues. -- **For network analysis**: To inspect network requests and identify issues like CORS errors. -- **Not for E2E testing**: Use Playwright for end-to-end testing scenarios. -- **Not for static analysis**: Use native Claude for code review and logic validation. - -## Works Best With -- **Sequential**: Sequential plans a performance improvement strategy → Chrome DevTools analyzes and verifies the improvements. -- **Playwright**: Playwright automates a user flow → Chrome DevTools analyzes the performance of that flow. - -## Examples -``` -"analyze the performance of this page" → Chrome DevTools (performance analysis) -"why is this page loading slowly?" → Chrome DevTools (performance analysis) -"debug the layout shift on this element" → Chrome DevTools (live debugging) -"check for console errors on the homepage" → Chrome DevTools (live debugging) -"what network requests are failing?" → Chrome DevTools (network analysis) -"test the login flow" → Playwright (browser automation) -"review this function's logic" → Native Claude (static analysis) -``` \ No newline at end of file diff --git a/superclaude/mcp/MCP_Context7.md b/superclaude/mcp/MCP_Context7.md deleted file mode 100644 index b6fd45e..0000000 --- a/superclaude/mcp/MCP_Context7.md +++ /dev/null @@ -1,30 +0,0 @@ -# Context7 MCP Server - -**Purpose**: Official library documentation lookup and framework pattern guidance - -## Triggers -- Import statements: `import`, `require`, `from`, `use` -- Framework keywords: React, Vue, Angular, Next.js, Express, etc. -- Library-specific questions about APIs or best practices -- Need for official documentation patterns vs generic solutions -- Version-specific implementation requirements - -## Choose When -- **Over WebSearch**: When you need curated, version-specific documentation -- **Over native knowledge**: When implementation must follow official patterns -- **For frameworks**: React hooks, Vue composition API, Angular services -- **For libraries**: Correct API usage, authentication flows, configuration -- **For compliance**: When adherence to official standards is mandatory - -## Works Best With -- **Sequential**: Context7 provides docs → Sequential analyzes implementation strategy -- **Magic**: Context7 supplies patterns → Magic generates framework-compliant components - -## Examples -``` -"implement React useEffect" → Context7 (official React patterns) -"add authentication with Auth0" → Context7 (official Auth0 docs) -"migrate to Vue 3" → Context7 (official migration guide) -"optimize Next.js performance" → Context7 (official optimization patterns) -"just explain this function" → Native Claude (no external docs needed) -``` \ No newline at end of file diff --git a/superclaude/mcp/MCP_Magic.md b/superclaude/mcp/MCP_Magic.md deleted file mode 100644 index 0de990e..0000000 --- a/superclaude/mcp/MCP_Magic.md +++ /dev/null @@ -1,31 +0,0 @@ -# Magic MCP Server - -**Purpose**: Modern UI component generation from 21st.dev patterns with design system integration - -## Triggers -- UI component requests: button, form, modal, card, table, nav -- Design system implementation needs -- `/ui` or `/21` commands -- Frontend-specific keywords: responsive, accessible, interactive -- Component enhancement or refinement requests - -## Choose When -- **For UI components**: Use Magic, not native HTML/CSS generation -- **Over manual coding**: When you need production-ready, accessible components -- **For design systems**: When consistency with existing patterns matters -- **For modern frameworks**: React, Vue, Angular with current best practices -- **Not for backend**: API logic, database queries, server configuration - -## Works Best With -- **Context7**: Magic uses 21st.dev patterns → Context7 provides framework integration -- **Sequential**: Sequential analyzes UI requirements → Magic implements structured components - -## Examples -``` -"create a login form" → Magic (UI component generation) -"build a responsive navbar" → Magic (UI pattern with accessibility) -"add a data table with sorting" → Magic (complex UI component) -"make this component accessible" → Magic (UI enhancement) -"write a REST API" → Native Claude (backend logic) -"fix database query" → Native Claude (non-UI task) -``` \ No newline at end of file diff --git a/superclaude/mcp/MCP_Morphllm.md b/superclaude/mcp/MCP_Morphllm.md deleted file mode 100644 index 7b34d77..0000000 --- a/superclaude/mcp/MCP_Morphllm.md +++ /dev/null @@ -1,31 +0,0 @@ -# Morphllm MCP Server - -**Purpose**: Pattern-based code editing engine with token optimization for bulk transformations - -## Triggers -- Multi-file edit operations requiring consistent patterns -- Framework updates, style guide enforcement, code cleanup -- Bulk text replacements across multiple files -- Natural language edit instructions with specific scope -- Token optimization needed (efficiency gains 30-50%) - -## Choose When -- **Over Serena**: For pattern-based edits, not symbol operations -- **For bulk operations**: Style enforcement, framework updates, text replacements -- **When token efficiency matters**: Fast Apply scenarios with compression needs -- **For simple to moderate complexity**: <10 files, straightforward transformations -- **Not for semantic operations**: Symbol renames, dependency tracking, LSP integration - -## Works Best With -- **Serena**: Serena analyzes semantic context → Morphllm executes precise edits -- **Sequential**: Sequential plans edit strategy → Morphllm applies systematic changes - -## Examples -``` -"update all React class components to hooks" → Morphllm (pattern transformation) -"enforce ESLint rules across project" → Morphllm (style guide application) -"replace all console.log with logger calls" → Morphllm (bulk text replacement) -"rename getUserData function everywhere" → Serena (symbol operation) -"analyze code architecture" → Sequential (complex analysis) -"explain this algorithm" → Native Claude (simple explanation) -``` \ No newline at end of file diff --git a/superclaude/mcp/MCP_Playwright.md b/superclaude/mcp/MCP_Playwright.md deleted file mode 100644 index cbfe022..0000000 --- a/superclaude/mcp/MCP_Playwright.md +++ /dev/null @@ -1,32 +0,0 @@ -# Playwright MCP Server - -**Purpose**: Browser automation and E2E testing with real browser interaction - -## Triggers -- Browser testing and E2E test scenarios -- Visual testing, screenshot, or UI validation requests -- Form submission and user interaction testing -- Cross-browser compatibility validation -- Performance testing requiring real browser rendering -- Accessibility testing with automated WCAG compliance - -## Choose When -- **For real browser interaction**: When you need actual rendering, not just code -- **Over unit tests**: For integration testing, user journeys, visual validation -- **For E2E scenarios**: Login flows, form submissions, multi-page workflows -- **For visual testing**: Screenshot comparisons, responsive design validation -- **Not for code analysis**: Static code review, syntax checking, logic validation - -## Works Best With -- **Sequential**: Sequential plans test strategy → Playwright executes browser automation -- **Magic**: Magic creates UI components → Playwright validates accessibility and behavior - -## Examples -``` -"test the login flow" → Playwright (browser automation) -"check if form validation works" → Playwright (real user interaction) -"take screenshots of responsive design" → Playwright (visual testing) -"validate accessibility compliance" → Playwright (automated WCAG testing) -"review this function's logic" → Native Claude (static analysis) -"explain the authentication code" → Native Claude (code review) -``` \ No newline at end of file diff --git a/superclaude/mcp/MCP_Sequential.md b/superclaude/mcp/MCP_Sequential.md deleted file mode 100644 index 10c6e06..0000000 --- a/superclaude/mcp/MCP_Sequential.md +++ /dev/null @@ -1,33 +0,0 @@ -# Sequential MCP Server - -**Purpose**: Multi-step reasoning engine for complex analysis and systematic problem solving - -## Triggers -- Complex debugging scenarios with multiple layers -- Architectural analysis and system design questions -- `--think`, `--think-hard`, `--ultrathink` flags -- Problems requiring hypothesis testing and validation -- Multi-component failure investigation -- Performance bottleneck identification requiring methodical approach - -## Choose When -- **Over native reasoning**: When problems have 3+ interconnected components -- **For systematic analysis**: Root cause analysis, architecture review, security assessment -- **When structure matters**: Problems benefit from decomposition and evidence gathering -- **For cross-domain issues**: Problems spanning frontend, backend, database, infrastructure -- **Not for simple tasks**: Basic explanations, single-file changes, straightforward fixes - -## Works Best With -- **Context7**: Sequential coordinates analysis → Context7 provides official patterns -- **Magic**: Sequential analyzes UI logic → Magic implements structured components -- **Playwright**: Sequential identifies testing strategy → Playwright executes validation - -## Examples -``` -"why is this API slow?" → Sequential (systematic performance analysis) -"design a microservices architecture" → Sequential (structured system design) -"debug this authentication flow" → Sequential (multi-component investigation) -"analyze security vulnerabilities" → Sequential (comprehensive threat modeling) -"explain this function" → Native Claude (simple explanation) -"fix this typo" → Native Claude (straightforward change) -``` \ No newline at end of file diff --git a/superclaude/mcp/MCP_Serena.md b/superclaude/mcp/MCP_Serena.md deleted file mode 100644 index 3424e38..0000000 --- a/superclaude/mcp/MCP_Serena.md +++ /dev/null @@ -1,32 +0,0 @@ -# Serena MCP Server - -**Purpose**: Semantic code understanding with project memory and session persistence - -## Triggers -- Symbol operations: rename, extract, move functions/classes -- Project-wide code navigation and exploration -- Multi-language projects requiring LSP integration -- Session lifecycle: `/sc:load`, `/sc:save`, project activation -- Memory-driven development workflows -- Large codebase analysis (>50 files, complex architecture) - -## Choose When -- **Over Morphllm**: For symbol operations, not pattern-based edits -- **For semantic understanding**: Symbol references, dependency tracking, LSP integration -- **For session persistence**: Project context, memory management, cross-session learning -- **For large projects**: Multi-language codebases requiring architectural understanding -- **Not for simple edits**: Basic text replacements, style enforcement, bulk operations - -## Works Best With -- **Morphllm**: Serena analyzes semantic context → Morphllm executes precise edits -- **Sequential**: Serena provides project context → Sequential performs architectural analysis - -## Examples -``` -"rename getUserData function everywhere" → Serena (symbol operation with dependency tracking) -"find all references to this class" → Serena (semantic search and navigation) -"load my project context" → Serena (/sc:load with project activation) -"save my current work session" → Serena (/sc:save with memory persistence) -"update all console.log to logger" → Morphllm (pattern-based replacement) -"create a login form" → Magic (UI component generation) -``` \ No newline at end of file diff --git a/superclaude/mcp/MCP_Tavily.md b/superclaude/mcp/MCP_Tavily.md deleted file mode 100644 index c9a0f9f..0000000 --- a/superclaude/mcp/MCP_Tavily.md +++ /dev/null @@ -1,285 +0,0 @@ -# Tavily MCP Server - -**Purpose**: Web search and real-time information retrieval for research and current events - -## Triggers -- Web search requirements beyond Claude's knowledge cutoff -- Current events, news, and real-time information needs -- Market research and competitive analysis tasks -- Technical documentation not in training data -- Academic research requiring recent publications -- Fact-checking and verification needs -- Deep research investigations requiring multi-source analysis -- `/sc:research` command activation - -## Choose When -- **Over WebSearch**: When you need structured search with advanced filtering -- **Over WebFetch**: When you need multi-source search, not single page extraction -- **For research**: Comprehensive investigations requiring multiple sources -- **For current info**: Events, updates, or changes after knowledge cutoff -- **Not for**: Simple questions answerable from training, code generation, local file operations - -## Works Best With -- **Sequential**: Tavily provides raw information → Sequential analyzes and synthesizes -- **Playwright**: Tavily discovers URLs → Playwright extracts complex content -- **Context7**: Tavily searches for updates → Context7 provides stable documentation -- **Serena**: Tavily performs searches → Serena stores research sessions - -## Configuration -Requires TAVILY_API_KEY environment variable from https://app.tavily.com - -## Search Capabilities -- **Web Search**: General web searches with ranking algorithms -- **News Search**: Time-filtered news and current events -- **Academic Search**: Scholarly articles and research papers -- **Domain Filtering**: Include/exclude specific domains -- **Content Extraction**: Full-text extraction from search results -- **Freshness Control**: Prioritize recent content -- **Multi-Round Searching**: Iterative refinement based on gaps - -## Examples -``` -"latest TypeScript features 2024" → Tavily (current technical information) -"OpenAI GPT updates this week" → Tavily (recent news and updates) -"quantum computing breakthroughs 2024" → Tavily (recent research) -"best practices React Server Components" → Tavily (current best practices) -"explain recursion" → Native Claude (general concept explanation) -"write a Python function" → Native Claude (code generation) -``` - -## Search Patterns - -### Basic Search -``` -Query: "search term" -→ Returns: Ranked results with snippets -``` - -### Domain-Specific Search -``` -Query: "search term" -Domains: ["arxiv.org", "github.com"] -→ Returns: Results from specified domains only -``` - -### Time-Filtered Search -``` -Query: "search term" -Recency: "week" | "month" | "year" -→ Returns: Recent results within timeframe -``` - -### Deep Content Search -``` -Query: "search term" -Extract: true -→ Returns: Full content extraction from top results -``` - -## Quality Optimization -- **Query Refinement**: Iterate searches based on initial results -- **Source Diversity**: Ensure multiple perspectives in results -- **Credibility Filtering**: Prioritize authoritative sources -- **Deduplication**: Remove redundant information across sources -- **Relevance Scoring**: Focus on most pertinent results - -## Integration Flows - -### Research Flow -``` -1. Tavily: Initial broad search -2. Sequential: Analyze and identify gaps -3. Tavily: Targeted follow-up searches -4. Sequential: Synthesize findings -5. Serena: Store research session -``` - -### Fact-Checking Flow -``` -1. Tavily: Search for claim verification -2. Tavily: Find contradicting sources -3. Sequential: Analyze evidence -4. Report: Present balanced findings -``` - -### Competitive Analysis Flow -``` -1. Tavily: Search competitor information -2. Tavily: Search market trends -3. Sequential: Comparative analysis -4. Context7: Technical comparisons -5. Report: Strategic insights -``` - -### Deep Research Flow (DR Agent) -``` -1. Planning: Decompose research question -2. Tavily: Execute planned searches -3. Analysis: Assess URL complexity -4. Routing: Simple → Tavily extract | Complex → Playwright -5. Synthesis: Combine all sources -6. Iteration: Refine based on gaps -``` - -## Advanced Search Strategies - -### Multi-Hop Research -```yaml -Initial_Search: - query: "core topic" - depth: broad - -Follow_Up_1: - query: "entities from initial" - depth: targeted - -Follow_Up_2: - query: "relationships discovered" - depth: deep - -Synthesis: - combine: all_findings - resolve: contradictions -``` - -### Adaptive Query Generation -```yaml -Simple_Query: - - Direct search terms - - Single concept focus - -Complex_Query: - - Multiple search variations - - Boolean operators - - Domain restrictions - - Time filters - -Iterative_Query: - - Start broad - - Refine based on results - - Target specific gaps -``` - -### Source Credibility Assessment -```yaml -High_Credibility: - - Academic institutions - - Government sources - - Established media - - Official documentation - -Medium_Credibility: - - Industry publications - - Expert blogs - - Community resources - -Low_Credibility: - - User forums - - Social media - - Unverified sources -``` - -## Performance Considerations - -### Search Optimization -- Batch similar searches together -- Cache search results for reuse -- Prioritize high-value sources -- Limit depth based on confidence - -### Rate Limiting -- Maximum searches per minute -- Token usage per search -- Result caching duration -- Parallel search limits - -### Cost Management -- Monitor API usage -- Set budget limits -- Optimize query efficiency -- Use caching effectively - -## Integration with DR Agent Architecture - -### Planning Strategy Support -```yaml -Planning_Only: - - Direct query execution - - No refinement needed - -Intent_Planning: - - Clarify search intent - - Generate focused queries - -Unified: - - Present search plan - - Adjust based on feedback -``` - -### Multi-Hop Execution -```yaml -Hop_Management: - - Track search genealogy - - Build on previous results - - Detect circular references - - Maintain hop context -``` - -### Self-Reflection Integration -```yaml -Quality_Check: - - Assess result relevance - - Identify coverage gaps - - Trigger additional searches - - Calculate confidence scores -``` - -### Case-Based Learning -```yaml -Pattern_Storage: - - Successful query formulations - - Effective search strategies - - Domain preferences - - Time filter patterns -``` - -## Error Handling - -### Common Issues -- API key not configured -- Rate limit exceeded -- Network timeout -- No results found -- Invalid query format - -### Fallback Strategies -- Use native WebSearch -- Try alternative queries -- Expand search scope -- Use cached results -- Simplify search terms - -## Best Practices - -### Query Formulation -1. Start with clear, specific terms -2. Use quotes for exact phrases -3. Include relevant keywords -4. Specify time ranges when needed -5. Use domain filters strategically - -### Result Processing -1. Verify source credibility -2. Cross-reference multiple sources -3. Check publication dates -4. Identify potential biases -5. Extract key information - -### Integration Workflow -1. Plan search strategy -2. Execute initial searches -3. Analyze results -4. Identify gaps -5. Refine and iterate -6. Synthesize findings -7. Store valuable patterns \ No newline at end of file diff --git a/superclaude/mcp/__init__.py b/superclaude/mcp/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/superclaude/mcp/configs/context7.json b/superclaude/mcp/configs/context7.json deleted file mode 100644 index 76125cc..0000000 --- a/superclaude/mcp/configs/context7.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "context7": { - "command": "npx", - "args": [ - "-y", - "@upstash/context7-mcp@latest" - ] - } -} \ No newline at end of file diff --git a/superclaude/mcp/configs/magic.json b/superclaude/mcp/configs/magic.json deleted file mode 100644 index dd3d7f0..0000000 --- a/superclaude/mcp/configs/magic.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "magic": { - "type": "stdio", - "command": "npx", - "args": [ - "@21st-dev/magic" - ], - "env": { - "TWENTYFIRST_API_KEY": "" - } - } -} \ No newline at end of file diff --git a/superclaude/mcp/configs/morphllm.json b/superclaude/mcp/configs/morphllm.json deleted file mode 100644 index 471053d..0000000 --- a/superclaude/mcp/configs/morphllm.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "morphllm-fast-apply": { - "command": "npx", - "args": [ - "@morph-llm/morph-fast-apply", - "/home/" - ], - "env": { - "MORPH_API_KEY": "", - "ALL_TOOLS": "true" - } - } -} \ No newline at end of file diff --git a/superclaude/mcp/configs/playwright.json b/superclaude/mcp/configs/playwright.json deleted file mode 100644 index 7817848..0000000 --- a/superclaude/mcp/configs/playwright.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "playwright": { - "command": "npx", - "args": [ - "@playwright/mcp@latest" - ] - } -} \ No newline at end of file diff --git a/superclaude/mcp/configs/sequential.json b/superclaude/mcp/configs/sequential.json deleted file mode 100644 index ea14ecb..0000000 --- a/superclaude/mcp/configs/sequential.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "sequential-thinking": { - "command": "npx", - "args": [ - "-y", - "@modelcontextprotocol/server-sequential-thinking" - ] - } -} \ No newline at end of file diff --git a/superclaude/mcp/configs/serena-docker.json b/superclaude/mcp/configs/serena-docker.json deleted file mode 100644 index 0ec8a71..0000000 --- a/superclaude/mcp/configs/serena-docker.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "serena": { - "command": "docker", - "args": [ - "run", - "--rm", - "-v", "${PWD}:/workspace", - "--workdir", "/workspace", - "python:3.11-slim", - "bash", "-c", - "pip install uv && uv tool install serena-ai && uv tool run serena-ai start-mcp-server --context ide-assistant --project /workspace" - ] - } -} \ No newline at end of file diff --git a/superclaude/mcp/configs/serena.json b/superclaude/mcp/configs/serena.json deleted file mode 100644 index 518296a..0000000 --- a/superclaude/mcp/configs/serena.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "serena": { - "command": "uvx", - "args": [ - "--from", - "git+https://github.com/oraios/serena", - "serena", - "start-mcp-server", - "--context", - "ide-assistant" - ] - } - } diff --git a/superclaude/mcp/configs/tavily.json b/superclaude/mcp/configs/tavily.json deleted file mode 100644 index 6966b5a..0000000 --- a/superclaude/mcp/configs/tavily.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "tavily": { - "command": "npx", - "args": [ - "-y", - "mcp-remote", - "https://mcp.tavily.com/mcp/?tavilyApiKey=${TAVILY_API_KEY}" - ], - "env": { - "TAVILY_API_KEY": "${TAVILY_API_KEY}" - } - } -} \ No newline at end of file