From a6a4b961179087de0477e1549386ad5bc7c981a4 Mon Sep 17 00:00:00 2001 From: Tony Date: Mon, 15 Dec 2025 19:43:19 -0500 Subject: [PATCH 1/4] refactor: simplify MCP integrations and remove unused code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit πŸ€– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .../Developer-Guide/technical-architecture.md | 6 +- Docs/real_integrations_plan.md | 13 +- README.md | 94 +- .../01-core-development/frontend-developer.md | 1 - SuperClaude/Agents/selector.py | 5 +- SuperClaude/Agents/socratic-mentor.md | 14 +- SuperClaude/Commands/executor.py | 709 +-------------- SuperClaude/Config/mcp.yaml | 97 +- SuperClaude/Core/AGENTS.md | 261 +++--- SuperClaude/Core/AGENTS_EXTENDED.md | 182 ---- SuperClaude/Core/AGENT_DISCOVERY.md | 186 ---- SuperClaude/Core/FLAGS.md | 2 +- SuperClaude/Core/PRINCIPLES.md | 72 -- SuperClaude/Core/QUICKSTART.md | 2 +- SuperClaude/Core/REFERENCE.md | 192 ++++ SuperClaude/Core/RULES_RECOMMENDED.md | 164 ---- SuperClaude/Core/migrate_serena_data.py | 77 -- SuperClaude/Core/worktree_manager.py | 5 +- SuperClaude/MCP/MCP_LinkUp.md | 115 +-- SuperClaude/MCP/MCP_Pal.md | 93 ++ SuperClaude/MCP/MCP_Rube.md | 71 +- SuperClaude/MCP/MCP_Zen.md | 48 - SuperClaude/MCP/__init__.py | 125 +-- SuperClaude/MCP/__main__.py | 148 --- SuperClaude/MCP/rube_integration.py | 425 --------- SuperClaude/MCP/zen_integration.py | 330 ------- SuperClaude/Quality/quality_scorer.py | 4 +- SuperClaude/__main__.py | 5 +- config/superclaud.yaml | 2 +- examples/advanced_workflows.py | 317 ------- examples/basic_usage.py | 254 ------ .../business}/BUSINESS_PANEL_EXAMPLES.md | 0 .../business}/BUSINESS_SYMBOLS.md | 0 pyproject.toml | 2 +- ..._zen_api_keys.sh => setup_pal_api_keys.sh} | 0 ...integration.sh => test_pal_integration.sh} | 0 setup/cli/commands/clean.py | 3 +- setup/components/mcp.py | 841 ++---------------- setup/components/mcp_docs.py | 290 ++---- setup/core/registry.py | 12 +- setup/core/validator.py | 14 +- setup/services/files.py | 30 +- setup/utils/security.py | 19 +- setup/utils/updater.py | 18 +- tests/quality/test_quality_scorer.py | 8 +- tests/test_linkup.py | 146 --- tests/test_mcp_servers.py | 330 ------- 47 files changed, 967 insertions(+), 4765 deletions(-) delete mode 100644 SuperClaude/Agents/Extended/01-core-development/frontend-developer.md delete mode 100644 SuperClaude/Core/AGENTS_EXTENDED.md delete mode 100644 SuperClaude/Core/AGENT_DISCOVERY.md delete mode 100644 SuperClaude/Core/PRINCIPLES.md create mode 100644 SuperClaude/Core/REFERENCE.md delete mode 100644 SuperClaude/Core/RULES_RECOMMENDED.md delete mode 100644 SuperClaude/Core/migrate_serena_data.py create mode 100644 SuperClaude/MCP/MCP_Pal.md delete mode 100644 SuperClaude/MCP/MCP_Zen.md delete mode 100644 SuperClaude/MCP/__main__.py delete mode 100644 SuperClaude/MCP/rube_integration.py delete mode 100644 SuperClaude/MCP/zen_integration.py delete mode 100644 examples/advanced_workflows.py delete mode 100644 examples/basic_usage.py rename {SuperClaude/Core => examples/business}/BUSINESS_PANEL_EXAMPLES.md (100%) rename {SuperClaude/Core => examples/business}/BUSINESS_SYMBOLS.md (100%) rename scripts/{setup_zen_api_keys.sh => setup_pal_api_keys.sh} (100%) rename scripts/{test_zen_integration.sh => test_pal_integration.sh} (100%) delete mode 100644 tests/test_linkup.py delete mode 100644 tests/test_mcp_servers.py diff --git a/Docs/Developer-Guide/technical-architecture.md b/Docs/Developer-Guide/technical-architecture.md index d8feaf44..b4172f1a 100644 --- a/Docs/Developer-Guide/technical-architecture.md +++ b/Docs/Developer-Guide/technical-architecture.md @@ -46,9 +46,9 @@ contributors can map features to code quickly. - `ModelRouterFacade` resolves provider clients (OpenAI, Anthropic, Google, X.AI). When credentials are missing it returns a structured error so callers can decide whether to retry or short-circuit. -- `ZenIntegration` (MCP) now delegates to `ModelRouterFacade.run_consensus`, - re-packaging the payload into a simple dataclass. The integration therefore - shares the same provider availability rules as the core executor. +- MCP functionality (consensus, code review, etc.) is now accessed via Claude + Code's native tools (`mcp__pal__*`, `mcp__rube__*`) instead of custom wrappers. + No Python integration code is needed. - Tests that need deterministic behaviour register in-memory executors directly on `ConsensusBuilder`. diff --git a/Docs/real_integrations_plan.md b/Docs/real_integrations_plan.md index 6fd94ee3..688d39fa 100644 --- a/Docs/real_integrations_plan.md +++ b/Docs/real_integrations_plan.md @@ -12,14 +12,11 @@ current implementation, remaining risks, and optional follow-up experiments. - **Nice-to-have:** add a smoke test that runs the bootstrap flow inside the benchmark harness’s virtualenv job. -## Rube MCP Live Mode (`SuperClaude/MCP/rube_integration.py`) -- **Current state:** live HTTP calls include retry with backoff, structured - error propagation, and telemetry tags (`rube_mcp`). Dry-run remains available - via `SC_RUBE_MODE=dry-run`. -- **What to monitor next:** record circuit-breaker metrics once we add provider - rate limits and expose a health summary in `.superclaude_metrics`. -- **Nice-to-have:** ship contract fixtures for partner sandboxes so CI can run - smoke requests when credentials exist. +## Rube MCP (Native Tools) +- **Current state:** MCP functionality is now accessed via Claude Code's native + tools (`mcp__rube__*`). No custom HTTP wrapper is needed. +- **What to monitor next:** usage patterns of native MCP tools in command flows. +- **Nice-to-have:** add command-level telemetry for MCP tool invocations. ## Token Accounting (`SuperClaude/Monitoring/performance_monitor.py`) - **Current state:** every provider invocation updates cumulative counters and diff --git a/README.md b/README.md index bf66e73e..57c314e4 100644 --- a/README.md +++ b/README.md @@ -438,7 +438,7 @@ classDiagram +behavior_mode: str +think_level: int +loop_enabled: bool - +zen_review_enabled: bool + +pal_review_enabled: bool } class CommandResult { @@ -514,60 +514,48 @@ graph TB end ``` -#### Rube MCP +#### Rube MCP (Native) -Rube MCP connects 500+ apps for seamless cross-app automation. +Rube MCP connects 500+ apps for seamless cross-app automation via Claude Code's native tools. -```python -from SuperClaude.MCP.rube_integration import RubeIntegration - -# Initialize Rube -rube = RubeIntegration({ - "endpoint": "https://rube.app/mcp", - "api_key": os.getenv("SC_RUBE_API_KEY"), - "enabled": True -}) - -# Web search via LinkUp -result = await rube.linkup_search( - query="latest React 19 features", - depth="deep", - output_type="sourcedAnswer" -) - -# Batch searches -results = await rube.linkup_batch_search( - queries=["Python 3.13 features", "TypeScript 5.6 changes"], - max_concurrent=4 -) +``` +# Web search via LinkUp - use mcp__rube__RUBE_MULTI_EXECUTE_TOOL +Use mcp__rube__RUBE_MULTI_EXECUTE_TOOL with: + tools: [{ + "tool_slug": "LINKUP_SEARCH", + "arguments": { + "query": "latest React 19 features", + "depth": "deep", + "output_type": "sourcedAnswer" + } + }] + session_id: "" + memory: {} ``` -#### Zen MCP - -Zen MCP provides local consensus orchestration and code review. +#### PAL MCP (Native) - Formerly "Zen" -```python -from SuperClaude.MCP.zen_integration import ZenIntegration, ConsensusType - -# Initialize Zen -zen = ZenIntegration() -await zen.initialize_session() - -# Run consensus -result = await zen.consensus( - prompt="Evaluate this architectural decision", - models=[ModelConfig("gpt-5"), ModelConfig("claude-opus-4.5")], - vote=ConsensusType.weighted, - thinking=ThinkingMode.high -) +PAL MCP provides consensus orchestration and code review via Claude Code's native tools. -# Code review -review = await zen.review_code( - diff=git_diff_content, - files=["src/auth.py", "src/api.py"], - model="gpt-5", - max_issues=10 -) +``` +# Code review - use mcp__pal__codereview +Use mcp__pal__codereview with: + step: "Review authentication module for security issues" + step_number: 1 + total_steps: 2 + next_step_required: true + findings: "Initial security scan..." + relevant_files: ["/path/to/auth.py"] + model: "gpt-5.2" + +# Multi-model consensus - use mcp__pal__consensus +Use mcp__pal__consensus with: + step: "Evaluate: Should we use REST or GraphQL?" + step_number: 1 + total_steps: 3 + next_step_required: true + findings: "Analyzing tradeoffs..." + models: [{"model": "gpt-5.2", "stance": "for"}, {"model": "gemini-3-pro", "stance": "against"}] ``` --- @@ -929,7 +917,7 @@ pie title Agent Distribution | `--think` | 1-5 | Thinking depth level | | `--loop` | iterations | Enable quality iteration | | `--consensus` | majority/unanimous | Consensus strategy | -| `--zen-review` | true/false | Enable GPT-5 code review | +| `--pal-review` | true/false | Enable GPT-5 code review | ### Quality Flags @@ -1052,8 +1040,10 @@ SuperClaude/ β”‚ β”‚ └── AGENTS.md # Agent guidelines β”‚ β”‚ β”‚ β”œβ”€β”€ MCP/ -β”‚ β”‚ β”œβ”€β”€ rube_integration.py # Rube MCP client -β”‚ β”‚ └── zen_integration.py # Zen consensus +β”‚ β”‚ β”œβ”€β”€ __init__.py # Native MCP tools reference +β”‚ β”‚ β”œβ”€β”€ MCP_Rube.md # Rube MCP documentation +β”‚ β”‚ β”œβ”€β”€ MCP_Zen.md # PAL MCP documentation +β”‚ β”‚ └── MCP_LinkUp.md # LinkUp search documentation β”‚ β”‚ β”‚ β”œβ”€β”€ ModelRouter/ β”‚ β”‚ β”œβ”€β”€ router.py # Request routing diff --git a/SuperClaude/Agents/Extended/01-core-development/frontend-developer.md b/SuperClaude/Agents/Extended/01-core-development/frontend-developer.md deleted file mode 100644 index 8b137891..00000000 --- a/SuperClaude/Agents/Extended/01-core-development/frontend-developer.md +++ /dev/null @@ -1 +0,0 @@ - diff --git a/SuperClaude/Agents/selector.py b/SuperClaude/Agents/selector.py index 81001a5e..bb50061c 100644 --- a/SuperClaude/Agents/selector.py +++ b/SuperClaude/Agents/selector.py @@ -290,8 +290,9 @@ def _keyword_core_boost(self, agent_name: str, context_lower: str) -> float: for k in ["performance", "optimize", "slow", "speed up"] ): boosts += 0.5 - except Exception: - pass + except Exception as e: + # Agent scoring calculation error; continue with default score + self.logger.debug(f"Error calculating agent boost for {agent_name}: {e}") return boosts def _score_triggers(self, context: str, triggers: List[str]) -> float: diff --git a/SuperClaude/Agents/socratic-mentor.md b/SuperClaude/Agents/socratic-mentor.md index 4980cb1b..c504f42a 100644 --- a/SuperClaude/Agents/socratic-mentor.md +++ b/SuperClaude/Agents/socratic-mentor.md @@ -167,12 +167,14 @@ persona_triggers: ### MCP Server Coordination ```yaml -zen_integration: - usage_patterns: - - "Consensus-backed Socratic reasoning progressions" - - "Complex discovery session orchestration" - - "Progressive question generation and adaptation" - +native_mcp_tools: + pal_consensus: + tool: "mcp__pal__consensus" + usage_patterns: + - "Consensus-backed Socratic reasoning progressions" + - "Complex discovery session orchestration" + - "Progressive question generation and adaptation" + benefits: - "Maintains logical flow of discovery process" - "Enables multi-perspective reasoning about user understanding" diff --git a/SuperClaude/Commands/executor.py b/SuperClaude/Commands/executor.py index 4754e0f3..e19cf3dc 100644 --- a/SuperClaude/Commands/executor.py +++ b/SuperClaude/Commands/executor.py @@ -35,7 +35,6 @@ from ..Agents.registry import AgentRegistry from ..APIClients.codex_cli import CodexCLIClient, CodexCLIUnavailable from ..Core.worktree_manager import WorktreeManager -from ..MCP import get_mcp_integration from ..ModelRouter.consensus import VoteType from ..ModelRouter.facade import ModelRouterFacade from ..Modes.behavioral_manager import BehavioralMode, BehavioralModeManager @@ -87,8 +86,6 @@ class CommandContext: fast_codex_requested: bool = False fast_codex_active: bool = False fast_codex_blocked: List[str] = field(default_factory=list) - zen_review_enabled: bool = False - zen_review_model: str = "gpt-5" @dataclass @@ -139,7 +136,6 @@ def __init__( self.registry = registry self.parser = parser self.execution_history: List[CommandResult] = [] - self.active_mcp_servers: Dict[str, Any] = {} self.hooks: Dict[str, List[Callable]] = { "pre_execute": [], "post_execute": [], @@ -240,8 +236,8 @@ async def execute(self, command_str: str) -> CommandResult: # Run pre-execution hooks await self._run_hooks("pre_execute", context) - # Activate required MCP servers - await self._activate_mcp_servers(context) + # Note: MCP servers are now accessed via native Claude Code tools + # (mcp__rube__*, mcp__pal__*) - no activation needed # Select and load required agents await self._load_agents(context) @@ -269,8 +265,6 @@ async def execute(self, command_str: str) -> CommandResult: if loop_result: output = loop_result["output"] loop_assessment = loop_result["assessment"] - await self._run_zen_reviews(context, output) - consensus_required = metadata.requires_evidence or context.consensus_forced consensus_result = await self._ensure_consensus( context, @@ -630,7 +624,6 @@ async def execute(self, command_str: str) -> CommandResult: ) if loop_assessment and not quality_assessment: quality_assessment = loop_assessment - await self._run_zen_reviews(context, output) context.errors = self._deduplicate(context.errors) @@ -649,16 +642,8 @@ async def execute(self, command_str: str) -> CommandResult: dict(context.results), ) - # Dispatch any Rube automation once metrics have been recorded. - rube_operations = await self._dispatch_rube_actions(context, output) - if rube_operations: - executed_operations.extend(rube_operations) - if isinstance(output, dict): - integrations = output.setdefault("integrations", {}) - existing_ops = self._ensure_list(integrations, "rube") - for op in rube_operations: - if op not in existing_ops: - existing_ops.append(op) + # Note: Rube automation is now handled via native MCP tools + # (mcp__rube__*) - no internal dispatch needed # Run post-execution hooks await self._run_hooks("post_execute", context) @@ -696,8 +681,9 @@ async def execute(self, command_str: str) -> CommandResult: for hook in self.hooks["on_error"]: try: await hook(e, command_str) - except: - pass + except Exception as hook_error: + # Hook errors are non-fatal; continue processing other hooks + logger.debug(f"Error hook failed: {hook_error}", exc_info=True) return CommandResult( success=False, @@ -707,108 +693,6 @@ async def execute(self, command_str: str) -> CommandResult: execution_time=(datetime.now() - start_time).total_seconds(), ) - async def _activate_mcp_servers(self, context: CommandContext) -> None: - """ - Activate required MCP servers for command. - - Args: - context: Command execution context - """ - required_servers = context.metadata.mcp_servers or [] - - # Load MCP server config (best-effort) - mcp_config = {} - try: - # Resolve config path relative to package - base_dir = os.path.dirname(os.path.dirname(__file__)) - cfg_path = os.path.join(base_dir, "Config", "mcp.yaml") - if os.path.exists(cfg_path): - if yaml is None: - logger.warning("PyYAML missing; skipping MCP config load") - else: - with open(cfg_path, encoding="utf-8") as f: - mcp_config = yaml.safe_load(f) or {} - except Exception as e: - logger.warning(f"Failed to load MCP config: {e}") - - server_configs = ( - (mcp_config.get("servers") or {}) if isinstance(mcp_config, dict) else {} - ) - - def _record_warning(message: str) -> None: - warnings_list = context.results.setdefault("warnings", []) - if message not in warnings_list: - warnings_list.append(message) - - for server_name in required_servers: - if server_name in self.active_mcp_servers: - context.mcp_servers.append(server_name) - continue - - try: - cfg = ( - server_configs.get(server_name, {}) - if isinstance(server_configs, dict) - else {} - ) - if not isinstance(cfg, dict): - cfg = {} - - enabled_flag = cfg.get("enabled", True) - if not self._is_truthy(enabled_flag): - logger.info( - f"Skipping MCP server '{server_name}' because it is disabled in configuration." - ) - _record_warning(f"MCP server '{server_name}' disabled") - continue - - requires_network = bool(cfg.get("requires_network", False)) - network_mode = os.getenv("SC_NETWORK_MODE", "offline").strip().lower() - network_allowed = network_mode in {"online", "mixed", "rube", "auto"} - - if requires_network and not network_allowed: - logger.info( - "Skipping MCP server '%s' because network mode '%s' disallows outbound access.", - server_name, - network_mode or "offline", - ) - _record_warning( - f"MCP server '{server_name}' unavailable (network mode)" - ) - continue - - # Instantiate the integration. Prefer passing config if accepted. - try: - instance = get_mcp_integration(server_name, config=cfg) - except TypeError: - instance = get_mcp_integration(server_name) - - # Attempt basic initialization hooks if present - init = getattr(instance, "initialize", None) - init_session = getattr(instance, "initialize_session", None) - if callable(init): - maybe = init() - if hasattr(maybe, "__await__"): - await maybe - if callable(init_session): - maybe = ( - init_session() - ) # often async for UnifiedStore-backed sessions - if hasattr(maybe, "__await__"): - await maybe - - self.active_mcp_servers[server_name] = { - "status": "active", - "activated_at": datetime.now(), - "instance": instance, - "config": cfg, - } - context.mcp_servers.append(server_name) - logger.info(f"Activated MCP server: {server_name}") - except Exception as e: - # Don't fail the command for unknown/non-critical MCP servers; log and continue - logger.warning(f"Skipping MCP server '{server_name}': {e}") - async def _load_agents(self, context: CommandContext) -> None: """ Load required agents for command. @@ -1171,122 +1055,16 @@ async def _execute_test(self, context: CommandContext) -> Dict[str, Any]: } if linkup_requested: - linkup_result = await self._execute_linkup_queries( - context, scenario_hint=test_type - ) - output["linkup"] = linkup_result - status = linkup_result.get("status") - if status == "linkup_failed": - output["status"] = "tests_failed" - else: - output["status"] = "tests_with_linkup" + # LinkUp searches are now done via native MCP tools (mcp__rube__RUBE_SEARCH_TOOLS) + # Commands should use those tools directly in prompts/documentation + output["linkup"] = { + "status": "use_native_mcp", + "message": "Use mcp__rube__RUBE_SEARCH_TOOLS for web searches", + } + output["status"] = "tests_started" return output - async def _execute_linkup_queries( - self, context: CommandContext, scenario_hint: str - ) -> Dict[str, Any]: - entry = self.active_mcp_servers.get("rube") - if not entry: - message = "LinkUp search requires the Rube MCP server to be active." - context.errors.append(message) - return {"status": "linkup_failed", "error": message} - - rube = entry.get("instance") - if rube is None: - message = "Rube MCP instance missing from activation registry." - context.errors.append(message) - return {"status": "linkup_failed", "error": message} - - queries = self._extract_linkup_queries(context) - if not queries: - message = ( - "LinkUp web search requires at least one query. " - "Provide --linkup-query/--query or positional input." - ) - context.errors.append(message) - return {"status": "linkup_failed", "error": message} - - # Use RubeIntegration's built-in linkup_batch_search - responses = await rube.linkup_batch_search(queries) - - aggregated: List[Dict[str, Any]] = [] - failures: List[Dict[str, Any]] = [] - - for idx, result in enumerate(responses): - query_text = queries[idx] - if isinstance(result, dict) and result.get("status") == "failed": - error_message = str(result.get("error", "LinkUp request failed")) - failures.append({"query": query_text, "error": error_message}) - aggregated.append( - {"query": query_text, "status": "failed", "error": error_message} - ) - context.errors.append(f"LinkUp query failed: {error_message}") - continue - - aggregated.append( - {"query": query_text, "status": "completed", "response": result} - ) - - successes = sum(1 for item in aggregated if item.get("status") == "completed") - status = "linkup_completed" - if successes == 0: - status = "linkup_failed" - elif failures: - status = "linkup_partial" - - exec_ops = context.results.setdefault("executed_operations", []) - label = "linkup:search" - if label not in exec_ops: - exec_ops.append(label) - - context.results.setdefault("linkup_queries", []).extend(aggregated) - if failures: - context.results.setdefault("linkup_failures", []).extend(failures) - - return { - "status": status, - "scenario": scenario_hint.lower(), - "queries": aggregated, - "failures": failures, - } - - def _extract_linkup_queries(self, context: CommandContext) -> List[str]: - candidates: List[str] = [] - params = context.command.parameters or {} - - def _append(value: Any) -> None: - if value is None: - return - if isinstance(value, (list, tuple, set)): - for item in value: - _append(item) - return - text = str(value).strip() - if text: - candidates.append(text) - - for key in ("linkup_query", "linkup_queries", "query", "queries"): - _append(params.get(key)) - - # Backward compatibility: treat --url as a query string. - _append(params.get("url")) - - for argument in context.command.arguments: - if isinstance(argument, str) and argument.startswith( - ("http://", "https://") - ): - candidates.append(argument.strip()) - - seen: Set[str] = set() - ordered: List[str] = [] - for item in candidates: - if item not in seen: - seen.add(item) - ordered.append(item) - - return ordered - async def _execute_build(self, context: CommandContext) -> Dict[str, Any]: """Execute build command.""" repo_root = Path(self.repo_root or Path.cwd()) @@ -2469,8 +2247,6 @@ def _run_quality_remediation_iteration( entry = f"loop iteration {iteration_index + 1}: apply {path}" if entry not in applied_list: applied_list.append(entry) - self._record_loop_review_target(context, applied_files, iteration_index) - tests = self._run_requested_tests(context.command) tests_summary = self._summarize_test_results(tests) @@ -2530,255 +2306,6 @@ def _run_quality_remediation_iteration( improved_output.setdefault("quality_loop", []).append(loop_payload) return improved_output - def _record_loop_review_target( - self, context: CommandContext, applied_files: List[str], iteration_index: int - ) -> None: - """Capture diffs for later Zen reviews when loop iterations make changes.""" - if not context.zen_review_enabled or not applied_files: - return - - diff_blob = self._collect_file_diffs(applied_files) - if not diff_blob: - return - - targets = context.results.setdefault("zen_review_targets", []) - targets.append( - { - "iteration": iteration_index + 1, - "files": sorted(set(applied_files)), - "diff": diff_blob, - "captured_at": datetime.now().isoformat(), - } - ) - - def _collect_file_diffs(self, applied_files: Sequence[str]) -> str: - """Generate unified diffs for the provided repository-relative paths.""" - repo_root = Path(self.repo_root or Path.cwd()) - seen: Set[str] = set() - diff_chunks: List[str] = [] - - for rel_path in applied_files: - if not rel_path: - continue - normalized = str(rel_path).strip() - if not normalized or normalized in seen: - continue - seen.add(normalized) - - file_path = (repo_root / normalized).resolve() - try: - file_path.relative_to(repo_root) - except ValueError: - continue - if not file_path.exists(): - continue - - if self._is_tracked_file(normalized): - command = ["git", "diff", "--no-color", "--unified=3", "--", normalized] - else: - command = [ - "git", - "diff", - "--no-color", - "--unified=3", - "--no-index", - "/dev/null", - str(file_path), - ] - - result = self._run_command(command, cwd=repo_root) - diff_text = (result.get("stdout") or "").strip() - if diff_text: - diff_chunks.append(f"### {normalized}\n{diff_text}") - - return "\n\n".join(diff_chunks) - - def _is_tracked_file(self, rel_path: str) -> bool: - """Return True if the given path is tracked by git.""" - repo_root = Path(self.repo_root or Path.cwd()) - result = self._run_command( - ["git", "ls-files", "--error-unmatch", rel_path], cwd=repo_root - ) - return result.get("exit_code") == 0 - - def _enable_primary_zen_quality( - self, context: CommandContext - ) -> Optional[Callable[[], None]]: - """Promote GPT-backed evaluation to the primary quality scorer path.""" - zen_instance = self._get_active_mcp_instance("zen") - if not zen_instance: - return None - - def _primary_evaluator( - _: Any, eval_context: Dict[str, Any], iteration: int - ) -> Optional[Dict[str, Any]]: - diff_blob = self._collect_full_repo_diff() - if not diff_blob.strip(): - return None - - files = eval_context.get("changed_files") or self._list_changed_files() - metadata = { - "reason": "quality-loop-primary", - "loop_requested": context.results.get("loop_requested", False), - "iteration": iteration, - "think_level": context.think_level, - } - - try: - review_payload = self._invoke_zen_review_sync( - zen_instance, - diff_blob, - files=files, - metadata=metadata, - model=context.zen_review_model or "gpt-5", - ) - except Exception as exc: - context.results.setdefault("zen_review_errors", []).append(str(exc)) - return None - - metrics = self._convert_zen_payload_to_metrics(review_payload) - if not metrics: - return None - - improvements = ( - review_payload.get("improvements") - or review_payload.get("recommendations") - or [] - ) - meta = {"zen_review": review_payload} - return { - "metrics": metrics, - "improvements": improvements, - "metadata": meta, - } - - self.quality_scorer.set_primary_evaluator(_primary_evaluator) - - def _cleanup(): - if self.quality_scorer.primary_evaluator is _primary_evaluator: - self.quality_scorer.clear_primary_evaluator() - - return _cleanup - - def _collect_full_repo_diff(self) -> str: - repo_root = Path(self.repo_root or Path.cwd()) - result = self._run_command(["git", "diff", "--no-color"], cwd=repo_root) - return (result.get("stdout") or "").strip() - - def _list_changed_files(self) -> List[str]: - repo_root = Path(self.repo_root or Path.cwd()) - result = self._run_command(["git", "status", "--short"], cwd=repo_root) - files: List[str] = [] - stdout = result.get("stdout") or "" - for line in stdout.splitlines(): - line = line.strip() - if not line: - continue - parts = line.split(maxsplit=1) - if len(parts) == 2: - files.append(parts[1].strip()) - return files - - def _convert_zen_payload_to_metrics( - self, payload: Dict[str, Any] - ) -> List[QualityMetric]: - metrics: List[QualityMetric] = [] - dimensions = payload.get("dimensions") or {} - summary = payload.get("summary") or "Zen review summary unavailable." - overall_score = float(payload.get("score", 0.0)) - - if isinstance(dimensions, dict) and dimensions: - for name, data in dimensions.items(): - try: - dimension = QualityDimension(name) - except ValueError: - continue - if not isinstance(data, dict): - continue - score = float(data.get("score", overall_score)) - issues = data.get("issues") or payload.get("issues") or [] - suggestions = ( - data.get("suggestions") or payload.get("recommendations") or [] - ) - weight = self.quality_scorer.default_weights.get(dimension, 0.1) - metrics.append( - QualityMetric( - dimension=dimension, - score=max(0.0, min(100.0, score)), - weight=weight, - details=summary, - issues=issues[:6] if isinstance(issues, list) else [], - suggestions=suggestions[:6] - if isinstance(suggestions, list) - else [], - ) - ) - - if not metrics: - issues = [] - for issue in payload.get("issues") or []: - if isinstance(issue, dict): - issues.append(issue.get("title") or issue.get("details") or "") - else: - issues.append(str(issue)) - suggestions = payload.get("recommendations") or [] - weight = self.quality_scorer.default_weights.get( - QualityDimension.ZEN_REVIEW, 0.1 - ) - metrics.append( - QualityMetric( - dimension=QualityDimension.ZEN_REVIEW, - score=max(0.0, min(100.0, overall_score)), - weight=weight, - details=summary, - issues=[text for text in issues if text][:6], - suggestions=suggestions[:6] - if isinstance(suggestions, list) - else [], - ) - ) - - return metrics - - def _invoke_zen_review_sync( - self, - zen_instance: Any, - diff_blob: str, - *, - files: Sequence[str], - metadata: Dict[str, Any], - model: str, - ) -> Dict[str, Any]: - async def _call_review(): - return await zen_instance.review_code( - diff_blob, files=list(files), metadata=metadata, model=model - ) - - return self._run_async_function(_call_review) - - def _run_async_function(self, async_callable: Callable[[], Any]) -> Any: - """Execute an async callable from synchronous code using a dedicated event loop.""" - result: Dict[str, Any] = {} - error: Dict[str, Exception] = {} - - def _runner(): - loop = asyncio.new_event_loop() - asyncio.set_event_loop(loop) - try: - result["value"] = loop.run_until_complete(async_callable()) - except Exception as exc: - error["exc"] = exc - finally: - loop.close() - - thread = threading.Thread(target=_runner, daemon=True) - thread.start() - thread.join() - - if error: - raise error["exc"] - return result.get("value", {}) - def _prepare_remediation_agents( self, context: CommandContext, agents: Iterable[str] ) -> None: @@ -3687,10 +3214,6 @@ def _remediation_improver( ) -> Any: return self._quality_loop_improver(context, current_output, loop_context) - zen_cleanup = None - if context.zen_review_enabled: - zen_cleanup = self._enable_primary_zen_quality(context) - try: improved_output, final_assessment, iteration_history = ( self.quality_scorer.agentic_loop( @@ -3705,9 +3228,6 @@ def _remediation_improver( logger.warning(f"Agentic loop execution failed: {exc}") context.results["loop_error"] = str(exc) return None - finally: - if zen_cleanup: - zen_cleanup() context.results["loop_iterations_executed"] = len(iteration_history) context.results["loop_assessment"] = self._serialize_assessment( @@ -3732,93 +3252,6 @@ def _remediation_improver( return {"output": improved_output, "assessment": final_assessment} - async def _run_zen_reviews(self, context: CommandContext, output: Any) -> None: - """Execute deferred Zen MCP reviews for loop iterations.""" - if not context.zen_review_enabled: - return - - targets = context.results.pop("zen_review_targets", []) or [] - if not targets: - return - - zen_instance = self._get_active_mcp_instance("zen") - if not zen_instance: - context.results.setdefault("warnings", []).append( - "Zen MCP unavailable; loop review skipped." - ) - return - - review_method = getattr(zen_instance, "review_code", None) - if not callable(review_method): - context.results.setdefault("warnings", []).append( - "Zen MCP missing review_code capability; skipping zen-review." - ) - return - - reviews: List[Dict[str, Any]] = [] - for target in targets: - diff_blob = target.get("diff") - if not diff_blob: - continue - try: - review_payload = await self._execute_zen_review( - review_method, - context, - diff_blob, - files=target.get("files") or [], - iteration=target.get("iteration"), - ) - except Exception as exc: - logger.warning(f"Zen review failed: {exc}") - context.results.setdefault("zen_review_errors", []).append(str(exc)) - continue - - reviews.append( - { - "iteration": target.get("iteration"), - "files": target.get("files") or [], - "result": review_payload, - } - ) - - if reviews: - context.results.setdefault("zen_reviews", []).extend(reviews) - if isinstance(output, dict): - output["zen_reviews"] = context.results["zen_reviews"] - - async def _execute_zen_review( - self, - review_method: Callable[..., Any], - context: CommandContext, - diff_blob: str, - *, - files: List[str], - iteration: Optional[int], - ) -> Dict[str, Any]: - """Invoke the zen review coroutine and normalize its response.""" - metadata = { - "command": context.command.raw_string, - "iteration": iteration, - "loop_requested": context.results.get("loop_requested", False), - } - - result = await review_method( - diff_blob, - files=files, - model=context.zen_review_model or "gpt-5", - metadata=metadata, - ) - - if isinstance(result, dict): - return result - return {"summary": str(result), "model": context.zen_review_model or "gpt-5"} - - def _get_active_mcp_instance(self, name: str) -> Optional[Any]: - entry = self.active_mcp_servers.get(name) - if not entry: - return None - return entry.get("instance") - def _evaluate_quality_gate( self, context: CommandContext, @@ -4286,89 +3719,12 @@ def _maybe_record_plan_only_event( async def _dispatch_rube_actions( self, context: CommandContext, output: Any ) -> List[str]: - """Send orchestration data to Rube MCP when available.""" - if "rube" not in context.mcp_servers: - return [] - - rube_entry = self.active_mcp_servers.get("rube") - if not rube_entry: - return [] - - instance = rube_entry.get("instance") - if instance is None or not hasattr(instance, "invoke"): - return [] - - request = self._build_rube_request(context, output) - if not request: - return [] + """Legacy method - Rube actions are now handled via native MCP tools. - tool = request["tool"] - payload = request["payload"] - - try: - response = await instance.invoke(tool, payload) - context.results["rube_response"] = response - status = ( - response.get("status", "ok") if isinstance(response, dict) else "ok" - ) - - if self.monitor: - base = "commands.rube" - tags = {"command": context.command.name, "status": status} - self.monitor and self.monitor.record_metric( - f"{base}.invocations", 1, MetricType.COUNTER, tags - ) - metric = f"{base}.dry_run" if status == "dry-run" else f"{base}.success" - self.monitor and self.monitor.record_metric( - metric, 1, MetricType.COUNTER, tags - ) - - return [f"rube:{tool}:{status}"] - except Exception as exc: # pragma: no cover - network behaviour - message = f"Rube automation failed: {exc}" - logger.warning(message) - context.errors.append(message) - if self.monitor: - tags = {"command": context.command.name} - self.monitor and self.monitor.record_metric( - "commands.rube.failure", 1, MetricType.COUNTER, tags - ) - return [f"rube:{tool}:error"] - - def _build_rube_request( - self, context: CommandContext, output: Any - ) -> Optional[Dict[str, Any]]: - """Construct a payload describing the action for Rube MCP.""" - command_name = context.command.name - tool_map = { - "task": "workflow.dispatch", - "workflow": "workflow.dispatch", - "spawn": "workflow.dispatch", - "improve": "automation.log", - "implement": "automation.log", - } - - tool = tool_map.get(command_name) - if not tool: - return None - - payload: Dict[str, Any] = { - "command": command_name, - "session_id": context.session_id, - "summary": self._summarize_rube_context(command_name, output, context), - "metadata": { - "status": context.results.get("status", context.command.name), - "requires_evidence": context.metadata.requires_evidence, - "errors": list(context.errors), - }, - } - - if context.command.arguments: - payload["arguments"] = list(context.command.arguments) - if context.command.parameters: - payload["parameters"] = dict(context.command.parameters) - - return {"tool": tool, "payload": payload} + Use mcp__rube__RUBE_MULTI_EXECUTE_TOOL directly for workflow automation. + """ + # No longer dispatches to internal wrapper - use native MCP tools + return [] def _summarize_rube_context( self, @@ -4809,17 +4165,14 @@ def _apply_execution_flags(self, context: CommandContext) -> None: "min_improvement" ] - zen_review = self._resolve_zen_review_request(parsed, loop_info["enabled"]) - context.zen_review_enabled = zen_review["enabled"] - context.zen_review_model = zen_review["model"] - context.results["zen_review_enabled"] = context.zen_review_enabled - if zen_review["model"]: - context.results["zen_review_model"] = zen_review["model"] - if context.zen_review_enabled: - servers = list(context.metadata.mcp_servers or []) - if "zen" not in servers: - servers.append("zen") - context.metadata.mcp_servers = servers + # PAL review via Python executor is no longer supported - use native MCP tools + pal_review = self._resolve_pal_review_request(parsed, loop_info["enabled"]) + if pal_review["enabled"]: + context.results.setdefault("warnings", []).append( + "PAL review via --pal-review flag is not available in the Python executor. " + "Use native MCP tools directly: mcp__pal__codereview, mcp__pal__consensus" + ) + context.results["pal_review_enabled"] = False context.consensus_forced = self._flag_present(parsed, "consensus") context.results["consensus_forced"] = context.consensus_forced @@ -4880,14 +4233,14 @@ def _resolve_loop_request(self, parsed: ParsedCommand) -> Dict[str, Any]: "min_improvement": min_improvement, } - def _resolve_zen_review_request( + def _resolve_pal_review_request( self, parsed: ParsedCommand, loop_requested: bool ) -> Dict[str, Any]: - """Resolve whether zen-review should run and which model to use.""" - enabled = loop_requested or self._flag_present(parsed, "zen-review") + """Resolve whether pal-review should run and which model to use.""" + enabled = loop_requested or self._flag_present(parsed, "pal-review") model = None - model_keys = ["zen-model", "zen_model", "zen-review-model", "zen_model_name"] + model_keys = ["pal-model", "pal_model", "pal-review-model", "pal_model_name"] for key in model_keys: if key in parsed.parameters: model = str(parsed.parameters[key]).strip() or None diff --git a/SuperClaude/Config/mcp.yaml b/SuperClaude/Config/mcp.yaml index 7875fe50..855b2575 100644 --- a/SuperClaude/Config/mcp.yaml +++ b/SuperClaude/Config/mcp.yaml @@ -1,65 +1,40 @@ -# SuperClaude Framework MCP Server Configuration -# Version: 6.0.0-alpha +# SuperClaude Framework MCP Configuration +# Version: 6.0.0 +# +# NOTE: MCP servers are now accessed via Claude Code's native tool system. +# This file is kept for reference only - no custom wrapper configuration needed. +# +# Native MCP Tools Available: +# +# Rube MCP (mcp__rube__*): +# - RUBE_SEARCH_TOOLS: Discover available tools and integrations +# - RUBE_MULTI_EXECUTE_TOOL: Execute tools in parallel +# - RUBE_CREATE_PLAN: Create execution plans for workflows +# - RUBE_MANAGE_CONNECTIONS: Manage app connections +# - RUBE_REMOTE_WORKBENCH: Execute Python in remote sandbox +# - RUBE_REMOTE_BASH_TOOL: Execute bash in remote sandbox +# +# PAL MCP (mcp__pal__*): +# - chat: General chat and collaborative thinking +# - thinkdeep: Multi-stage investigation and reasoning +# - planner: Interactive sequential planning +# - consensus: Multi-model consensus building +# - codereview: Systematic code review +# - precommit: Git change validation +# - debug: Systematic debugging +# +# Usage: +# These tools are invoked directly via Claude Code's native tool calls. +# No Python wrapper code or configuration is needed. +# +# Example: +# "Use mcp__rube__RUBE_SEARCH_TOOLS to find available integrations" +# "Use mcp__pal__codereview for code review tasks" +# Legacy server references (for documentation only) servers: - zen: - enabled: true - name: Multi-Model Orchestrator - triggers: - - --zen - - --consensus - - --thinkdeep - - --zen-review - capabilities: - - multi-model-consensus - - deep-thinking - - code-review - - validation - priority: high + pal: + note: "Use mcp__pal__consensus, mcp__pal__codereview, mcp__pal__thinkdeep" rube: - enabled: true - name: Rube Automation Hub - triggers: - - --rube - - --external - capabilities: - - automation-proxy - - cross-app-integration - - oauth-broker - priority: low - requires_network: true - endpoint: https://rube.app/mcp - timeout_seconds: 60 - linkup: - default_depth: deep - default_output_type: sourcedAnswer - max_concurrent: 4 - throttle_seconds: 0.0 - -# Integration Configuration -integration: - auto_enable: - complexity_threshold: 0.7 - multi_domain: true - performance_mode: false - - orchestration: - concurrent_servers: 3 - timeout: 300 - retry_limit: 2 - - coordination: - zen_validation: true # Zen validates critical operations - -# Performance Configuration -performance: - batch_operations: true - parallel_execution: true - cache_results: true - stream_responses: true - - limits: - max_concurrent: 5 - memory_limit: 2GB - token_budget: 100000 + note: "Use mcp__rube__RUBE_SEARCH_TOOLS, mcp__rube__RUBE_MULTI_EXECUTE_TOOL" diff --git a/SuperClaude/Core/AGENTS.md b/SuperClaude/Core/AGENTS.md index 01f3e3bd..b766967f 100644 --- a/SuperClaude/Core/AGENTS.md +++ b/SuperClaude/Core/AGENTS.md @@ -3,62 +3,10 @@ ## Core Concept Task agents are specialized sub-agents for complex operations. Use `--delegate` for automatic selection from ALL 131 agents (core + extended) or specify directly with `Task(agent-name)`. -## ⚠️ Critical Instructions - -### Intelligence Maximization Rules -- Use parallel tool calls whenever possible to gather context quickly. -- Check dependencies first so you understand available libraries before coding. -- Follow existing patterns exactly to match established style and conventions. -- Consider edge cases, including error handling, null checks, and race conditions. -- Write testable code that can be exercised with unit tests. -- Never ship quick fixes or overengineeringβ€”prefer clean, maintainable solutions. - -### Command Safety Rules -- Never run destructive or bulk-reset commands (`git checkout -- `, `git reset --hard`, `git clean -fdx`, `rm -rf`, etc.) unless the user explicitly requests it for that path. -- Never use `git checkout`, `git restore`, or similar commands to revert tracked files unless explicitly directed for that file. -- Always consult `.claude/settings.json` before executing shell commands to honor any `denyList` or `askList` guardrails. -- Treat uncertainties as denialsβ€”ask the user if unsure whether a command is safe. -- Prefer targeted edits (e.g., `sed -n`, `apply_patch`) instead of repo-wide operations. -- Log potentially mutating commands in your reasoning so the safety rationale is clear. - -### Current Context -- Current time: October 2025. -- Claude lacks real-time clock access; rely on explicit dates when relevant. - -### Web Search Instructions (Critical) -- Built-in web search is disabled; use LinkUp via Rube MCP for all searches. -- Default to `depth: "deep"` and `output_type: "sourcedAnswer"`. -- Be proactiveβ€”look up library versions, API docs, security updates, error messages, and external service status when needed. - -```json -// mcp__rube__RUBE_MULTI_EXECUTE_TOOL -{ - "tools": [{ - "tool_slug": "LINKUP_SEARCH", - "arguments": { - "query": "your search query here", - "depth": "deep", - "output_type": "sourcedAnswer" - } - }], - "session_id": "WEB-SESSION-001", - "memory": {}, - "sync_response_to_workbench": false, - "thought": "Searching for [topic]", - "current_step": "SEARCHING", - "current_step_metric": {"completed": 0, "total": 1, "unit": "searches"}, - "next_step": "COMPLETE" -} -``` - -> Remember: your training data is static. LinkUp provides current informationβ€”use it liberally when details may have changed. - -## πŸš€ NEW: Unified Agent Registry -All agents now searchable through single registry with intelligent selection: +## Unified Agent Registry - **131 Total Agents**: 15 core + 116 extended specialists -- **Smart Selection**: `--delegate` now searches ALL agents based on context -- **Discovery Features**: Use `--suggest-agents` to see relevant specialists -- **Registry Location**: `agent_registry.yaml` with metadata for all agents +- **Smart Selection**: `--delegate` searches ALL agents based on context +- **Registry Location**: `agent_registry.yaml` ## Quality-Driven Execution Every Task output gets a quality score (0-100): @@ -66,43 +14,99 @@ Every Task output gets a quality score (0-100): - **70-89**: Acceptable β†’ Review notes - **<70**: Needs improvement β†’ Auto-iterate with specialist suggestion +--- + ## Agent Discovery & Selection -### New Discovery Flags -- `--suggest-agents`: Show top 5 relevant agents for current context -- `--agent-search [keyword]`: Find agents by capability -- `--delegate-extended`: Prefer extended agents over core -- `--why`: Explain why an agent was selected +### Discovery Flags +| Flag | Purpose | +|------|---------| +| `--delegate` | Auto-select best agent from all 131 | +| `--suggest-agents` | Show top 5 relevant agents for context | +| `--agent-search [keyword]` | Search agents by capability | +| `--delegate-extended` | Prefer specialists over generalists | +| `--why` | Explain agent selection reasoning | +| `--stick-to-core` | Use only core agents | ### Automatic Context Detection -The framework now detects context and suggests appropriate specialists: -- **File Extensions**: `.rs` β†’ rust-engineer, `.sol` β†’ blockchain-developer -- **Imports**: `tensorflow` β†’ ml-engineer, `react` β†’ react-specialist -- **Keywords**: "kubernetes" β†’ kubernetes-specialist, "payment" β†’ fintech-engineer -- **Quality Escalation**: Core agent scores <70 β†’ suggests specialist - -## Agent Quick Reference - -### Most Used Core Agents (Priority 1) -- **general-purpose**: Unknown scope, exploration -- **root-cause-analyst**: Debugging, error investigation -- **refactoring-expert**: Code improvements, cleanup -- **quality-engineer**: Test coverage, quality metrics -- **technical-writer**: Documentation generation -- **frontend-architect**: UI/UX, React, Vue, Angular -- **backend-architect**: APIs, servers, databases -- **security-engineer**: Vulnerability assessment -- **performance-engineer**: Optimization, bottlenecks -- **python-expert**: Python ecosystem mastery - -### Popular Extended Specialists (Priority 2) -- **typescript-pro**: Advanced TypeScript patterns -- **rust-engineer**: Systems programming -- **kubernetes-specialist**: K8s orchestration -- **ml-engineer**: Machine learning models -- **blockchain-developer**: Web3 and smart contracts -- **react-specialist**: Modern React patterns -- **terraform-engineer**: Infrastructure as Code +| Context | Auto-Selected Agent | +|---------|-------------------| +| `.rs` file | rust-engineer | +| `.tsx` with React imports | react-specialist | +| `Dockerfile` present | devops-architect | +| `.sol` smart contract | blockchain-developer | +| ML notebook `.ipynb` | ml-engineer | +| `terraform.tf` files | terraform-engineer | +| API performance issues | performance-engineer | +| Security vulnerabilities | security-auditor | + +--- + +## Core Agents (15) + +### Most Used (Priority 1) +| Agent | Use For | +|-------|---------| +| **general-purpose** | Unknown scope, exploration | +| **root-cause-analyst** | Debugging, error investigation | +| **refactoring-expert** | Code improvements, cleanup | +| **quality-engineer** | Test coverage, quality metrics | +| **technical-writer** | Documentation generation | +| **frontend-architect** | UI/UX, React, Vue, Angular | +| **backend-architect** | APIs, servers, databases | +| **security-engineer** | Vulnerability assessment | +| **performance-engineer** | Optimization, bottlenecks | +| **python-expert** | Python ecosystem mastery | + +### Additional Core Agents +- **system-architect** - System design, scalability +- **requirements-analyst** - Feature analysis, PRD breakdown +- **socratic-mentor** - Teaching through questions +- **learning-guide** - Tutorials, educational content +- **devops-architect** - Infrastructure, CI/CD + +--- + +## Extended Agent Library (116) + +### Categories Overview + +| Category | Count | Focus | +|----------|-------|-------| +| **01-core-development** | 14 | APIs, mobile, microservices, UI/UX | +| **02-language-specialists** | 26 | TypeScript, Rust, Go, React, Vue, Angular | +| **03-infrastructure** | 12 | K8s, Terraform, Cloud, SRE, DevOps | +| **04-quality-security** | 12 | Security audit, QA, performance, accessibility | +| **05-data-ai** | 12 | ML, LLM, data pipelines, databases | +| **06-developer-experience** | 10 | Build tools, CLI, refactoring, legacy code | +| **07-specialized-domains** | 11 | Blockchain, gaming, IoT, fintech | +| **08-business-product** | 10 | Product management, UX research, docs | +| **09-meta-orchestration** | 8 | Multi-agent coordination, workflows | +| **10-research-analysis** | 6 | Market research, competitive analysis | + +### Top 20 Extended Agents +1. **typescript-pro** - Advanced TypeScript patterns +2. **python-pro** - Python ecosystem expert +3. **react-specialist** - Modern React patterns +4. **kubernetes-specialist** - K8s orchestration +5. **rust-engineer** - Systems programming +6. **golang-pro** - Go concurrency +7. **ml-engineer** - Machine learning +8. **cloud-architect** - Multi-cloud design +9. **security-auditor** - Security assessment +10. **nextjs-developer** - Full-stack Next.js +11. **vue-expert** - Vue 3 expertise +12. **terraform-engineer** - IaC expert +13. **blockchain-developer** - Web3 development +14. **qa-expert** - Test automation +15. **devops-engineer** - CI/CD pipelines +16. **database-optimizer** - Query optimization +17. **api-designer** - REST/GraphQL APIs +18. **mobile-developer** - Cross-platform mobile +19. **microservices-architect** - Distributed systems +20. **technical-writer** - Documentation expert + +--- ## Usage Examples @@ -120,45 +124,27 @@ The framework now detects context and suggests appropriate specialists: ### Direct Agent Invocation ```bash -# Core agent (simplified path) +# Core agent Task(refactoring-expert) # Extended agent (auto-resolved from registry) -Task(rust-engineer) # No need for full path! -Task(kubernetes-specialist) # Framework finds it +Task(rust-engineer) # No need for full path! +Task(kubernetes-specialist) # Framework finds it # Or use full path if preferred Task(Extended/02-language-specialists/rust-engineer) ``` -### Context-Aware Selection -```bash -# Working on Rust file -# Framework auto-suggests: rust-engineer - -# Editing Kubernetes manifests -# Framework auto-suggests: kubernetes-specialist, terraform-engineer - -# Machine learning project -# Framework auto-suggests: ml-engineer, data-engineer, python-pro +### Quality-Based Escalation +``` +Initial: Task(general-purpose) +Quality: 65/100 +Auto-suggest: "Try rust-engineer for Rust expertise" +Retry: Task(rust-engineer) +Quality: 92/100 βœ… ``` -## Extended Agent Categories - -The 116 extended agents are organized into specialized domains: - -- **01-core-development**: APIs, mobile, microservices, UI/UX -- **02-language-specialists**: TypeScript, Rust, Go, React, Vue, Angular -- **03-infrastructure**: K8s, Terraform, Cloud, SRE, DevOps -- **04-quality-security**: Security audit, QA, performance, accessibility -- **05-data-ai**: ML, LLM, data pipelines, databases -- **06-developer-experience**: Build tools, CLI, refactoring, legacy code -- **07-specialized-domains**: Blockchain, gaming, IoT, fintech -- **08-business-product**: Product management, UX research, documentation -- **09-meta-orchestration**: Multi-agent coordination, workflows -- **10-research-analysis**: Market research, competitive analysis - -See **AGENTS_EXTENDED.md** for complete category details and **agent_registry.yaml** for full metadata. +--- ## Context Package Every delegation includes: @@ -173,24 +159,11 @@ context: ## Iteration Pattern ``` 1. Delegate β†’ Task(agent, context) -2. Evaluate β†’ score = quality(output) +2. Evaluate β†’ score = quality(output) 3. Iterate β†’ if score < 70: retry with feedback 4. Accept β†’ when score β‰₯ 70 ``` -## Best Practices - -### DO -- βœ… Always evaluate quality scores -- βœ… Preserve context across iterations -- βœ… Use specialist agents over general-purpose -- βœ… Let quality drive iterations - -### DON'T -- ❌ Accept low-quality outputs -- ❌ Lose context between delegations -- ❌ Exceed iteration limits without permission - ## Integration with Flags | Flag | Effect on Agents | @@ -200,19 +173,15 @@ context: | `--think [1-3]` | Analysis depth | | `--safe-mode` | Conservative execution | -## Example Workflow +## Best Practices -```bash -# Complex debugging ---think 2 --delegate -β†’ Uses root-cause-analyst -β†’ Quality: 65/100 -β†’ Auto-iterates with feedback -β†’ Quality: 88/100 βœ… - -# Refactoring with safety ---delegate --safe-mode --loop 5 -β†’ Uses refactoring-expert -β†’ Maximum validation -β†’ Up to 5 iterations -``` +### DO +- Use `--delegate` for automatic selection +- Evaluate quality scores on every output +- Preserve context across iterations +- Use specialist agents over general-purpose when domain-specific + +### DON'T +- Accept outputs with score < 70 +- Lose context between delegations +- Exceed iteration limits without permission diff --git a/SuperClaude/Core/AGENTS_EXTENDED.md b/SuperClaude/Core/AGENTS_EXTENDED.md deleted file mode 100644 index dc37faf0..00000000 --- a/SuperClaude/Core/AGENTS_EXTENDED.md +++ /dev/null @@ -1,182 +0,0 @@ -# Extended Agent Library - Quick Discovery Guide - -## Overview -The Extended Agent Library provides 100+ specialized agents from the awesome-claude-code-subagents collection, offering production-ready expertise for specific domains and technologies. - -## Quick Selection by Task - -### πŸš€ "I need help with a specific language/framework" -**β†’ Check `02-language-specialists/`** -- **TypeScript**: `typescript-pro.md` - Advanced TypeScript patterns, type gymnastics -- **Python**: `python-pro.md` - Ecosystem mastery, async patterns -- **Rust**: `rust-engineer.md` - Memory safety, systems programming -- **Go**: `golang-pro.md` - Concurrency, microservices -- **React**: `react-specialist.md` - React 18+, hooks, performance -- **Vue**: `vue-expert.md` - Vue 3, Composition API -- **Angular**: `angular-architect.md` - Enterprise patterns -- **Next.js**: `nextjs-developer.md` - Full-stack, SSR/SSG -- **Spring Boot**: `spring-boot-engineer.md` - Java microservices -- **Rails**: `rails-expert.md` - Rails 7+, rapid development - -### πŸ—οΈ "I need infrastructure/DevOps help" -**β†’ Check `03-infrastructure/`** -- **Kubernetes**: `kubernetes-specialist.md` - Container orchestration -- **Terraform**: `terraform-engineer.md` - Infrastructure as Code -- **AWS/GCP/Azure**: `cloud-architect.md` - Multi-cloud expertise -- **CI/CD**: `devops-engineer.md` - Pipeline automation -- **Site Reliability**: `sre-engineer.md` - Monitoring, resilience -- **Incident Response**: `incident-responder.md` - Crisis management - -### πŸ”’ "I need security/quality expertise" -**β†’ Check `04-quality-security/`** -- **Security Audit**: `security-auditor.md` - Vulnerability assessment -- **Penetration Testing**: `penetration-tester.md` - Ethical hacking -- **QA Automation**: `qa-expert.md` - Test frameworks -- **Accessibility**: `accessibility-tester.md` - WCAG compliance -- **Performance**: `performance-engineer.md` - Optimization -- **Code Review**: `code-reviewer.md` - Quality guardian - -### πŸ€– "I need AI/ML/Data expertise" -**β†’ Check `05-data-ai/`** -- **Machine Learning**: `ml-engineer.md` - Model development -- **LLM Architecture**: `llm-architect.md` - Large language models -- **Data Engineering**: `data-engineer.md` - Pipeline architecture -- **MLOps**: `mlops-engineer.md` - Model deployment -- **NLP**: `nlp-engineer.md` - Natural language processing -- **Database Optimization**: `database-optimizer.md` - Query performance - -### πŸ’Ž "I need domain-specific expertise" -**β†’ Check `07-specialized-domains/`** -- **Blockchain/Web3**: `blockchain-developer.md` - Smart contracts, DeFi -- **Gaming**: `game-developer.md` - Game engines, physics -- **IoT**: `iot-engineer.md` - Embedded systems, sensors -- **FinTech**: `fintech-engineer.md` - Financial systems -- **Payments**: `payment-integration.md` - Payment gateways -- **SEO**: `seo-specialist.md` - Search optimization - -### πŸ› οΈ "I need developer tooling/experience help" -**β†’ Check `06-developer-experience/`** -- **Build Systems**: `build-engineer.md` - Webpack, Vite, etc. -- **CLI Tools**: `cli-developer.md` - Command-line interfaces -- **Legacy Code**: `legacy-modernizer.md` - Modernization -- **Refactoring**: `refactoring-specialist.md` - Code improvement -- **Documentation**: `documentation-engineer.md` - Technical docs - -### πŸ“Š "I need business/product expertise" -**β†’ Check `08-business-product/`** -- **Product Management**: `product-manager.md` - Strategy, roadmaps -- **Technical Writing**: `technical-writer.md` - Documentation -- **UX Research**: `ux-researcher.md` - User studies -- **Project Management**: `project-manager.md` - Agile, Scrum -- **Business Analysis**: `business-analyst.md` - Requirements - -### πŸ”„ "I need multi-agent coordination" -**β†’ Check `09-meta-orchestration/`** -- **Agent Coordination**: `multi-agent-coordinator.md` - Complex workflows -- **Workflow Automation**: `workflow-orchestrator.md` - Process automation -- **Context Management**: `context-manager.md` - State optimization -- **Task Distribution**: `task-distributor.md` - Work allocation - -## Usage Examples - -### Direct Invocation -```bash -# Use specific extended agent -Task(Extended/02-language-specialists/rust-engineer) - -# With context -Task(Extended/03-infrastructure/kubernetes-specialist, { - goal: "Deploy microservices to K8s", - constraints: ["Use Helm charts", "Enable auto-scaling"] -}) -``` - -### Discovery Pattern -1. Check this guide for the right category -2. Browse category directory for specific agent -3. Read agent file for detailed capabilities -4. Invoke with appropriate context - -## Top 20 Most Useful Extended Agents - -1. **typescript-pro** - TypeScript mastery -2. **python-pro** - Python ecosystem expert -3. **react-specialist** - Modern React patterns -4. **kubernetes-specialist** - K8s orchestration -5. **rust-engineer** - Systems programming -6. **golang-pro** - Go concurrency -7. **ml-engineer** - Machine learning -8. **cloud-architect** - Multi-cloud design -9. **security-auditor** - Security assessment -10. **nextjs-developer** - Full-stack Next.js -11. **vue-expert** - Vue 3 expertise -12. **terraform-engineer** - IaC expert -13. **blockchain-developer** - Web3 development -14. **qa-expert** - Test automation -15. **devops-engineer** - CI/CD pipelines -16. **database-optimizer** - Query optimization -17. **api-designer** - REST/GraphQL APIs -18. **mobile-developer** - Cross-platform mobile -19. **microservices-architect** - Distributed systems -20. **technical-writer** - Documentation expert - -## Category Deep Dive - -### 01-core-development (14 agents) -Foundation development patterns: APIs, backends, frontends, full-stack, microservices - -### 02-language-specialists (26 agents) -Deep expertise in specific languages and their ecosystems - -### 03-infrastructure (12 agents) -Cloud, containers, networking, platform engineering - -### 04-quality-security (12 agents) -Testing, security, performance, quality assurance - -### 05-data-ai (12 agents) -Data pipelines, ML/AI, analytics, databases - -### 06-developer-experience (10 agents) -Tools, automation, productivity, refactoring - -### 07-specialized-domains (11 agents) -Industry-specific: finance, gaming, IoT, blockchain - -### 08-business-product (10 agents) -Product management, documentation, user research - -### 09-meta-orchestration (8 agents) -Multi-agent coordination, workflow automation - -### 10-research-analysis (6 agents) -Market research, competitive analysis, trends - -## Integration with Core Agents - -The Extended Library complements SuperClaude's 15 core agents: -- **Core agents**: Quick access, general purpose -- **Extended agents**: Specialized expertise, production patterns - -Use core agents for common tasks, extended agents for specialized needs. - -## Best Practices - -1. **Start with core agents** - Often sufficient for general tasks -2. **Use extended for specifics** - When you need deep expertise -3. **Check agent descriptions** - Each file has detailed capabilities -4. **Provide context** - Extended agents work best with clear goals -5. **Combine agents** - Use multiple agents for complex workflows - -## Finding the Right Agent - -Ask yourself: -1. What technology/domain am I working with? -2. What type of task (development/testing/design)? -3. What level of expertise needed? - -Then navigate to the appropriate category and select the most specific agent for your needs. - ---- - -*Extended Agent Library - 100+ specialized agents for every development need* \ No newline at end of file diff --git a/SuperClaude/Core/AGENT_DISCOVERY.md b/SuperClaude/Core/AGENT_DISCOVERY.md deleted file mode 100644 index 9d5208f7..00000000 --- a/SuperClaude/Core/AGENT_DISCOVERY.md +++ /dev/null @@ -1,186 +0,0 @@ -# Agent Discovery & Liberal Usage System - -## Overview -The SuperClaude Framework now treats all 131 agents (15 core + 116 extended) as first-class citizens through a unified registry and intelligent selection system. - -## Key Improvements - -### 1. Unified Agent Registry -- **Location**: `agent_registry.yaml` -- **Contents**: All 131 agents with metadata -- **Benefits**: Single source of truth for agent capabilities - -### 2. Enhanced --delegate Flag -- Now searches ALL 131 agents, not just core 15 -- Uses context-aware selection based on: - - File extensions (`.rs` β†’ rust-engineer) - - Imports (`tensorflow` β†’ ml-engineer) - - Keywords (`kubernetes` β†’ kubernetes-specialist) - - Current project context - -### 3. Discovery Features - -#### New Flags -- `--suggest-agents`: Show top 5 relevant agents for current context -- `--agent-search [keyword]`: Search all agents by capability -- `--delegate-extended`: Prefer specialists over generalists -- `--why`: Explain agent selection reasoning -- `--stick-to-core`: Use only core agents (opt-out) - -#### Discovery Script -```bash -# Search for agents -python3 scripts/agent_discovery.py --search "blockchain" - -# Find agents for specific file -python3 scripts/agent_discovery.py --file src/main.rs - -# List all available agents -python3 scripts/agent_discovery.py --list-all - -# Suggest agents for current project -python3 scripts/agent_discovery.py --suggest -``` - -## Usage Examples - -### Automatic Selection (Recommended) -```bash -# Let framework choose from all 131 agents ---delegate - -# Framework detects: -# - Rust file β†’ rust-engineer -# - React component β†’ react-specialist -# - Kubernetes manifest β†’ kubernetes-specialist -``` - -### Discovery Workflow -```bash -# 1. See what's available ---suggest-agents - -# 2. Search for specific capability ---agent-search "machine learning" - -# 3. Use the specialist -Task(ml-engineer) -``` - -### Quality-Based Escalation -``` -Initial: Task(general-purpose) -Quality: 65/100 -Auto-suggest: "Try rust-engineer for Rust expertise" -Retry: Task(rust-engineer) -Quality: 92/100 βœ… -``` - -## Agent Priority System - -### Priority 1: Core Agents (15) -- Quick access, daily tasks -- General purpose operations -- Always available via simplified names - -### Priority 2: Extended Domains (116) -- Specialized expertise across ten domains -- Language/framework specific personas -- Domain-focused problem solvers - -## Context Detection Examples - -| Context | Auto-Selected Agent | -|---------|-------------------| -| `.rs` file | rust-engineer | -| `.tsx` file with React imports | react-specialist | -| `Dockerfile` present | devops-architect | -| `.sol` smart contract | blockchain-developer | -| ML notebook `.ipynb` | ml-engineer | -| `terraform.tf` files | terraform-engineer | -| API performance issues | performance-engineer | -| Security vulnerabilities | security-auditor | - -## Implementation Status - -### βœ… Phase 1 Complete -- [x] Unified agent registry created -- [x] Enhanced --delegate to search all agents -- [x] Discovery flags added -- [x] Agent search functionality -- [x] Context detection framework - -### 🚧 Phase 2 (Next Steps) -- [ ] Semantic similarity matching -- [ ] Import-based agent selection -- [ ] Quality metric refinement -- [ ] Usage telemetry - -### πŸ“‹ Phase 3 (Future) -- [ ] ML-based routing -- [ ] Team preferences -- [ ] Auto-escalation on quality < 70 -- [ ] Performance optimization - -## Benefits - -1. **Discoverability**: Extended agents are now easily discoverable -2. **Automatic Selection**: Framework picks the right specialist -3. **Quality Improvement**: Specialists provide better outputs -4. **Simplified Usage**: No need to remember paths -5. **Backward Compatible**: Old paths still work - -## Migration Guide - -### Old Way -```bash -# Had to know exact path -Task(Extended/02-language-specialists/rust-engineer) -``` - -### New Way -```bash -# Multiple options: -Task(rust-engineer) # Direct by name ---delegate # Auto-select from context ---suggest-agents # See recommendations -``` - -## Metrics & Success - -- **Before**: ~0% extended agent usage -- **Target**: 30%+ extended agent usage -- **Quality**: 15%+ improvement in task outputs -- **Discovery**: 80%+ user satisfaction with selection - -## Troubleshooting - -### Agent Not Found -```bash -# Search for it ---agent-search "your-keyword" - -# Or let framework find it ---delegate -``` - -### Wrong Agent Selected -```bash -# See why it was chosen ---why - -# Override with specific agent -Task(preferred-agent) - -# Or limit to core only ---stick-to-core -``` - -### Performance Concerns -- Registry search: <10ms for 131 agents -- With caching: <1ms for repeated selections -- No noticeable impact on performance - ---- - -*The SuperClaude Framework now liberally uses all 131 agents to provide specialized expertise exactly when needed.* diff --git a/SuperClaude/Core/FLAGS.md b/SuperClaude/Core/FLAGS.md index ef510547..6dd57d6e 100644 --- a/SuperClaude/Core/FLAGS.md +++ b/SuperClaude/Core/FLAGS.md @@ -38,7 +38,7 @@ - Enable quality-driven iteration (score < 70 = retry) **--tools [name]** -- Enable specific MCP server: zen, rube, browser +- Enable specific MCP server: pal, rube, browser - Use --no-mcp to disable all MCP servers ## Quality Control diff --git a/SuperClaude/Core/PRINCIPLES.md b/SuperClaude/Core/PRINCIPLES.md deleted file mode 100644 index e836311c..00000000 --- a/SuperClaude/Core/PRINCIPLES.md +++ /dev/null @@ -1,72 +0,0 @@ -# SuperClaude Principles - -## Core Philosophy -**Evidence > Assumptions | Code > Documentation | Efficiency > Verbosity** - -## Engineering Principles - -### SOLID -- **Single Responsibility**: One reason to change -- **Open/Closed**: Extend, don't modify -- **Liskov Substitution**: Subtypes must be substitutable -- **Interface Segregation**: No unused dependencies -- **Dependency Inversion**: Depend on abstractions - -### Essential Patterns -- **DRY**: Don't Repeat Yourself -- **KISS**: Keep It Simple, Stupid -- **YAGNI**: You Aren't Gonna Need It - -## Decision Framework - -### Evidence-Based -- Measure before optimizing -- Test hypotheses systematically -- Verify all claims with data - -### Trade-offs -- Immediate vs long-term impact -- Reversible vs irreversible decisions -- Simplicity vs completeness - -### Risk Management -- Identify risks proactively -- Assess probability Γ— impact -- Maintain reversibility when uncertain - -## Quality Standards - -### Four Quadrants -1. **Functional**: Does it work correctly? -2. **Structural**: Is it maintainable? -3. **Performance**: Is it efficient? -4. **Security**: Is it safe? - -### Enforcement -- Automated testing and linting -- Error prevention > exception handling -- Make illegal states unrepresentable - -## Practical Application - -```python -# Good: Explicit validation -def process(user_id: str) -> Optional[Result]: - if not user_id: - return None - return do_work(user_id) - -# Bad: Hidden assumptions -def process(user_id): - try: - return do_work(user_id) - except: - pass # Silent failure -``` - -## Key Takeaways -1. Build only what's requested -2. Complete what you start -3. Validate inputs, not exceptions -4. Evidence drives decisions -5. Simple solutions first \ No newline at end of file diff --git a/SuperClaude/Core/QUICKSTART.md b/SuperClaude/Core/QUICKSTART.md index d73a2837..1423b6b6 100644 --- a/SuperClaude/Core/QUICKSTART.md +++ b/SuperClaude/Core/QUICKSTART.md @@ -58,7 +58,7 @@ - **Performance**: performance-engineer ### MCP Servers (use with --mcp) -- **Consensus & Analysis**: zen +- **Consensus & Analysis**: pal - **Automation (opt-in)**: rube - **LinkUp Web Search**: linkup - **Persistence**: UnifiedStore (built-in, no --mcp flag) diff --git a/SuperClaude/Core/REFERENCE.md b/SuperClaude/Core/REFERENCE.md new file mode 100644 index 00000000..32d869d9 --- /dev/null +++ b/SuperClaude/Core/REFERENCE.md @@ -0,0 +1,192 @@ +# SuperClaude Reference Guide + +This document consolidates principles, recommended rules, and best practices for enhanced operation. + +--- + +## Core Philosophy +**Evidence > Assumptions | Code > Documentation | Efficiency > Verbosity** + +--- + +## Engineering Principles + +### SOLID +| Principle | Rule | +|-----------|------| +| **Single Responsibility** | One reason to change | +| **Open/Closed** | Extend, don't modify | +| **Liskov Substitution** | Subtypes must be substitutable | +| **Interface Segregation** | No unused dependencies | +| **Dependency Inversion** | Depend on abstractions | + +### Essential Patterns +- **DRY**: Don't Repeat Yourself +- **KISS**: Keep It Simple, Stupid +- **YAGNI**: You Aren't Gonna Need It + +--- + +## Quality Standards + +### Four Quadrants +1. **Functional**: Does it work correctly? +2. **Structural**: Is it maintainable? +3. **Performance**: Is it efficient? +4. **Security**: Is it safe? + +### Enforcement +- Automated testing and linting +- Error prevention > exception handling +- Make illegal states unrepresentable + +--- + +## Decision Framework + +### Evidence-Based +- Measure before optimizing +- Test hypotheses systematically +- Verify all claims with data + +### Trade-offs +- Immediate vs long-term impact +- Reversible vs irreversible decisions +- Simplicity vs completeness + +### Risk Management +- Identify risks proactively +- Assess probability Γ— impact +- Maintain reversibility when uncertain + +--- + +## Code Organization + +### Naming Conventions +- **Consistency**: Follow language standards (camelCase for JS, snake_case for Python) +- **Descriptive**: Names must clearly describe purpose +- **Pattern Following**: Match existing project conventions +- **No Mixed Conventions**: Never mix styles within same project + +### Directory Structure +- **Logical**: Organize by feature/domain, not file type +- **Hierarchical**: Clear parent-child relationships +- **Elegant**: Clean, scalable structure + +--- + +## Tool Optimization + +### Selection Priority +``` +MCP Servers > Native Tools > Basic Tools +``` + +### Tool Selection Matrix +| Task | Recommended Tool | +|------|------------------| +| Automation | Rube MCP | +| Consensus Checks | Zen MCP | +| Web Research | LinkUp via Rube | +| Symbol Operations | UnifiedStore | +| Documentation | Repository templates | +| Pattern Search | Grep (not bash grep) | +| Bulk Edits | MultiEdit | + +### Execution Patterns +- **Parallel Everything**: Execute independent operations in parallel +- **Batch Operations**: Use MultiEdit over multiple Edits +- **Agent Delegation**: Use Task agents for >3 step operations + +--- + +## Performance Optimization + +### Parallel Execution +- **File Operations**: Read multiple files in parallel +- **Independent Edits**: Apply edits simultaneously +- **Search Operations**: Run multiple patterns concurrently +- **Test Execution**: Run independent suites in parallel + +### Resource Management +- **Context Awareness**: Switch to `--uc` mode at >75% context +- **Token Efficiency**: Use symbol communication when appropriate +- **Memory Management**: Clean up temporary resources promptly +- **Cache Utilization**: Reuse computed results + +--- + +## Testing Guidelines + +- **Coverage**: Aim for >80% on critical paths +- **Edge Cases**: Always test boundary conditions +- **Error Scenarios**: Test failure paths explicitly +- **Performance Tests**: Include benchmarks for critical operations + +--- + +## Debugging Strategies + +1. **Binary Search**: Isolate by halving the problem space +2. **Minimal Reproduction**: Create smallest failing case +3. **Logging Strategy**: Add strategic log points +4. **Hypothesis Testing**: Form and test specific theories + +--- + +## Architecture Guidelines + +### Component Design +- **Single Purpose**: One clear responsibility per component +- **Loose Coupling**: Minimize dependencies +- **High Cohesion**: Related functionality stays together +- **Clear Interfaces**: Well-defined APIs + +### Data Flow +- **Unidirectional**: Prefer one-way data flow +- **Immutability**: Avoid mutating shared state +- **Event-Driven**: Use events for loose coupling +- **Caching Strategy**: Cache expensive computations + +--- + +## Communication Best Practices + +### Progress Updates +- Update TodoWrite every 3-5 completed items +- Use status symbols consistently: βœ… πŸ”„ ⏳ ❌ +- Brief, technical descriptions +- Specific next steps when blocked + +### Error Reporting +- Include error messages and stack traces +- Document reproduction steps +- List attempted solutions +- Describe impact scope + +--- + +## Quick Reference Checklist + +- [ ] Parallel operations planned? +- [ ] Best tool selected for task? +- [ ] Batch operations utilized? +- [ ] Context usage monitored? +- [ ] Clean workspace maintained? +- [ ] Code patterns followed? +- [ ] Tests comprehensive? +- [ ] Documentation updated? + +--- + +## Key Takeaways + +1. Build only what's requested +2. Complete what you start +3. Validate inputs, not exceptions +4. Evidence drives decisions +5. Simple solutions first +6. Always parallelize independent operations +7. Use specialized tools over generic ones +8. Profile before optimizing diff --git a/SuperClaude/Core/RULES_RECOMMENDED.md b/SuperClaude/Core/RULES_RECOMMENDED.md deleted file mode 100644 index 869db0d3..00000000 --- a/SuperClaude/Core/RULES_RECOMMENDED.md +++ /dev/null @@ -1,164 +0,0 @@ -# Claude Code Recommended Rules - -Best practices and optimization guidelines for enhanced Claude Code operation. -These 🟒 RECOMMENDED rules should be applied when practical. -For critical and important rules, see RULES_CRITICAL.md. - -## 🟒 RECOMMENDED Rules - -### Code Organization -**Triggers**: Creating files, structuring projects, naming decisions - -- **Naming Convention Consistency**: Follow language/framework standards (camelCase for JS, snake_case for Python) -- **Descriptive Names**: Files, functions, variables must clearly describe their purpose -- **Logical Directory Structure**: Organize by feature/domain, not file type -- **Pattern Following**: Match existing project organization and naming schemes -- **Hierarchical Logic**: Create clear parent-child relationships in folder structure -- **No Mixed Conventions**: Never mix camelCase/snake_case/kebab-case within same project -- **Elegant Organization**: Clean, scalable structure that aids navigation and understanding - -βœ… **Right**: `getUserData()`, `user_data.py`, `components/auth/` -❌ **Wrong**: `get_userData()`, `userdata.py`, `files/everything/` - -### Tool Optimization -**Triggers**: Multi-step operations, performance needs, complex tasks - -- **Best Tool Selection**: Always use the most powerful tool for each task (MCP > Native > Basic) -- **Parallel Everything**: Execute independent operations in parallel, never sequentially -- **Agent Delegation**: Use Task agents for complex multi-step operations (>3 steps) -- **MCP Server Usage**: Leverage specialized MCP servers for their strengths: - - MultiEdit for bulk edits - - Zen for consensus and risk validation - - Rube for cross-system automation - - LinkUp via Rube for up-to-date research; validate critical findings manually or through trusted SMEs when needed -- **Batch Operations**: Use MultiEdit over multiple Edits, batch Read calls, group operations -- **Powerful Search**: Use Grep tool over bash grep, Glob over find, specialized search tools -- **Efficiency First**: Choose speed and power over familiarity - use the fastest method available -- **Tool Specialization**: Match tools to their designed purpose - -βœ… **Right**: Use MultiEdit for 3+ file changes, parallel Read calls -❌ **Wrong**: Sequential Edit calls, bash grep instead of Grep tool - -### Performance Optimization - -#### Parallel Execution Patterns -- **File Operations**: Read multiple files in parallel, not sequentially -- **Independent Edits**: Apply edits to multiple files simultaneously -- **Search Operations**: Run multiple search patterns concurrently -- **Test Execution**: Run independent test suites in parallel - -#### Resource Management -- **Context Awareness**: Monitor context usage, switch to --uc mode at >75% -- **Token Efficiency**: Use symbol communication when appropriate -- **Memory Management**: Clean up temporary resources promptly -- **Cache Utilization**: Reuse computed results across operations - -### Code Quality Best Practices - -#### Documentation Standards -- **Inline Comments**: Only when logic is non-obvious -- **Function Documentation**: Clear purpose and parameter descriptions -- **README Updates**: Keep synchronized with code changes -- **API Documentation**: Include examples for all endpoints - -#### Testing Guidelines -- **Test Coverage**: Aim for >80% coverage on critical paths -- **Edge Cases**: Always test boundary conditions -- **Error Scenarios**: Test failure paths explicitly -- **Performance Tests**: Include benchmarks for critical operations - -#### Refactoring Principles -- **Small Increments**: Refactor in small, testable chunks -- **Preserve Behavior**: Ensure tests pass before and after -- **Clean As You Go**: Improve code quality during feature work -- **Technical Debt**: Track and address systematically - -### Communication Best Practices - -#### Progress Updates -- **Regular Checkpoints**: Update TodoWrite every 3-5 completed items -- **Clear Status**: Use status symbols (βœ…, πŸ”„, ⏳, ❌) consistently -- **Concise Explanations**: Brief, technical descriptions -- **Actionable Feedback**: Specific next steps when blocked - -#### Error Reporting -- **Relevant Context**: Include error messages and stack traces -- **Reproduction Steps**: Document how to reproduce issues -- **Attempted Solutions**: List what was already tried -- **Impact Assessment**: Describe scope of the problem - -### Development Workflow Optimizations - -#### Branch Management -- **Descriptive Names**: feature/, bugfix/, refactor/ prefixes -- **Small PRs**: Keep pull requests focused and reviewable -- **Regular Rebasing**: Keep feature branches up-to-date -- **Clean History**: Squash commits when appropriate - -#### Dependency Management -- **Version Pinning**: Use exact versions in production -- **Regular Updates**: Schedule dependency updates -- **Security Scanning**: Check for vulnerabilities -- **License Compliance**: Verify license compatibility - -#### Debugging Strategies -- **Binary Search**: Isolate issues by halving the problem space -- **Minimal Reproduction**: Create smallest failing case -- **Logging Strategy**: Add strategic log points -- **Hypothesis Testing**: Form and test specific theories - -### Architecture Guidelines - -#### Component Design -- **Single Purpose**: Each component has one clear responsibility -- **Loose Coupling**: Minimize dependencies between components -- **High Cohesion**: Related functionality stays together -- **Clear Interfaces**: Well-defined APIs between components - -#### Data Flow -- **Unidirectional**: Prefer one-way data flow patterns -- **Immutability**: Avoid mutating shared state -- **Event-Driven**: Use events for loose coupling -- **Caching Strategy**: Cache expensive computations - -#### Scalability Considerations -- **Horizontal Scaling**: Design for multiple instances -- **Stateless Services**: Keep services stateless when possible -- **Database Optimization**: Use appropriate indexes -- **Async Processing**: Offload heavy work to background jobs - -## Quick Reference - -### Tool Selection Matrix -``` -Task Type β†’ Recommended Tool: -β”œβ”€ Automation β†’ Rube MCP -β”œβ”€ Consensus Checks β†’ Zen MCP -β”œβ”€ Web Research β†’ LinkUp for sourced intelligence; Repository docs for static references -β”œβ”€ Symbol Operations β†’ UnifiedStore -β”œβ”€ Documentation β†’ Repository templates & standards -└─ Pattern Search β†’ Grep (not bash grep) -``` - -### Optimization Checklist -- [ ] Parallel operations planned? -- [ ] Best tool selected for task? -- [ ] Batch operations utilized? -- [ ] Context usage monitored? -- [ ] Clean workspace maintained? -- [ ] Code patterns followed? -- [ ] Tests comprehensive? -- [ ] Documentation updated? - -### Performance Tips -1. **Always parallelize** independent operations -2. **Batch similar operations** together -3. **Use specialized tools** over generic ones -4. **Monitor context usage** and adapt -5. **Clean as you go** to prevent bloat -6. **Cache computed results** when possible -7. **Profile before optimizing** specific code - ---- -*Recommended practices for optimal Claude Code operation* -*Apply these guidelines when practical to enhance quality and efficiency* diff --git a/SuperClaude/Core/migrate_serena_data.py b/SuperClaude/Core/migrate_serena_data.py deleted file mode 100644 index 0f0720a3..00000000 --- a/SuperClaude/Core/migrate_serena_data.py +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env python3 -""" -One-time migration helper that copies legacy Serena data into UnifiedStore. - -Run this script before removing Serena integrations to ensure existing -session memories and symbols are preserved inside the new SQLite-backed -store located at ~/.claude/unified_store.db. -""" - -from __future__ import annotations - -import json -from pathlib import Path -from typing import Any - -from SuperClaude.Core.unified_store import SymbolInfo, UnifiedStore - - -def migrate_serena_data() -> bool: - """ - Copy entries from serena_memory.json into the UnifiedStore database. - - Returns: - bool: True if migration succeeded or no data was found. False on error. - """ - serena_file = Path.home() / ".claude" / "serena_memory.json" - if not serena_file.exists(): - print("No serena_memory.json found – skipping migration.") - return True - - print(f"Migrating Serena data from {serena_file}") - store = UnifiedStore() - - try: - content = serena_file.read_text(encoding="utf-8") - data: dict[str, Any] = json.loads(content) - except Exception as exc: # pragma: no cover - defensive logging - print(f"Failed to read Serena data: {exc}") - store.close() - return False - - # Restore memories - memories = data.get("memories", {}) or {} - for key, value in memories.items(): - store.write_memory(key, value) - print(f" Migrated memory key: {key}") - - # Restore symbols - symbols = data.get("symbols", []) or [] - for symbol_data in symbols: - symbol = SymbolInfo( - name=symbol_data.get("name", ""), - kind=symbol_data.get("kind", ""), - file_path=symbol_data.get("path") or symbol_data.get("file_path", ""), - line=symbol_data.get("line", 0), - signature=symbol_data.get("signature"), - ) - store.add_symbol(symbol) - if symbols: - print(f" Migrated {len(symbols)} symbols") - - store.close() - - # Backup original JSON file for safety. - backup_path = serena_file.with_suffix(".json.backup") - try: - serena_file.rename(backup_path) - print(f"Legacy file backed up to {backup_path}") - except Exception as exc: # pragma: no cover - defensive logging - print(f"Warning: unable to rename legacy file ({exc}).") - - print("Migration completed successfully.") - return True - - -if __name__ == "__main__": - migrate_serena_data() diff --git a/SuperClaude/Core/worktree_manager.py b/SuperClaude/Core/worktree_manager.py index 86c95fff..cb636408 100644 --- a/SuperClaude/Core/worktree_manager.py +++ b/SuperClaude/Core/worktree_manager.py @@ -43,8 +43,9 @@ def __init__(self, repo_path: str, max_worktrees: int = 10): # Create repository and worktree directories if they don't exist try: self.repo_path.mkdir(parents=True, exist_ok=True) - except Exception: - pass + except Exception as e: + # Directory creation failed; may already exist or permission issue + logger.debug(f"Could not create repo_path directory: {e}") self.worktree_dir.mkdir(parents=True, exist_ok=True) # Load or initialize state diff --git a/SuperClaude/MCP/MCP_LinkUp.md b/SuperClaude/MCP/MCP_LinkUp.md index 7e80073d..b7dc15a4 100644 --- a/SuperClaude/MCP/MCP_LinkUp.md +++ b/SuperClaude/MCP/MCP_LinkUp.md @@ -1,70 +1,79 @@ -# LinkUp Web Intelligence (via Rube MCP) +# LinkUp Web Search (via Rube MCP) -LinkUp extends the existing Rube MCP integration with deep web search -capabilities. It issues `LINKUP_SEARCH` requests over the active Rube session -and returns sourced answers, citations, and URLs that SuperClaude commands can -surface as evidence. +LinkUp provides deep web search capabilities with sourced answers, citations, and URLs through the native Rube MCP tools. -## Capabilities +## How to Use -- **Deep search with citations** – combine summarised answers, source lists, and - follow-up links suitable for change plans. -- **Configurable depth/output** – adjust `depth`, `output_type`, and throttle - controls without modifying code. -- **Batch-friendly** – run multiple LinkUp queries per command using the shared - Rube session (respecting concurrency and throttling limits). +LinkUp searches are executed via `mcp__rube__RUBE_MULTI_EXECUTE_TOOL`: -## Prerequisites +``` +Use mcp__rube__RUBE_MULTI_EXECUTE_TOOL with: + tools: [{ + "tool_slug": "LINKUP_SEARCH", + "arguments": { + "query": "your search query here", + "depth": "deep", + "output_type": "sourcedAnswer" + } + }] + session_id: "" + memory: {} + sync_response_to_workbench: false + thought: "Searching for [topic]" + current_step: "SEARCHING" + next_step: "COMPLETE" +``` -1. Provision Rube MCP access (see `MCP_Rube.md`) and set `SC_RUBE_API_KEY`. -2. Ensure `SC_NETWORK_MODE` permits outbound requests (`online`, `mixed`, - `rube`, or `auto`). -3. Optional: export `SC_RUBE_MODE=dry-run` to inspect payloads without sending - live traffic (responses echo the payload for debugging). +## Parameters -## Configuration (`SuperClaude/Config/mcp.yaml`) +| Parameter | Values | Description | +|-----------|--------|-------------| +| `query` | string | The search query | +| `depth` | `"deep"`, `"standard"` | Search thoroughness (use "deep" for comprehensive results) | +| `output_type` | `"sourcedAnswer"`, `"searchResults"`, `"structured"` | Response format | -```yaml -servers: - rube: - linkup: - default_depth: deep - default_output_type: sourcedAnswer - max_concurrent: 4 - throttle_seconds: 0.0 -``` +## Capabilities -- `default_depth` / `default_output_type` are applied when commands do not - override `depth` or `output_type`. -- `max_concurrent` limits the number of in-flight LinkUp calls (tune for rate - limits). -- `throttle_seconds` enforces a minimum delay between calls when providers ask - for pacing. -- Add any persistent payload keys under `payload_defaults` (e.g., domain - filters) to avoid repeating them in command parameters. +- **Deep search with citations** - summarized answers with source lists and follow-up links +- **Multiple queries** - batch multiple searches in a single tool call +- **Sourced answers** - responses include citations and URLs for verification -## CLI Usage +## Example Usage +### Simple Search ``` -/sc:test --linkup --query "pytest asyncio best practices" +Use mcp__rube__RUBE_MULTI_EXECUTE_TOOL with: + tools: [{ + "tool_slug": "LINKUP_SEARCH", + "arguments": { + "query": "pytest asyncio best practices 2025", + "depth": "deep", + "output_type": "sourcedAnswer" + } + }] ``` -- `--linkup` (or the legacy `--browser`) toggles LinkUp for `/sc:test`. -- Provide one or more queries via `--query`, `--linkup-query`, or `--linkup-queries`. -- Results are stored under `context.results['linkup_queries']` with per-query - status, citation data, and any surfaced warnings. +### Batch Searches +``` +Use mcp__rube__RUBE_MULTI_EXECUTE_TOOL with: + tools: [ + {"tool_slug": "LINKUP_SEARCH", "arguments": {"query": "React 19 new features", "depth": "deep", "output_type": "sourcedAnswer"}}, + {"tool_slug": "LINKUP_SEARCH", "arguments": {"query": "TypeScript 5.4 changes", "depth": "deep", "output_type": "sourcedAnswer"}} + ] +``` -## Dry-Run Behaviour +## When to Use -When `SC_RUBE_MODE=dry-run`, LinkUp logs payloads and returns structured -placeholders. Commands still receive deterministic responses but no outbound -traffic occursβ€”ideal for CI environments lacking network access. +Use LinkUp for: +- Current library/framework versions and documentation +- Latest API syntax and best practices +- Recent security updates and vulnerabilities +- Error messages and deprecation warnings +- External service status and configuration -## Troubleshooting +## Notes -- **Missing Rube server** – ensure `/sc:test` metadata lists `rube` in its MCP - servers and that `_activate_mcp_servers` successfully initialised Rube. -- **Empty queries** – commands emit `linkup_failed` when no query is supplied; - pass `--query` or positional `https://…` targets. -- **Rate limits** – increase `throttle_seconds` or reduce `max_concurrent` if - providers return HTTP `429` responses. +- LinkUp is accessed through the Rube MCP server's LINKUP_SEARCH tool +- No separate configuration needed - uses the same Rube MCP connection +- Session IDs from RUBE_SEARCH_TOOLS should be reused for context preservation +- Results include citations - include source links in responses diff --git a/SuperClaude/MCP/MCP_Pal.md b/SuperClaude/MCP/MCP_Pal.md new file mode 100644 index 00000000..a961378a --- /dev/null +++ b/SuperClaude/MCP/MCP_Pal.md @@ -0,0 +1,93 @@ +# PAL MCP Server (Native) - Formerly "Zen" + +PAL MCP provides collaborative thinking, code review, and multi-model consensus through Claude Code's native MCP tools. + +## Native MCP Tools + +Use these tools directly via Claude Code's tool invocation: + +| Tool | Description | +|------|-------------| +| `mcp__pal__chat` | General chat and collaborative thinking | +| `mcp__pal__thinkdeep` | Multi-stage investigation and reasoning | +| `mcp__pal__planner` | Interactive sequential planning with revision | +| `mcp__pal__consensus` | Multi-model consensus through structured debate | +| `mcp__pal__codereview` | Systematic code review with expert validation | +| `mcp__pal__precommit` | Git change validation before committing | +| `mcp__pal__debug` | Systematic debugging and root cause analysis | +| `mcp__pal__challenge` | Critical thinking when statements are challenged | +| `mcp__pal__apilookup` | Current API/SDK documentation lookup | +| `mcp__pal__listmodels` | List available AI models | +| `mcp__pal__clink` | Link to external AI CLIs (Gemini, Codex, etc.) | + +## Capabilities + +- **Multi-model consensus** - consult multiple models with different stances +- **Deep thinking** - systematic hypothesis testing and evidence gathering +- **Code review** - comprehensive analysis of quality, security, performance +- **Git validation** - pre-commit checks for staged/unstaged changes +- **Debugging** - structured root cause analysis for complex issues + +## Usage Examples + +### Code Review +``` +Use mcp__pal__codereview with: + step: "Review the authentication module for security issues" + step_number: 1 + total_steps: 2 + next_step_required: true + findings: "Initial security scan..." + relevant_files: ["/path/to/auth.py"] + model: "gpt-5.2" +``` + +### Multi-Model Consensus +``` +Use mcp__pal__consensus with: + step: "Evaluate: Should we use REST or GraphQL for the new API?" + step_number: 1 + total_steps: 3 + next_step_required: true + findings: "Analyzing tradeoffs..." + models: [ + {"model": "gpt-5.2", "stance": "for"}, + {"model": "gemini-3-pro-preview", "stance": "against"} + ] +``` + +### Deep Thinking +``` +Use mcp__pal__thinkdeep with: + step: "Investigate the performance bottleneck in the database layer" + step_number: 1 + total_steps: 3 + next_step_required: true + findings: "Initial profiling shows..." + hypothesis: "The N+1 query pattern may be causing slowdowns" + model: "gpt-5.2" +``` + +### Debugging +``` +Use mcp__pal__debug with: + step: "Analyze the intermittent test failures in CI" + step_number: 1 + total_steps: 2 + next_step_required: true + findings: "Test logs show timing-related failures..." + hypothesis: "Race condition in async initialization" + model: "gpt-5.2" +``` + +## Configuration + +PAL MCP server configuration is handled by Claude Code settings. +No SuperClaude-specific environment variables are needed. + +## Notes + +- All tools are invoked directly via Claude Code's native tool system +- continuation_id allows multi-turn conversations across tool calls +- thinking_mode controls reasoning depth (minimal/low/medium/high/max) +- Models can be specified by name - use listmodels to see available options diff --git a/SuperClaude/MCP/MCP_Rube.md b/SuperClaude/MCP/MCP_Rube.md index d51198b7..13c3be91 100644 --- a/SuperClaude/MCP/MCP_Rube.md +++ b/SuperClaude/MCP/MCP_Rube.md @@ -1,22 +1,67 @@ -# Rube MCP Server +# Rube MCP Server (Native) -The Rube MCP server connects SuperClaude to Composio's automation hub, enabling access to hundreds of SaaS integrations from a single endpoint. +Rube MCP connects SuperClaude to Composio's automation hub, enabling access to 500+ SaaS integrations through Claude Code's native MCP tools. + +## Native MCP Tools + +Use these tools directly via Claude Code's tool invocation: + +| Tool | Description | +|------|-------------| +| `mcp__rube__RUBE_SEARCH_TOOLS` | Discover available tools and integrations | +| `mcp__rube__RUBE_MULTI_EXECUTE_TOOL` | Execute tools in parallel (up to 20) | +| `mcp__rube__RUBE_CREATE_PLAN` | Create execution plans for workflows | +| `mcp__rube__RUBE_MANAGE_CONNECTIONS` | Create/manage app connections | +| `mcp__rube__RUBE_REMOTE_WORKBENCH` | Execute Python in remote sandbox | +| `mcp__rube__RUBE_REMOTE_BASH_TOOL` | Execute bash in remote sandbox | +| `mcp__rube__RUBE_FIND_RECIPE` | Find recipes by natural language | +| `mcp__rube__RUBE_EXECUTE_RECIPE` | Execute saved recipes | +| `mcp__rube__RUBE_GET_RECIPE_DETAILS` | Get recipe details | +| `mcp__rube__RUBE_MANAGE_RECIPE_SCHEDULE` | Manage scheduled recipe runs | ## Capabilities -- **Workflow dispatch** – create tickets, update sprints, or trigger CI/CD pipelines. -- **Notification fan-out** – post release notes or QA status updates across collaboration tools. -- **Data sync** – coordinate artefacts (docs, dashboards, sheets) with orchestrated changes. +- **Workflow dispatch** - create tickets, update sprints, trigger CI/CD pipelines +- **Notification fan-out** - post release notes or QA status updates across tools +- **Data sync** - coordinate artifacts (docs, dashboards, sheets) with changes +- **Web search** - LinkUp integration for sourced answers and citations + +## Usage Examples + +### Search for Tools +``` +Use mcp__rube__RUBE_SEARCH_TOOLS with: + queries: [{"use_case": "send a message to slack"}] + session: {generate_id: true} +``` + +### Execute Tools +``` +Use mcp__rube__RUBE_MULTI_EXECUTE_TOOL with: + tools: [{"tool_slug": "SLACK_SEND_MESSAGE", "arguments": {...}}] + session_id: "" + memory: {} + sync_response_to_workbench: false +``` + +### Web Search (LinkUp) +``` +Use mcp__rube__RUBE_MULTI_EXECUTE_TOOL with: + tools: [{"tool_slug": "LINKUP_SEARCH", "arguments": { + "query": "your search query", + "depth": "deep", + "output_type": "sourcedAnswer" + }}] +``` ## Configuration -- Endpoint: `https://rube.app/mcp` (default) -- Credentials: set `SC_RUBE_API_KEY` with your Composio OAuth token. -- Network: export `SC_NETWORK_MODE=online` to allow outbound calls. When missing, the integration runs in dry-run mode and only logs payloads. -- Dry-run: force simulation even when online with `SC_RUBE_MODE=dry-run`. +MCP server configuration is handled by Claude Code settings, not SuperClaude. +No environment variables (like `SC_RUBE_API_KEY`) are needed - auth is managed by the MCP server. -## Safety Notes +## Notes -- The connector fails fast with descriptive errors if credentials are missing or the endpoint is unreachable. -- Dry-run mode is recommended for CI and local development because it never touches external services. -- Future releases will add secure secret storage and granular scope controls. +- All tools are invoked directly via Claude Code's native tool system +- No Python wrapper code is used - tools are called directly +- Session IDs are managed per workflow for context preservation +- Memory parameter helps track cross-call state diff --git a/SuperClaude/MCP/MCP_Zen.md b/SuperClaude/MCP/MCP_Zen.md deleted file mode 100644 index 9350cf10..00000000 --- a/SuperClaude/MCP/MCP_Zen.md +++ /dev/null @@ -1,48 +0,0 @@ -# Zen MCP Integration - -The Zen integration exposes SuperClaude's consensus engine over the Model -Context Protocol. It now delegates to the live `ModelRouterFacade` instead of a -mock heuristic. - -## Capabilities - -- **Consensus:** Executes the same voting logic as the core executor. -- **Thinking modes:** Maps MCP thinking levels to `--think` values (minimal β†’ 1, - max β†’ 5). -- **Quorum rules:** Respects the `vote` parameter supplied by the client; quorum - size defaults to `⌈n/2βŒ‰ + 1` when unspecified. - -## Configuration - -- Enable in `SuperClaude/Config/mcp.yaml` under the `zen` entry. -- Optional environment variables: - - `SC_ZEN_OFFLINE=1` to force offline mode (expect explicit executor - registration). - - `SUPERCLAUDE_OFFLINE_MODE=1` to turn off provider lookups globally. - -## Usage - -```python -from SuperClaude.MCP import ZenIntegration -from SuperClaude.ModelRouter.facade import ModelRouterFacade - -facade = ModelRouterFacade() -zen = ZenIntegration(facade=facade) -zen.initialize() -await zen.initialize_session() -result = await zen.consensus("Approve deployment?", models=None) -``` - -## Error Handling - -- If no provider executors are registered the integration raises `RuntimeError` - instead of returning fabricated votes. -- Downstream callers should catch the exception and either register custom - executors (for offline tests) or prompt the operator to configure API keys. - -## Telemetry - -- Consensus payloads contain the selected models, agreement score, and - per-model metadata. Capture them in your MCP client logs for auditing. - -Refer to `Docs/User-Guide/mcp-servers.md` for broader MCP configuration details. diff --git a/SuperClaude/MCP/__init__.py b/SuperClaude/MCP/__init__.py index 0ce09b91..e0298458 100644 --- a/SuperClaude/MCP/__init__.py +++ b/SuperClaude/MCP/__init__.py @@ -1,64 +1,83 @@ -"""SuperClaude Framework MCP Server Integrations.""" +"""SuperClaude Framework MCP Server Reference. -from __future__ import annotations - -from typing import Any, Dict, Mapping, Type - -from .rube_integration import RubeIntegration, RubeInvocationError +This module documents the native MCP tools available through Claude Code. +SuperClaude no longer uses custom HTTP wrappers - all MCP functionality +is accessed through Claude Code's native tool invocation. -__version__ = "6.0.0-alpha" - -__all__ = [ - "RubeIntegration", - "RubeInvocationError", - "get_mcp_integration", - "integration_import_errors", -] +Native MCP Tools Available: +--------------------------- -_IMPORT_ERRORS: dict[str, ModuleNotFoundError] = {} +Rube MCP (mcp__rube__*): + - RUBE_SEARCH_TOOLS: Discover available tools and integrations + - RUBE_MULTI_EXECUTE_TOOL: Execute tools in parallel + - RUBE_CREATE_PLAN: Create execution plans for workflows + - RUBE_MANAGE_CONNECTIONS: Manage app connections + - RUBE_REMOTE_WORKBENCH: Execute Python in remote sandbox + - RUBE_REMOTE_BASH_TOOL: Execute bash in remote sandbox + - RUBE_FIND_RECIPE: Find recipes by natural language + - RUBE_EXECUTE_RECIPE: Execute saved recipes + - RUBE_MANAGE_RECIPE_SCHEDULE: Manage scheduled recipe runs -try: # Optional dependency: PyYAML via ModelRouter - from .zen_integration import ( # type: ignore[unused-import] - ConsensusResult, - ConsensusType, - ModelConfig, - ThinkingMode, - ZenIntegration, - ) -except ModuleNotFoundError as exc: # pragma: no cover - depends on local extras - if exc.name == "yaml": - _IMPORT_ERRORS["zen"] = exc - else: - raise -else: - __all__.extend( - [ - "ConsensusResult", - "ConsensusType", - "ModelConfig", - "ThinkingMode", - "ZenIntegration", - ] - ) +PAL MCP (mcp__pal__*): + - chat: General chat and collaborative thinking + - thinkdeep: Multi-stage investigation and reasoning + - planner: Interactive sequential planning + - consensus: Multi-model consensus building + - codereview: Systematic code review + - precommit: Git change validation + - debug: Systematic debugging and root cause analysis + - challenge: Critical thinking and analysis + - apilookup: Current API/SDK documentation lookup + - listmodels: List available AI models + - clink: Link to external AI CLIs (Gemini, Codex, etc.) -MCP_SERVERS: dict[str, type[Any]] = { - "rube": RubeIntegration, -} +Usage: +------ +These tools are invoked directly by Claude Code's tool system. +No Python wrapper code is needed - just call the tools directly +in your prompts or command implementations. -if "zen" not in _IMPORT_ERRORS: - MCP_SERVERS["zen"] = ZenIntegration +Example in documentation/prompts: + "Use mcp__rube__RUBE_SEARCH_TOOLS to find available integrations" + "Use mcp__pal__codereview for code review tasks" +""" +from __future__ import annotations -def integration_import_errors() -> Mapping[str, ModuleNotFoundError]: - """Return a mapping of server name β†’ import error (if any).""" +__version__ = "6.0.0" - return dict(_IMPORT_ERRORS) +# Native MCP tool namespaces (for documentation/reference only) +RUBE_TOOLS = [ + "RUBE_SEARCH_TOOLS", + "RUBE_MULTI_EXECUTE_TOOL", + "RUBE_CREATE_PLAN", + "RUBE_MANAGE_CONNECTIONS", + "RUBE_REMOTE_WORKBENCH", + "RUBE_REMOTE_BASH_TOOL", + "RUBE_FIND_RECIPE", + "RUBE_EXECUTE_RECIPE", + "RUBE_GET_RECIPE_DETAILS", + "RUBE_GET_TOOL_SCHEMAS", + "RUBE_MANAGE_RECIPE_SCHEDULE", + "RUBE_CREATE_UPDATE_RECIPE", +] +PAL_TOOLS = [ + "chat", + "thinkdeep", + "planner", + "consensus", + "codereview", + "precommit", + "debug", + "challenge", + "apilookup", + "listmodels", + "version", + "clink", +] -def get_mcp_integration(server_name: str, **kwargs): - """Factory to create an MCP integration instance by server name.""" - cls = MCP_SERVERS.get(server_name) - if not cls: - available = ", ".join(sorted(MCP_SERVERS.keys())) - raise ValueError(f"Unknown MCP server: {server_name}. Available: {available}") - return cls(**kwargs) +__all__ = [ + "RUBE_TOOLS", + "PAL_TOOLS", +] diff --git a/SuperClaude/MCP/__main__.py b/SuperClaude/MCP/__main__.py deleted file mode 100644 index 140c4e11..00000000 --- a/SuperClaude/MCP/__main__.py +++ /dev/null @@ -1,148 +0,0 @@ -"""Command-line helpers for inspecting MCP integrations. - -Usage: - python -m SuperClaude.MCP --list - python -m SuperClaude.MCP --describe rube -""" - -from __future__ import annotations - -import argparse -import json -import textwrap -from typing import Any - - -def _summarize_docstring(obj: Any) -> str: - doc = (getattr(obj, "__doc__", "") or "").strip() - if not doc: - return "" - first_line = doc.splitlines()[0].strip() - return first_line - - -def _load_registry(): - from . import ( # pylint: disable=import-outside-toplevel - MCP_SERVERS, - integration_import_errors, - ) - - return MCP_SERVERS, integration_import_errors() - - -def _describe_server(registry: dict[str, Any], name: str) -> dict[str, Any]: - cls = registry[name] - info: dict[str, Any] = { - "name": name, - "class": f"{cls.__module__}.{cls.__name__}", - "summary": _summarize_docstring(cls), - } - - # Collect common class-level metadata when present. - for attr in ("DEFAULT_ENDPOINT", "NETWORK_OK_VALUES", "DRY_RUN_VALUES"): - if hasattr(cls, attr): - value = getattr(cls, attr) - if isinstance(value, set): - value = sorted(value) - info[attr.lower()] = value - - # Best-effort instance attributes (constructor has no required args). - try: - instance = cls() # type: ignore[call-arg] - except Exception as exc: # pragma: no cover - defensive - info["warning"] = f"failed to instantiate: {exc}" - return info - - for attr in ("enabled", "requires_network", "endpoint", "timeout_seconds"): - value = getattr(instance, attr, None) - if callable(value): - # Skip callables – we only want plain attribute values. - continue - if value is not None: - if isinstance(value, set): - value = sorted(value) - info[attr] = value - - return info - - -def main(argv: list[str] | None = None) -> int: - parser = argparse.ArgumentParser( - description="Inspect available Model Context Protocol integrations", - formatter_class=argparse.RawDescriptionHelpFormatter, - epilog=textwrap.dedent( - """ - Examples: - python -m SuperClaude.MCP --list - python -m SuperClaude.MCP --describe rube --json - """ - ).strip(), - ) - parser.add_argument( - "--list", - action="store_true", - help="List available MCP server names.", - ) - parser.add_argument( - "--describe", - metavar="NAME", - help="Describe the specified server (name from --list).", - ) - parser.add_argument( - "--json", - action="store_true", - help="Emit structured JSON when used with --describe.", - ) - - args = parser.parse_args(argv) - - if not args.list and not args.describe: - parser.print_help() - return 0 - - registry, import_errors = _load_registry() - - if args.list: - print("Available MCP servers:") - for name in sorted(registry): - summary = _summarize_docstring(registry[name]) - if summary: - print(f" - {name}: {summary}") - else: - print(f" - {name}") - for name, error in sorted(import_errors.items()): - missing = error.name or "dependency" - print(f" - {name}: unavailable (missing dependency '{missing}')") - - if args.describe: - key = args.describe.lower() - if key not in registry: - if key in import_errors: - missing = import_errors[key].name or "dependency" - parser.error( - f"server '{args.describe}' is unavailable: missing optional dependency '{missing}'." - ) - parser.error( - f"unknown server '{args.describe}'. Run with --list to see options." - ) - - info = _describe_server(registry, key) - - if args.json: - print(json.dumps(info, indent=2, sort_keys=True)) - else: - print(f"Details for '{info['name']}':") - for field, value in info.items(): - if field == "name": - continue - if isinstance(value, (set, tuple, list)): - value_repr = ", ".join(map(str, value)) - else: - value_repr = str(value) - print(f" {field}: {value_repr}") - - return 0 - - -if __name__ == "__main__": # pragma: no cover - CLI entry point - raise SystemExit(main()) diff --git a/SuperClaude/MCP/rube_integration.py b/SuperClaude/MCP/rube_integration.py deleted file mode 100644 index 4cbd66f3..00000000 --- a/SuperClaude/MCP/rube_integration.py +++ /dev/null @@ -1,425 +0,0 @@ -""" -Rube MCP Integration - -Provides an asynchronous client wrapper that can talk to the hosted Rube MCP -endpoint when network access is permitted, while supporting a dry-run mode for -offline execution. -""" - -from __future__ import annotations - -import asyncio -import json -import logging -import os -import time -from typing import Any, Awaitable, Callable, Dict - -logger = logging.getLogger(__name__) - -try: # Optional dependency for real HTTP calls - import httpx # type: ignore -except ImportError: # pragma: no cover - httpx may not be installed - httpx = None # type: ignore - - -AsyncSender = Callable[[str, Dict[str, Any]], Awaitable[Dict[str, Any]]] - -# LinkUp defaults -DEFAULT_LINKUP_DEPTH = "deep" -DEFAULT_LINKUP_OUTPUT_TYPE = "sourcedAnswer" -DEFAULT_LINKUP_TOOL = "LINKUP_SEARCH" - - -class RubeInvocationError(RuntimeError): - """Structured error raised when a live Rube MCP invocation fails.""" - - def __init__( - self, - message: str, - *, - status: int | None = None, - code: str | None = None, - details: dict[str, Any] | None = None, - ): - super().__init__(message) - self.status = status - self.code = code - self.details = details or {} - - -class RubeIntegration: - """ - Integration that talks to the Rube MCP server via HTTP. - - Behaviour: - - Enabled by configuration (defaults to True). - - Requires outbound network access unless running in dry-run mode. - - Reads OAuth token from config or environment variable `SC_RUBE_API_KEY`. - - Respects `SC_RUBE_MODE=dry-run` or offline network mode to avoid real calls. - """ - - DEFAULT_ENDPOINT = "https://rube.app/mcp" - NETWORK_OK_VALUES = {"online", "mixed", "rube", "auto"} - DRY_RUN_VALUES = {"dry-run", "dryrun", "1", "true", "yes", "enabled"} - - def __init__( - self, - config: dict[str, Any] | None = None, - http_sender: AsyncSender | None = None, - ): - self.config = config or {} - self.endpoint = self.config.get("endpoint", self.DEFAULT_ENDPOINT) - self.requires_network = bool(self.config.get("requires_network", True)) - self.timeout_seconds = float(self.config.get("timeout_seconds", 60)) - self.api_key = self.config.get("api_key") or os.getenv("SC_RUBE_API_KEY") - self.scopes = self.config.get("scopes", []) - self._enabled = bool(self.config.get("enabled", True)) - self._initialized = False - self._session_ready = False - self._dry_run = False - self._http_sender = http_sender - self._client: httpx.AsyncClient | None = None # type: ignore[name-defined] - self.telemetry_enabled = bool(self.config.get("telemetry_enabled", True)) - self.telemetry_label = self.config.get("telemetry_label", "rube_mcp") - # LinkUp config - linkup_cfg = self.config.get("linkup", {}) - self._linkup_depth = linkup_cfg.get("default_depth", DEFAULT_LINKUP_DEPTH) - self._linkup_output_type = linkup_cfg.get( - "default_output_type", DEFAULT_LINKUP_OUTPUT_TYPE - ) - self._linkup_max_concurrent = max(1, int(linkup_cfg.get("max_concurrent", 4))) - - @property - def enabled(self) -> bool: - """Return whether the integration is enabled.""" - return self._enabled - - def initialize(self) -> bool: - """Perform synchronous initialization.""" - if not self.enabled: - raise RuntimeError("Rube MCP integration is disabled in configuration.") - - self._initialized = True - logger.info("Initialized Rube MCP integration (endpoint=%s)", self.endpoint) - return True - - async def initialize_session(self) -> bool: - """Prepare asynchronous resources and determine dry-run mode.""" - if not self._initialized: - raise RuntimeError("Call initialize() before initialize_session().") - - self._dry_run = self._should_dry_run() - - if ( - not self._dry_run - and self.requires_network - and not self._http_sender - and httpx is None - ): - raise RuntimeError( - "httpx is required for live Rube MCP requests. " - "Install httpx or set SC_RUBE_MODE=dry-run." - ) - - if not self._dry_run and self.requires_network and not self.api_key: - raise RuntimeError( - "SC_RUBE_API_KEY must be set to use Rube MCP in live mode. " - "Set SC_RUBE_MODE=dry-run to simulate responses." - ) - - if not self._dry_run and self._http_sender is None and httpx is not None: - headers = ( - {"Authorization": f"Bearer {self.api_key}"} if self.api_key else {} - ) - self._client = httpx.AsyncClient( # type: ignore[name-defined] - base_url=self.endpoint, - timeout=self.timeout_seconds, - headers=headers or None, - ) - - self._session_ready = True - logger.debug( - "Rube MCP session ready (dry_run=%s, network_required=%s).", - self._dry_run, - self.requires_network, - ) - return True - - async def close(self) -> None: - """Close any underlying resources.""" - if self._client is not None: - await self._client.aclose() - self._client = None - - async def invoke(self, tool: str, payload: dict[str, Any]) -> dict[str, Any]: - """ - Invoke a tool via Rube MCP. - - Args: - tool: The tool identifier to execute. - payload: Parameters for the tool. - """ - if not self._session_ready: - raise RuntimeError( - "Rube MCP session not initialized. Call initialize_session() first." - ) - - request_body = { - "tool": tool, - "payload": payload, - "scopes": self.scopes, - } - - if self._dry_run: - logger.info("Rube MCP dry-run: %s", json.dumps(request_body, default=str)) - return { - "status": "dry-run", - "tool": tool, - "payload": payload, - "message": "Dry-run mode: no external request was sent.", - } - - sender = self._http_sender or self._send_via_httpx - return await self._invoke_with_retries(sender, request_body, tool) - - # ------------------------------------------------------------------------- - # LinkUp convenience methods - # ------------------------------------------------------------------------- - - async def linkup_search( - self, - query: str, - depth: str | None = None, - output_type: str | None = None, - ) -> dict[str, Any]: - """Execute a single LinkUp web search. - - Args: - query: The search query string. - depth: Search depth ("deep" or "standard"). Defaults to config. - output_type: Output format ("sourcedAnswer", "searchResults"). Defaults to config. - - Returns: - Dict with search results including citations and sources. - """ - if not query or not query.strip(): - raise ValueError("LinkUp query cannot be empty") - - payload = { - "query": query.strip(), - "depth": depth or self._linkup_depth, - "output_type": output_type or self._linkup_output_type, - } - return await self.invoke(DEFAULT_LINKUP_TOOL, payload) - - async def linkup_batch_search( - self, - queries: list[str], - max_concurrent: int | None = None, - ) -> list[dict[str, Any]]: - """Execute multiple LinkUp searches with concurrency control. - - Args: - queries: List of search query strings. - max_concurrent: Max parallel requests. Defaults to config (4). - - Returns: - List of result dicts, one per query. Failed queries return - {"status": "failed", "error": "..."}. - """ - if not queries: - return [] - - concurrency = max_concurrent or self._linkup_max_concurrent - semaphore = asyncio.Semaphore(concurrency) - - async def _run(q: str) -> dict[str, Any]: - async with semaphore: - try: - return await self.linkup_search(q) - except RubeInvocationError as exc: - return {"status": "failed", "error": str(exc), "query": q} - except ValueError as exc: - return {"status": "failed", "error": str(exc), "query": q} - - results = await asyncio.gather( - *(_run(q) for q in queries), return_exceptions=False - ) - return list(results) - - async def _send_via_httpx(self, url: str, body: dict[str, Any]) -> dict[str, Any]: - """Send a request using httpx (live mode).""" - if self._client is None: - raise RuntimeError("HTTP client not initialized for Rube MCP.") - - response = await self._client.post("", json=body) - response.raise_for_status() - data = response.json() - if not isinstance(data, dict): - raise RuntimeError("Rube MCP returned non-object JSON.") - return data - - def _should_dry_run(self) -> bool: - """Determine if the integration should operate in dry-run mode.""" - explicit = os.getenv("SC_RUBE_MODE", "").strip().lower() - if explicit in self.DRY_RUN_VALUES: - return True - - network_mode = os.getenv("SC_NETWORK_MODE", "offline").strip().lower() - if self.requires_network and network_mode not in self.NETWORK_OK_VALUES: - return True - - # Fallback to dry-run when no HTTP transport is available - if self.requires_network and self._http_sender is None and httpx is None: - return True - - return False - - async def _invoke_with_retries( - self, - sender: AsyncSender, - request_body: dict[str, Any], - tool: str, - ) -> dict[str, Any]: - """Invoke sender with single retry on transient errors.""" - for attempt in (1, 2): # Max 2 attempts (1 retry) - start = time.perf_counter() - try: - response = await sender(self.endpoint, request_body) - duration = time.perf_counter() - start - if not isinstance(response, dict): - raise RuntimeError("Unexpected Rube MCP response format.") - self._record_telemetry("success", tool, request_body, attempt, duration) - return response - except Exception as exc: - duration = time.perf_counter() - start - retryable = self._is_retryable(exc) - - if attempt == 2 or not retryable: - self._record_telemetry( - "failure", tool, request_body, attempt, duration, error=exc - ) - error_details = self._format_error(exc) - error_details.update( - {"tool": tool, "attempts": attempt, "endpoint": self.endpoint} - ) - raise RubeInvocationError( - f"Rube MCP request failed after {attempt} attempt(s)", - status=error_details.get("status"), - code=error_details.get("code"), - details=error_details, - ) from exc - - # Single retry with fixed 1s delay - logger.debug("Rube MCP transient error, retrying in 1s: %s", exc) - await asyncio.sleep(1.0) - - raise RubeInvocationError("Unexpected retry exhaustion") - - def _is_retryable(self, exc: Exception) -> bool: - """Determine if an exception is retryable.""" - transient_types = (asyncio.TimeoutError,) - if httpx is not None: - transient_types = transient_types + ( - httpx.TransportError, # type: ignore[attr-defined] - httpx.TimeoutException, # type: ignore[attr-defined] - ) - - if isinstance(exc, transient_types): - return True - - message = str(exc).lower() - transient_tokens = ( - "timeout", - "temporarily", - "again later", - "rate limit", - "429", - ) - return any(token in message for token in transient_tokens) - - def _record_telemetry( - self, - outcome: str, - tool: str, - request_body: dict[str, Any], - attempt: int, - duration: float, - *, - error: Exception | None = None, - extra: dict[str, Any] | None = None, - ) -> None: - """Emit structured telemetry for each invocation outcome.""" - if not self.telemetry_enabled: - return - - payload_keys = sorted(request_body.get("payload", {}).keys()) - event = { - "label": self.telemetry_label, - "event": "rube_mcp.invoke", - "tool": tool, - "outcome": outcome, - "attempt": attempt, - "duration_ms": round(duration * 1000, 3), - "endpoint": self.endpoint, - "dry_run": self._dry_run, - "payload_keys": payload_keys, - "scopes": list(self.scopes), - } - - if extra: - event.update(extra) - - if error: - event["error"] = self._summarize_error(error) - - log_line = "[RubeMCP] %s" - log_payload = json.dumps(event, default=str) - if outcome == "success": - logger.info(log_line, log_payload) - elif outcome == "retry": - logger.warning(log_line, log_payload) - else: - logger.error(log_line, log_payload) - - def _summarize_error(self, exc: Exception) -> dict[str, Any]: - """Provide a compact summary of an exception for telemetry.""" - summary: dict[str, Any] = { - "type": exc.__class__.__name__, - "message": str(exc), - } - response = getattr(exc, "response", None) - if response is not None: - summary["status"] = getattr(response, "status_code", None) - return summary - - def _format_error(self, exc: Exception) -> dict[str, Any]: - """Produce a detailed, structured error payload.""" - details = self._summarize_error(exc) - response = getattr(exc, "response", None) - if response is not None: - details["status"] = getattr(response, "status_code", None) - details["code"] = getattr(response, "reason_phrase", None) - try: - details["response_body"] = response.json() - except Exception: # pragma: no cover - defensive - text = response.text - details["response_body"] = self._truncate(text) - headers = { - k: v for k, v in response.headers.items() if k.lower().startswith("x-") - } - if headers: - details["response_headers"] = headers - request = getattr(response, "request", None) - if request is not None: - details["method"] = getattr(request, "method", None) - details["url"] = str(getattr(request, "url", "")) or None - return details - - @staticmethod - def _truncate(value: str, limit: int = 512) -> str: - """Truncate long strings for error reporting.""" - if len(value) <= limit: - return value - return value[:limit] + "..." diff --git a/SuperClaude/MCP/zen_integration.py b/SuperClaude/MCP/zen_integration.py deleted file mode 100644 index 9d7e8729..00000000 --- a/SuperClaude/MCP/zen_integration.py +++ /dev/null @@ -1,330 +0,0 @@ -""" -Zen MCP Integration - -Local implementation that fronts the ModelRouter consensus engine. This -module now also provides a lightweight `--zen-review` facade used by the -executor's agentic loop. -""" - -import json -import re -from dataclasses import dataclass, field -from datetime import datetime -from enum import Enum -from typing import Any, Dict, List, Optional - -from ..ModelRouter.consensus import VoteType -from ..ModelRouter.facade import ModelRouterFacade - - -class ThinkingMode(Enum): - minimal = "minimal" - low = "low" - medium = "medium" - high = "high" - max = "max" - - -class ConsensusType(Enum): - majority = "majority" - unanimous = "unanimous" - quorum = "quorum" - weighted = "weighted" - - -@dataclass -class ModelConfig: - name: str - weight: float = 1.0 - role: Optional[str] = None - - -@dataclass -class ConsensusResult: - consensus_reached: bool - final_decision: Any - votes: List[Dict[str, Any]] = field(default_factory=list) - agreement_score: float = 0.0 - vote_type: str = "majority" - total_time: float = 0.0 - total_tokens: int = 0 - created_at: str = field(default_factory=lambda: datetime.now().isoformat()) - - -class ZenIntegration: - """ - Minimal in-process consensus orchestrator. - - Notes: - - No external API calls; simulates responses locally. - - Provides initialize/initialize_session to satisfy executor hooks. - - The `consensus` method performs a simple weighted frequency vote. - """ - - def __init__( - self, - config: Optional[Dict[str, Any]] = None, - facade: Optional[ModelRouterFacade] = None, - ): - self.config = config or {} - self.initialized = False - self.session_active = False - self._facade: Optional[ModelRouterFacade] = facade - - def initialize(self): - if self._facade is None: - self._facade = ModelRouterFacade(offline=self.config.get("offline")) - self.initialized = True - return True - - async def initialize_session(self): - self._ensure_facade() - self.session_active = True - return True - - async def consensus( - self, - prompt: str, - models: Optional[List[ModelConfig]] = None, - vote: ConsensusType = ConsensusType.majority, - thinking: ThinkingMode = ThinkingMode.low, - context: Optional[Dict[str, Any]] = None, - ) -> ConsensusResult: - facade = self._ensure_facade() - model_names = [m.name for m in models] if models else None - router_vote = self._resolve_vote_type(vote) - think_level = self._resolve_think_level(thinking) - - payload = await facade.run_consensus( - prompt, - models=model_names, - vote_type=router_vote, - quorum_size=self._resolve_quorum(vote, models), - context=context, - think_level=think_level, - ) - - if payload.get("error"): - raise RuntimeError(payload["error"]) - - votes: List[Dict[str, Any]] = [] - for entry in payload.get("votes", []): - votes.append( - { - "model": entry.get("model"), - "vote": entry.get("response"), - "confidence": entry.get("confidence"), - "weight": next( - ( - m.weight - for m in (models or []) - if m.name == entry.get("model") - ), - 1.0, - ), - "metadata": entry.get("metadata"), - } - ) - - return ConsensusResult( - consensus_reached=payload.get("consensus_reached", False), - final_decision=payload.get("final_decision"), - votes=votes, - agreement_score=payload.get("agreement_score", 0.0), - vote_type=router_vote.value, - total_time=payload.get("total_time", 0.0), - total_tokens=payload.get("total_tokens", 0), - created_at=datetime.now().isoformat(), - ) - - async def review_code( - self, - diff: str, - *, - files: Optional[List[str]] = None, - model: str = "gpt-5", - severity_filter: Optional[str] = None, - metadata: Optional[Dict[str, Any]] = None, - max_issues: int = 10, - ) -> Dict[str, Any]: - """Run a GPT-5 code review over a diff block via Zen consensus.""" - if not diff or not diff.strip(): - raise ValueError("diff payload required for zen-review") - - prompt = self._build_review_prompt( - diff, files or [], severity_filter, max_issues - ) - models = [ModelConfig(name=model, weight=1.0)] - review_context = { - "mode": "zen-review", - "files": files or [], - "metadata": metadata or {}, - "severity_filter": severity_filter, - } - - consensus = await self.consensus( - prompt, - models=models, - vote=ConsensusType.majority, - thinking=ThinkingMode.high, - context=review_context, - ) - - parsed = self._parse_review_response(consensus.final_decision) - parsed.setdefault("model", model) - parsed.setdefault("created_at", datetime.now().isoformat()) - parsed.setdefault("raw", consensus.final_decision) - parsed.setdefault("agreement_score", consensus.agreement_score) - parsed.setdefault("consensus", consensus.consensus_reached) - parsed.setdefault("tokens_used", consensus.total_tokens) - parsed.setdefault("files", files or []) - return parsed - - # ------------------------------------------------------------------ - # Helpers - # ------------------------------------------------------------------ - - def _ensure_facade(self) -> ModelRouterFacade: - if self._facade is None: - self._facade = ModelRouterFacade(offline=self.config.get("offline")) - if not self.initialized: - self.initialized = True - return self._facade - - @staticmethod - def _resolve_vote_type(vote: ConsensusType) -> VoteType: - mapping = { - ConsensusType.majority: VoteType.MAJORITY, - ConsensusType.unanimous: VoteType.UNANIMOUS, - ConsensusType.quorum: VoteType.QUORUM, - ConsensusType.weighted: VoteType.WEIGHTED, - } - return mapping.get(vote, VoteType.MAJORITY) - - @staticmethod - def _resolve_think_level(mode: ThinkingMode) -> int: - ordering = [ - ThinkingMode.minimal, - ThinkingMode.low, - ThinkingMode.medium, - ThinkingMode.high, - ThinkingMode.max, - ] - return max(1, ordering.index(mode) + 1) - - @staticmethod - def _resolve_quorum( - vote: ConsensusType, models: Optional[List[ModelConfig]] - ) -> int: - if vote != ConsensusType.quorum or not models: - return 2 - return max(1, (len(models) // 2) + 1) - - @staticmethod - def _build_review_prompt( - diff: str, - files: List[str], - severity_filter: Optional[str], - max_issues: int, - ) -> str: - file_text = ", ".join(files) if files else "(files inferred from diff)" - severity_text = severity_filter or "critical" - schema = ( - '{"overall_score": number 0-100, "summary": string, ' - '"critical_issues": integer, "dimensions": {' - '"correctness": {"score": number, "issues": [string], "suggestions": [string]}, ' - '"completeness": {"score": number, "issues": [string], "suggestions": [string]}, ' - '"maintainability": {"score": number}, "security": {"score": number}, ' - '"performance": {"score": number}, "scalability": {"score": number}, ' - '"testability": {"score": number}, "usability": {"score": number}}, ' - '"improvements": [string], "issues": [{"severity": "critical|warning|nit", ' - '"title": string, "details": string, "files": [string], "recommendation": string}], ' - '"recommendations": [string]}' - ) - return ( - "You are GPT-5 performing a production code review for Claude Code's agentic loop. " - "Evaluate the diff below for logical, security, and quality issues. " - "Report ONLY JSON matching this schema: " + schema + ". " - "Highlight up to " - + str(max_issues) - + " issues prioritising severity >= " - + severity_text - + ".\n" - f"Files: {file_text}\n" - "Diff to review:\n" + diff.strip() - ) - - def _parse_review_response(self, payload: Any) -> Dict[str, Any]: - if isinstance(payload, dict): - return self._normalize_review_payload(payload) - if isinstance(payload, str): - json_blob = self._extract_json_blob(payload) - if json_blob: - try: - data = json.loads(json_blob) - return self._normalize_review_payload(data) - except json.JSONDecodeError: - pass - return { - "score": 0.0, - "summary": payload.strip(), - "critical_issues": 0, - "warnings": 0, - "issues": [], - "recommendations": [], - } - return { - "score": 0.0, - "summary": "zen-review returned no structured payload", - "critical_issues": 0, - "warnings": 0, - "issues": [], - "recommendations": [], - } - - @staticmethod - def _normalize_review_payload(data: Dict[str, Any]) -> Dict[str, Any]: - issues = data.get("issues") or [] - normalized_issues: List[Dict[str, Any]] = [] - for issue in issues: - if not isinstance(issue, dict): - continue - normalized_issues.append( - { - "severity": str(issue.get("severity", "warning")), - "title": issue.get("title") or issue.get("summary") or "Unnamed", - "details": issue.get("details") or issue.get("description") or "", - "files": issue.get("files") or [], - "recommendation": issue.get("recommendation") - or issue.get("fix") - or "", - } - ) - - normalized_dimensions: Dict[str, Dict[str, Any]] = {} - raw_dimensions = data.get("dimensions") or {} - if isinstance(raw_dimensions, dict): - for key, payload in raw_dimensions.items(): - if not isinstance(payload, dict): - continue - normalized_dimensions[key] = { - "score": float(payload.get("score", 0.0)), - "issues": payload.get("issues") or [], - "suggestions": payload.get("suggestions") or [], - } - - return { - "score": float(data.get("overall_score", data.get("score", 0.0))), - "summary": str(data.get("summary", "")), - "critical_issues": int(data.get("critical_issues", 0)), - "warnings": int(data.get("warnings", 0)), - "issues": normalized_issues, - "recommendations": data.get("recommendations") or [], - "dimensions": normalized_dimensions, - "improvements": data.get("improvements") or [], - } - - @staticmethod - def _extract_json_blob(text: str) -> Optional[str]: - match = re.search(r"\{.*\}", text, re.DOTALL) - return match.group(0) if match else None diff --git a/SuperClaude/Quality/quality_scorer.py b/SuperClaude/Quality/quality_scorer.py index 781115ea..fc2a9951 100644 --- a/SuperClaude/Quality/quality_scorer.py +++ b/SuperClaude/Quality/quality_scorer.py @@ -36,7 +36,7 @@ class QualityDimension(Enum): SCALABILITY = "scalability" TESTABILITY = "testability" USABILITY = "usability" - ZEN_REVIEW = "zen_review" + PAL_REVIEW = "pal_review" @dataclass @@ -148,7 +148,7 @@ def __init__( QualityDimension.SCALABILITY: 0.10, QualityDimension.TESTABILITY: 0.10, QualityDimension.USABILITY: 0.05, - QualityDimension.ZEN_REVIEW: 0.10, + QualityDimension.PAL_REVIEW: 0.10, } self._load_configuration() diff --git a/SuperClaude/__main__.py b/SuperClaude/__main__.py index 6792e355..1e2507a6 100644 --- a/SuperClaude/__main__.py +++ b/SuperClaude/__main__.py @@ -493,8 +493,9 @@ def main() -> int: logger = get_logger() if logger: logger.exception(f"Unhandled error: {e}") - except: - print(f"{Colors.RED}[ERROR] {e}{Colors.RESET}") + except Exception: + # Logger itself failed; fall back to stderr + print(f"{Colors.RED}[ERROR] {e}{Colors.RESET}", file=sys.stderr) return 1 diff --git a/config/superclaud.yaml b/config/superclaud.yaml index 31ea157c..22263219 100644 --- a/config/superclaud.yaml +++ b/config/superclaud.yaml @@ -111,7 +111,7 @@ mcp_servers: retry_attempts: 3 servers: - zen: + pal: enabled: true models: - gpt-5 diff --git a/examples/advanced_workflows.py b/examples/advanced_workflows.py deleted file mode 100644 index fb4bf87a..00000000 --- a/examples/advanced_workflows.py +++ /dev/null @@ -1,317 +0,0 @@ -#!/usr/bin/env python3 -""" -SuperClaude Framework Advanced Workflow Examples -Demonstrates complex multi-component interactions -""" - -import asyncio -import sys -from pathlib import Path - -sys.path.insert(0, str(Path(__file__).parent.parent)) - -from SuperClaude.Coordination.agent_coordinator import AgentCoordinator -from SuperClaude.Testing.integration_framework import TestRunner - -from SuperClaude.Agents.extended_loader import ExtendedAgentLoader -from SuperClaude.Agents.loader import AgentLoader -from SuperClaude.Core.worktree_manager import WorktreeManager -from SuperClaude.MCP import ZenIntegration -from SuperClaude.ModelRouter.router import ModelRouter -from SuperClaude.Quality.quality_scorer import QualityScorer - - -async def workflow_feature_development(): - """Complete feature development workflow""" - print("\n=== Feature Development Workflow ===") - print("Goal: Implement user authentication with TDD") - - # Phase 1: Requirements Analysis - print("\nPhase 1: Requirements Analysis") - loader = AgentLoader() - analyst = await loader.select_agent("gather requirements for authentication") - print(f" Agent: {analyst.id}") - - requirements = { - "features": ["login", "logout", "session management", "OAuth2"], - "security": ["JWT tokens", "rate limiting", "CSRF protection"], - "testing": ["unit tests", "integration tests", "E2E tests"], - } - print(f" Requirements gathered: {len(requirements)} categories") - - # Phase 2: Architecture Design - print("\nPhase 2: Architecture Design") - architect = await loader.select_agent("design authentication architecture") - print(f" Agent: {architect.id}") - - # Phase 3: Implementation - print("\nPhase 3: Implementation") - worktree_manager = WorktreeManager("/tmp/project") - worktree = await worktree_manager.create_worktree( - "auth-feature", "feature/authentication" - ) - print(f" Worktree created: {worktree['path']}") - - # Coordinate multiple agents - coordinator = AgentCoordinator() - result = await coordinator.coordinate( - task={ - "goal": "Implement authentication", - "subtasks": [ - "Create database models", - "Implement JWT service", - "Create API endpoints", - "Add middleware", - "Write tests", - ], - }, - strategy="pipeline", - agents=[ - "backend-architect", - "python-expert", - "security-engineer", - "qa-engineer", - ], - ) - print(f" Implementation completed: {result['completed']}/{result['total']} tasks") - - # Phase 4: Quality Validation - print("\nPhase 4: Quality Validation") - scorer = QualityScorer() - score = scorer.calculate_score( - { - "correctness": 92, - "completeness": 88, - "performance": 85, - "maintainability": 90, - "security": 95, - "scalability": 87, - "testability": 93, - "usability": 86, - } - ) - print(f" Quality score: {score['overall']}/100 ({score['grade']})") - - # Phase 5: Testing - print("\nPhase 5: Testing") - runner = TestRunner() - test_results = await runner.run_all_tests() - print(f" Tests run: {test_results['total']}") - print(f" Passed: {test_results['passed']}") - print(f" Failed: {test_results['failed']}") - - # Phase 6: Merge - print("\nPhase 6: Progressive Merge") - if score["overall"] >= 70 and test_results["failed"] == 0: - merge_result = await worktree_manager.progressive_merge( - worktree["id"], "integration" - ) - print(f" Merged to integration: {merge_result['success']}") - - -async def workflow_debugging_complex_issue(): - """Complex debugging workflow with multi-model consensus""" - print("\n=== Complex Debugging Workflow ===") - print("Issue: Intermittent performance degradation in production") - - # Step 1: Multi-angle analysis with Zen - print("\nStep 1: Multi-Model Analysis") - zen = ZenIntegration() - analysis = await zen.deep_think( - problem="Intermittent API slowdowns, 10x latency spikes every few hours", - context_files=["/logs/api.log", "/metrics/performance.json"], - model="gpt-5", - max_tokens=50000, - ) - print(f" Deep thinking completed: {analysis['hypothesis']}") - - # Step 2: Build consensus on root cause - print("\nStep 2: Multi-Model Consensus") - consensus = await zen.build_consensus( - f"Root cause hypothesis: {analysis['hypothesis']}", - models=["gpt-5", "claude-opus-4.1", "gemini-2.5-pro"], - context=analysis["evidence"], - ) - print(f" Consensus confidence: {consensus['confidence']}%") - print(f" Agreed root cause: {consensus['conclusion']}") - - # Step 3: Coordinate fix implementation - print("\nStep 3: Coordinated Fix") - coordinator = AgentCoordinator() - ExtendedAgentLoader() - - # Select specialized agents - agents_needed = [] - if "database" in consensus["conclusion"].lower(): - agents_needed.append("database-engineer") - if "cache" in consensus["conclusion"].lower(): - agents_needed.append("performance-engineer") - if "memory" in consensus["conclusion"].lower(): - agents_needed.append("backend-architect") - - await coordinator.coordinate( - task={"goal": f"Fix: {consensus['conclusion']}"}, - strategy="swarm", - agents=agents_needed, - ) - print(f" Fix implemented by {len(agents_needed)} agents") - - # Step 4: Validate fix - print("\nStep 4: Validation") - print(" Run LinkUp web search for recent regression advisories") - print(" Trigger external Playwright/Cypress pipeline for UI regression checks") - print(" Aggregate results into UnifiedStore for cross-session tracking") - - -async def workflow_large_codebase_refactoring(): - """Refactoring workflow for large codebases""" - print("\n=== Large Codebase Refactoring Workflow ===") - print("Goal: Modernize 100K+ line legacy codebase") - - # Step 1: Analyze with Gemini (2M context) - print("\nStep 1: Ultra-Long Context Analysis") - router = ModelRouter() - model = await router.select_model( - task_type="bulk-analysis", - context_size=1500000, # 1.5M tokens - priority="high", - ) - print(f" Selected model: {model['name']} ({model['context_window']} tokens)") - - # Step 2: Plan refactoring strategy - print("\nStep 2: Strategic Planning") - zen = ZenIntegration() - plan = await zen.plan( - goal="Modernize codebase: migrate to microservices, add types, improve tests", - constraints=[ - "maintain backward compatibility", - "zero downtime", - "incremental migration", - ], - model="gpt-5", - ) - print(f" Plan created: {plan['phases']} phases, {plan['estimated_weeks']} weeks") - - # Step 3: Create worktrees for parallel work - print("\nStep 3: Parallel Worktrees") - manager = WorktreeManager("/tmp/legacy-project") - worktrees = [] - for phase in range(1, plan["phases"] + 1): - wt = await manager.create_worktree( - f"refactor-phase-{phase}", f"refactor/phase-{phase}" - ) - worktrees.append(wt) - print(f" Created worktree for phase {phase}: {wt['path']}") - - # Step 4: Coordinate specialized agents - print("\nStep 4: Multi-Agent Refactoring") - coordinator = AgentCoordinator() - - for phase, wt in enumerate(worktrees, 1): - result = await coordinator.coordinate( - task={"goal": f"Phase {phase} refactoring", "worktree": wt["path"]}, - strategy="hierarchical" if phase == 1 else "pipeline", - agents=[ - "refactoring-specialist", - "typescript-expert", - "test-automation", - "microservices-architect", - "legacy-modernization", - ], - ) - print(f" Phase {phase} completed: {result['success']}") - - # Step 5: Progressive integration - print("\nStep 5: Progressive Integration") - for phase, wt in enumerate(worktrees, 1): - validation = await manager.validate_worktree(wt["id"]) - if validation["ready"]: - merge = await manager.progressive_merge(wt["id"], "integration") - print(f" Phase {phase} merged: {merge['success']}") - - -async def workflow_production_deployment(): - """Production deployment with comprehensive validation""" - print("\n=== Production Deployment Workflow ===") - print("Goal: Deploy critical feature with zero downtime") - - # Step 1: Pre-deployment validation - print("\nStep 1: Pre-Deployment Validation") - zen = ZenIntegration() - review = await zen.code_review( - path="/src", review_type="full", severity_filter="high", model="gpt-5" - ) - print(f" Code review score: {review['score']}/100") - print(f" Critical issues: {review['critical_issues']}") - - if review["critical_issues"] > 0: - print(" ❌ Deployment blocked: Critical issues found") - return - - # Step 2: Multi-model consensus on deployment readiness - print("\nStep 2: Deployment Consensus") - consensus = await zen.build_consensus( - "Is this code ready for production deployment?", - models=["gpt-5", "claude-opus-4.1", "gpt-4.1"], - context={"review": review, "tests": "all passing", "coverage": "92%"}, - ) - print(f" Consensus: {consensus['decision']}") - print(f" Confidence: {consensus['confidence']}%") - - if consensus["confidence"] < 80: - print(" ⚠️ Low confidence - manual review required") - return - - # Step 3: Performance validation - print("\nStep 3: Performance Validation") - monitor = None # Monitoring removed - monitor.start_collection() - - # Simulate load test - await asyncio.sleep(0.5) - - metrics = monitor.get_metrics() - bottlenecks = monitor.detect_bottlenecks() - - print(f" CPU usage: {metrics['cpu_percent']}%") - print(f" Memory usage: {metrics['memory_percent']}%") - print(f" Bottlenecks: {len(bottlenecks)}") - - # Step 4: Deploy with monitoring - print("\nStep 4: Progressive Deployment") - stages = ["canary", "staging", "production"] - for stage in stages: - print(f" Deploying to {stage}...") - # Deployment logic here - - # Run E2E tests via external automation - print(f" Initiating external UI regression suite for {stage}") - print(" βœ… Automation pipeline reported success") - - -async def main(): - """Run all workflow examples""" - print("SuperClaude Framework Advanced Workflows") - print("=" * 50) - - workflows = [ - workflow_feature_development(), - workflow_debugging_complex_issue(), - workflow_large_codebase_refactoring(), - workflow_production_deployment(), - ] - - for workflow in workflows: - try: - await workflow - except Exception as e: - print( - f" Note: This is a demonstration. Actual implementation would handle: {e}" - ) - - print("\n" + "=" * 50) - print("Advanced workflow examples completed!") - - -if __name__ == "__main__": - asyncio.run(main()) diff --git a/examples/basic_usage.py b/examples/basic_usage.py deleted file mode 100644 index dcc018c9..00000000 --- a/examples/basic_usage.py +++ /dev/null @@ -1,254 +0,0 @@ -#!/usr/bin/env python3 -""" -SuperClaude Framework Basic Usage Examples -Demonstrates core functionality of v6.0.0-alpha -""" - -import asyncio -import os -import sys -from pathlib import Path - -# Add parent directory to path -sys.path.insert(0, str(Path(__file__).parent.parent)) - -from SuperClaude.Agents.extended_loader import ExtendedAgentLoader -from SuperClaude.Agents.loader import AgentLoader -from SuperClaude.Commands.registry import CommandRegistry -from SuperClaude.Core.worktree_manager import WorktreeManager -from SuperClaude.ModelRouter.router import ModelRouter -from SuperClaude.Quality.quality_scorer import QualityScorer - - -async def example_agent_loading(): - """Example: Loading and using agents""" - print("\n=== Agent Loading Example ===") - - # Load core agents - core_loader = AgentLoader() - core_agents = await core_loader.get_available_agents() - print(f"Loaded {len(core_agents)} core agents") - - # Load extended agents - extended_loader = ExtendedAgentLoader() - extended_agents = extended_loader.load_all_agents() - print(f"Loaded {len(extended_agents)} extended agents") - - # Select an agent for a task - task = "Debug authentication flow" - agent = await core_loader.select_agent(task) - print(f"Selected agent for '{task}': {agent.id}") - - -async def example_model_routing(): - """Example: Intelligent model routing""" - print("\n=== Model Routing Example ===") - - router = ModelRouter() - - # Route for deep thinking - model = await router.select_model( - task_type="deep-thinking", context_size=45000, priority="high" - ) - print(f"Deep thinking model: {model['name']} ({model['context_window']} tokens)") - - # Route for long context - model = await router.select_model( - task_type="bulk-analysis", context_size=500000, priority="medium" - ) - print(f"Long context model: {model['name']} ({model['context_window']} tokens)") - - # Route for fast iteration - model = await router.select_model( - task_type="quick-fix", context_size=5000, priority="low" - ) - print(f"Fast iteration model: {model['name']} ({model['context_window']} tokens)") - - -async def example_command_registry(): - """Example: Command discovery and execution""" - print("\n=== Command Registry Example ===") - - registry = CommandRegistry() - - # Load all commands - commands = await registry.load_commands() - print(f"Loaded {len(commands)} commands") - - # Search for specific command - git_commands = await registry.search_commands("git") - print(f"Found {len(git_commands)} git-related commands") - - # Get command details - if git_commands: - cmd = git_commands[0] - print(f"Command: {cmd['name']}") - print(f"Description: {cmd['description']}") - print(f"Category: {cmd['metadata'].get('category', 'general')}") - - -def example_quality_scoring(): - """Example: Quality scoring system""" - print("\n=== Quality Scoring Example ===") - - scorer = QualityScorer() - - # Score a code implementation - metrics = { - "correctness": 85, - "completeness": 90, - "performance": 75, - "maintainability": 80, - "security": 70, - "scalability": 85, - "testability": 95, - "usability": 80, - } - - score = scorer.calculate_score(metrics) - print(f"Overall quality score: {score['overall']}/100") - print(f"Grade: {score['grade']}") - print(f"Action: {score['action']}") - - # Show dimension breakdown - print("\nDimension scores:") - for dim, value in metrics.items(): - print(f" {dim}: {value}/100") - - -async def example_worktree_management(): - """Example: Git worktree management""" - print("\n=== Worktree Management Example ===") - - manager = WorktreeManager("/tmp/demo-repo") - - # Create worktree for feature - worktree = await manager.create_worktree( - task_id="auth-feature", branch="feature/authentication" - ) - print(f"Created worktree: {worktree['path']}") - print(f"Branch: {worktree['branch']}") - - # List active worktrees - worktrees = await manager.list_worktrees() - print(f"Active worktrees: {len(worktrees)}") - - # Validate before merge - validation = await manager.validate_worktree(worktree["id"]) - print(f"Validation status: {validation['status']}") - print(f"Ready to merge: {validation['ready']}") - - -async def example_mcp_integration(): - """Example: MCP server integration""" - print("\n=== MCP Integration Example ===") - - # Import MCP integrations - from SuperClaude.MCP import ( - RubeIntegration, - ZenIntegration, - ) - - # Zen multi-model consensus - zen = ZenIntegration() - consensus = await zen.build_consensus( - "Should we migrate to microservices?", - models=["gpt-5", "claude-opus-4.1", "gemini-2.5-pro"], - ) - print(f"Consensus reached: {consensus['agreement']}") - print(f"Confidence: {consensus['confidence']}%") - - # Optional Rube automation (dry-run by default) - os.environ.setdefault("SC_RUBE_MODE", "dry-run") - rube = RubeIntegration() - rube.initialize() - await rube.initialize_session() - dry_run = await rube.invoke("demo.tool", {"ping": "pong"}) - print(f"Rube invocation status: {dry_run['status']}") - - -async def example_coordination(): - """Example: Multi-agent coordination""" - print("\n=== Agent Coordination Example ===") - - from SuperClaude.Coordination.agent_coordinator import AgentCoordinator - - coordinator = AgentCoordinator() - - # Define complex task - task = { - "goal": "Implement secure authentication system", - "subtasks": [ - "Design auth architecture", - "Implement JWT tokens", - "Add OAuth2 support", - "Create user management", - "Write tests", - "Document API", - ], - } - - # Coordinate agents - result = await coordinator.coordinate( - task=task, - strategy="hierarchical", - agents=[ - "system-architect", - "backend-architect", - "security-engineer", - "technical-writer", - ], - ) - - print(f"Coordination strategy: {result['strategy']}") - print(f"Agents involved: {len(result['agents'])}") - print(f"Tasks completed: {result['completed']}/{result['total']}") - print(f"Time taken: {result['duration']}s") - - -async def example_performance_monitoring(): - """Example: Performance monitoring""" - print("\n=== Performance Monitoring Example ===") - - monitor = None # Monitoring removed - - # Start monitoring - monitor.start_collection() - - # Simulate some operations - await asyncio.sleep(0.1) - - # Get metrics - metrics = monitor.get_metrics() - print(f"CPU Usage: {metrics['cpu_percent']}%") - print(f"Memory Usage: {metrics['memory_percent']}%") - print(f"Token Usage: {metrics['token_count']}") - print(f"Cache Hit Rate: {metrics['cache_hit_rate']}%") - - # Check for bottlenecks - bottlenecks = monitor.detect_bottlenecks() - if bottlenecks: - print(f"Bottlenecks detected: {', '.join(bottlenecks)}") - - -async def main(): - """Run all examples""" - print("SuperClaude Framework v6.0.0-alpha Examples") - print("=" * 50) - - # Run examples - await example_agent_loading() - await example_model_routing() - await example_command_registry() - example_quality_scoring() - await example_worktree_management() - await example_mcp_integration() - await example_coordination() - await example_performance_monitoring() - - print("\n" + "=" * 50) - print("Examples completed successfully!") - - -if __name__ == "__main__": - asyncio.run(main()) diff --git a/SuperClaude/Core/BUSINESS_PANEL_EXAMPLES.md b/examples/business/BUSINESS_PANEL_EXAMPLES.md similarity index 100% rename from SuperClaude/Core/BUSINESS_PANEL_EXAMPLES.md rename to examples/business/BUSINESS_PANEL_EXAMPLES.md diff --git a/SuperClaude/Core/BUSINESS_SYMBOLS.md b/examples/business/BUSINESS_SYMBOLS.md similarity index 100% rename from SuperClaude/Core/BUSINESS_SYMBOLS.md rename to examples/business/BUSINESS_SYMBOLS.md diff --git a/pyproject.toml b/pyproject.toml index 0da901d6..96409926 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -185,7 +185,7 @@ ignore = [ "RUF005", # List concatenation style (preference) "B007", # Unused loop variable (use _ convention) "E741", # Ambiguous variable name - "E722", # Bare except (legacy code pattern) + # E722 (bare except) REMOVED - Issue #10: all bare excepts fixed "B904", # Raise from (good practice, not critical) "B028", # stacklevel in warnings (not critical) "B027", # Empty method in abstract class diff --git a/scripts/setup_zen_api_keys.sh b/scripts/setup_pal_api_keys.sh similarity index 100% rename from scripts/setup_zen_api_keys.sh rename to scripts/setup_pal_api_keys.sh diff --git a/scripts/test_zen_integration.sh b/scripts/test_pal_integration.sh similarity index 100% rename from scripts/test_zen_integration.sh rename to scripts/test_pal_integration.sh diff --git a/setup/cli/commands/clean.py b/setup/cli/commands/clean.py index 45433ab7..6c62afcc 100644 --- a/setup/cli/commands/clean.py +++ b/setup/cli/commands/clean.py @@ -212,8 +212,9 @@ def clean_worktrees(self) -> bool: capture_output=True, check=False, ) - except: + except (subprocess.SubprocessError, OSError) as e: # Fallback to direct removal if git command fails + logger.debug(f"Git worktree remove failed, using fallback: {e}") shutil.rmtree(wt, ignore_errors=True) self.cleaned_items.append( diff --git a/setup/components/mcp.py b/setup/components/mcp.py index db7b3af4..519759da 100644 --- a/setup/components/mcp.py +++ b/setup/components/mcp.py @@ -1,815 +1,138 @@ """ -MCP component for MCP server integration +MCP component - Reference documentation for native MCP tools. + +SuperClaude now uses Claude Code's native MCP tools directly instead of +custom Python wrappers. This component provides documentation and verification +that MCP tools are available. """ -import os as os_module -import shlex -import subprocess -import sys from pathlib import Path from typing import Any, Dict, List, Optional, Tuple from setup import __version__ from ..core.base import Component -from ..utils.ui import display_info, display_warning +from ..utils.ui import display_info class MCPComponent(Component): - """MCP servers integration component""" + """MCP documentation and verification component. + + MCP servers are now accessed via Claude Code's native tool system: + - mcp__rube__* for Rube/Composio tools + - mcp__pal__* for PAL tools (consensus, code review, etc.) + + No custom installation is needed - Claude Code handles MCP configuration. + """ def __init__(self, install_dir: Optional[Path] = None): - """Initialize MCP component""" + """Initialize MCP component.""" super().__init__(install_dir) - # Define MCP servers to install - self.mcp_servers = { + # Reference documentation for available MCP tools + self.mcp_tools = { "rube": { - "name": "rube", - "description": "Hosted automation hub (Composio Rube)", - "hosted": True, - "required": False, - "http_endpoint": "https://rube.app/mcp", - "requires_api_key": True, - "api_key_env": "SC_RUBE_API_KEY", - "api_key_description": "Composio OAuth token for Rube MCP", + "prefix": "mcp__rube__", + "description": "Rube MCP - automation hub for 500+ app integrations", + "tools": [ + "RUBE_SEARCH_TOOLS", + "RUBE_MULTI_EXECUTE_TOOL", + "RUBE_CREATE_PLAN", + "RUBE_MANAGE_CONNECTIONS", + "RUBE_REMOTE_WORKBENCH", + "RUBE_REMOTE_BASH_TOOL", + "RUBE_FIND_RECIPE", + "RUBE_EXECUTE_RECIPE", + ], }, - "zen": { - "name": "zen", - "description": "Local consensus helper (requires local zen-mcp-server checkout)", - "documentation_only": False, - "command_env": "ZEN_MCP_COMMAND", - "args_env": "ZEN_MCP_ARGS", - "fallback_command": "/home/tony/Desktop/zen-mcp-server/.zen_venv/bin/python", - "fallback_args": ["/home/tony/Desktop/zen-mcp-server/server.py"], + "pal": { + "prefix": "mcp__pal__", + "description": "PAL MCP - collaborative thinking and code review", + "tools": [ + "chat", + "thinkdeep", + "planner", + "consensus", + "codereview", + "precommit", + "debug", + "challenge", + "apilookup", + "listmodels", + ], }, } - self.selection_servers = ["zen", "rube"] def get_metadata(self) -> Dict[str, str]: - """Get component metadata""" + """Get component metadata.""" return { "name": "mcp", "version": __version__, - "description": "MCP server integration (Zen, Rube)", + "description": "Native MCP tools reference (Rube, PAL)", "category": "integration", } def validate_prerequisites( self, installSubPath: Optional[Path] = None ) -> Tuple[bool, List[str]]: - """Check prerequisites""" - errors = [] - - # Check if Node.js is available - try: - result = subprocess.run( - ["node", "--version"], - capture_output=True, - text=True, - timeout=10, - shell=(sys.platform == "win32"), - ) - if result.returncode != 0: - errors.append("Node.js not found - required for MCP servers") - else: - version = result.stdout.strip() - self.logger.debug(f"Found Node.js {version}") - - # Check version (require 18+) - try: - version_num = int(version.lstrip("v").split(".")[0]) - if version_num < 18: - errors.append( - f"Node.js version {version} found, but version 18+ required" - ) - except: - self.logger.warning(f"Could not parse Node.js version: {version}") - except (subprocess.TimeoutExpired, FileNotFoundError): - errors.append("Node.js not found - required for MCP servers") - - # Check if Claude CLI is available - try: - result = subprocess.run( - ["claude", "--version"], - capture_output=True, - text=True, - timeout=10, - shell=(sys.platform == "win32"), - ) - if result.returncode != 0: - errors.append( - "Claude CLI not found - required for MCP server management" - ) - else: - version = result.stdout.strip() - self.logger.debug(f"Found Claude CLI {version}") - except (subprocess.TimeoutExpired, FileNotFoundError): - errors.append("Claude CLI not found - required for MCP server management") - - # Check if npm is available - try: - result = subprocess.run( - ["npm", "--version"], - capture_output=True, - text=True, - timeout=10, - shell=(sys.platform == "win32"), - ) - if result.returncode != 0: - errors.append("npm not found - required for MCP server installation") - else: - version = result.stdout.strip() - self.logger.debug(f"Found npm {version}") - except (subprocess.TimeoutExpired, FileNotFoundError): - errors.append("npm not found - required for MCP server installation") - - return len(errors) == 0, errors + """No prerequisites needed - native MCP tools are built into Claude Code.""" + return True, [] def get_files_to_install(self) -> List[Tuple[Path, Path]]: - """Get files to install (none for MCP component)""" + """No files to install - MCP is native to Claude Code.""" return [] def get_metadata_modifications(self) -> Dict[str, Any]: - """Get metadata modifications for MCP component""" + """Get metadata modifications for MCP component.""" return { "components": { "mcp": { "version": __version__, "installed": True, - "servers_count": len(self.mcp_servers), + "native_mcp": True, } }, "mcp": { - "enabled": True, - "servers": list(self.mcp_servers.keys()), - "auto_update": False, + "mode": "native", + "tools": list(self.mcp_tools.keys()), }, } - def _install_uv_mcp_server( - self, server_info: Dict[str, Any], config: Dict[str, Any] - ) -> bool: - """Install a single MCP server using uv""" - server_name = server_info["name"] - install_command = server_info.get("install_command") - - if not install_command: - self.logger.error( - f"No install_command found for uv-based server {server_name}" - ) - return False - - try: - self.logger.info(f"Installing MCP server using uv: {server_name}") - - if self._check_mcp_server_installed(server_name): - self.logger.info(f"MCP server {server_name} already installed") - return True - - if config.get("dry_run"): - self.logger.info( - f"Would install MCP server (user scope): {install_command}" - ) - return True - - self.logger.debug(f"Running: {install_command}") - - cmd_parts = shlex.split(install_command) - result = subprocess.run( - cmd_parts, - capture_output=True, - text=True, - timeout=900, # 15 minutes - shell=(sys.platform == "win32"), - ) - - if result.returncode == 0: - self.logger.success( - f"Successfully installed MCP server (user scope): {server_name}" - ) - run_command = install_command - - self.logger.info( - f"Registering {server_name} with Claude CLI. Run command: {run_command}" - ) - - reg_result = subprocess.run( - ["claude", "mcp", "add", "-s", "user", "--", server_name] - + run_command.split(), - capture_output=True, - text=True, - timeout=120, - shell=(sys.platform == "win32"), - ) - - if reg_result.returncode == 0: - self.logger.success( - f"Successfully registered {server_name} with Claude CLI." - ) - return True - else: - error_msg = ( - reg_result.stderr.strip() - if reg_result.stderr - else "Unknown error" - ) - self.logger.error( - f"Failed to register MCP server {server_name} with Claude CLI: {error_msg}" - ) - return False - else: - error_msg = result.stderr.strip() if result.stderr else "Unknown error" - self.logger.error( - f"Failed to install MCP server {server_name} using uv: {error_msg}\n{result.stdout}" - ) - return False - - except subprocess.TimeoutExpired: - self.logger.error(f"Timeout installing MCP server {server_name} using uv") - return False - except Exception as e: - self.logger.error( - f"Error installing MCP server {server_name} using uv: {e}" - ) - return False - - def _check_mcp_server_installed(self, server_name: str) -> bool: - """Check if MCP server is already installed""" - try: - result = subprocess.run( - ["claude", "mcp", "list"], - capture_output=True, - text=True, - timeout=60, - shell=(sys.platform == "win32"), - ) - - if result.returncode != 0: - self.logger.warning(f"Could not list MCP servers: {result.stderr}") - return False - - # Parse output to check if server is installed - output = result.stdout.lower() - return server_name.lower() in output - - except (subprocess.TimeoutExpired, subprocess.SubprocessError) as e: - self.logger.warning(f"Error checking MCP server status: {e}") - return False - - def _install_mcp_server( - self, server_info: Dict[str, Any], config: Dict[str, Any] - ) -> bool: - """Install a single MCP server""" - if server_info.get("documentation_only"): - server_name = server_info.get("name", "unknown") - self.logger.info( - f"Skipping installation for documentation-only MCP server: {server_name}" - ) - return True - - if server_info.get("install_method") == "uv": - return self._install_uv_mcp_server(server_info, config) - - server_name = server_info["name"] - - # Hosted HTTP endpoint registration - if server_info.get("http_endpoint"): - endpoint = server_info["http_endpoint"] - self.logger.info(f"Registering hosted MCP server: {server_name}") - - if server_info.get("hosted") and not config.get("dry_run", False): - self._warn_hosted_server_requirements(server_info) - - if config.get("dry_run"): - self.logger.info( - f"Would register hosted MCP server: claude mcp add -s user --transport http {server_name} {endpoint}" - ) - return True - - cmd = [ - "claude", - "mcp", - "add", - "-s", - "user", - "--transport", - "http", - server_name, - endpoint, - ] - try: - result = subprocess.run( - cmd, - capture_output=True, - text=True, - timeout=120, - shell=(sys.platform == "win32"), - ) - stdout = result.stdout.strip() if result.stdout else "" - stderr = result.stderr.strip() if result.stderr else "" - - if ( - result.returncode == 0 - or "already exists" in stdout.lower() - or "already exists" in stderr.lower() - ): - self.logger.success( - f"Successfully registered hosted MCP server: {server_name}" - ) - return True - else: - error_msg = stderr or "Unknown error" - self.logger.error( - f"Failed to register hosted MCP server {server_name}: {error_msg}" - ) - return False - except subprocess.TimeoutExpired: - self.logger.error( - f"Timeout registering hosted MCP server {server_name}" - ) - return False - - # Custom command-based registration (e.g., Zen) - command_env = server_info.get("command_env") - if command_env: - command = os_module.environ.get( - command_env, server_info.get("fallback_command") - ) - if not command: - self.logger.error( - f"Missing command for {server_name}. Set {command_env} or configure fallback_command." - ) - return False - - args_env = server_info.get("args_env") - if args_env: - raw_args = os_module.environ.get(args_env) - if raw_args: - try: - custom_args = shlex.split(raw_args) - except ValueError as exc: - self.logger.error( - f"Invalid {args_env} value for {server_name}: {exc}" - ) - return False - else: - custom_args = server_info.get("fallback_args", []) - else: - custom_args = server_info.get("fallback_args", []) - - self.logger.info( - f"Registering MCP server via custom command: {server_name}" - ) - if config.get("dry_run"): - self.logger.info( - f"Would register MCP server: claude mcp add -s user -- {server_name} {command} {' '.join(custom_args)}" - ) - return True - - cmd = [ - "claude", - "mcp", - "add", - "-s", - "user", - "--", - server_name, - command, - *custom_args, - ] - try: - result = subprocess.run( - cmd, - capture_output=True, - text=True, - timeout=180, - shell=(sys.platform == "win32"), - ) - if result.returncode == 0: - self.logger.success( - f"Successfully registered MCP server: {server_name}" - ) - return True - else: - error_msg = ( - result.stderr.strip() if result.stderr else "Unknown error" - ) - self.logger.error( - f"Failed to register MCP server {server_name}: {error_msg}" - ) - return False - except subprocess.TimeoutExpired: - self.logger.error(f"Timeout registering MCP server {server_name}") - return False - - npm_package = server_info.get("npm_package") - - if not npm_package: - self.logger.error(f"No npm_package found for server {server_name}") - return False - - command = "npx" - - try: - self.logger.info(f"Installing MCP server: {server_name}") - - # Check if already installed - if self._check_mcp_server_installed(server_name): - self.logger.info(f"MCP server {server_name} already installed") - return True - - # Handle API key requirements - if "api_key_env" in server_info: - api_key_env = server_info["api_key_env"] - api_key_desc = server_info.get( - "api_key_description", f"API key for {server_name}" - ) - - if not config.get("dry_run", False): - display_info(f"MCP server '{server_name}' requires an API key") - display_info(f"Environment variable: {api_key_env}") - display_info(f"Description: {api_key_desc}") - - # Check if API key is already set - if not os_module.getenv(api_key_env): - display_warning( - f"API key {api_key_env} not found in environment" - ) - self.logger.warning( - f"Proceeding without {api_key_env} - server may not function properly" - ) - - # Install using Claude CLI - if config.get("dry_run"): - self.logger.info( - f"Would install MCP server (user scope): claude mcp add -s user {server_name} {command} -y {npm_package}" - ) - return True - - self.logger.debug( - f"Running: claude mcp add -s user {server_name} {command} -y {npm_package}" - ) - - result = subprocess.run( - [ - "claude", - "mcp", - "add", - "-s", - "user", - "--", - server_name, - command, - "-y", - npm_package, - ], - capture_output=True, - text=True, - timeout=120, # 2 minutes timeout for installation - shell=(sys.platform == "win32"), - ) - - if result.returncode == 0: - self.logger.success( - f"Successfully installed MCP server (user scope): {server_name}" - ) - return True - else: - error_msg = result.stderr.strip() if result.stderr else "Unknown error" - self.logger.error( - f"Failed to install MCP server {server_name}: {error_msg}" - ) - return False + def install(self, **kwargs) -> bool: + """Display MCP tools information. - except subprocess.TimeoutExpired: - self.logger.error(f"Timeout installing MCP server {server_name}") - return False - except Exception as e: - self.logger.error(f"Error installing MCP server {server_name}: {e}") - return False + No installation needed - just shows documentation about available tools. + """ + display_info("MCP Integration (Native Claude Code Tools)") + display_info("") + display_info("SuperClaude uses Claude Code's native MCP tools directly.") + display_info("No custom installation or configuration needed.") + display_info("") - def _warn_hosted_server_requirements(self, server_info: Dict[str, Any]) -> None: - """Emit warnings for hosted MCP servers that rely on external credentials.""" - server_name = server_info.get("name", "rube") - api_key_env = server_info.get("api_key_env") + for server, info in self.mcp_tools.items(): + display_info(f" {info['prefix']}*: {info['description']}") + for tool in info["tools"][:5]: + display_info(f" - {info['prefix']}{tool}") + if len(info["tools"]) > 5: + display_info(f" - ... and {len(info['tools']) - 5} more") + display_info("") - if api_key_env: - if not os_module.getenv(api_key_env): - display_warning( - f"Hosted MCP server '{server_name}' requires credentials. " - f"Set {api_key_env} before running automation." - ) - self.logger.warning( - f"Hosted MCP server '{server_name}' missing environment variable {api_key_env}" - ) - else: - self.logger.info( - f"Found credentials for hosted MCP server '{server_name}' in {api_key_env}" - ) - - def _uninstall_mcp_server(self, server_name: str) -> bool: - """Uninstall a single MCP server""" - try: - self.logger.info(f"Uninstalling MCP server: {server_name}") - - # Check if installed - if not self._check_mcp_server_installed(server_name): - self.logger.info(f"MCP server {server_name} not installed") - return True - - self.logger.debug( - f"Running: claude mcp remove {server_name} (auto-detect scope)" - ) - - result = subprocess.run( - ["claude", "mcp", "remove", server_name], - capture_output=True, - text=True, - timeout=60, - shell=(sys.platform == "win32"), - ) - - if result.returncode == 0: - self.logger.success( - f"Successfully uninstalled MCP server: {server_name}" - ) - return True - else: - error_msg = result.stderr.strip() if result.stderr else "Unknown error" - self.logger.error( - f"Failed to uninstall MCP server {server_name}: {error_msg}" - ) - return False - - except subprocess.TimeoutExpired: - self.logger.error(f"Timeout uninstalling MCP server {server_name}") - return False - except Exception as e: - self.logger.error(f"Error uninstalling MCP server {server_name}: {e}") - return False - - def _install(self, config: Dict[str, Any]) -> bool: - """Install MCP component""" - self.logger.info("Installing SuperClaude MCP servers...") - - # Validate prerequisites - success, errors = self.validate_prerequisites() - if not success: - for error in errors: - self.logger.error(error) - return False - - # Install each MCP server - installed_count = 0 - failed_servers = [] - - for server_name, server_info in self.mcp_servers.items(): - if self._install_mcp_server(server_info, config): - installed_count += 1 - else: - failed_servers.append(server_name) - - # Check if this is a required server - if server_info.get("required", False): - self.logger.error( - f"Required MCP server {server_name} failed to install" - ) - return False - - # Verify installation - if not config.get("dry_run", False): - self.logger.info("Verifying MCP server installation...") - try: - result = subprocess.run( - ["claude", "mcp", "list"], - capture_output=True, - text=True, - timeout=60, - shell=(sys.platform == "win32"), - ) - - if result.returncode == 0: - self.logger.debug("MCP servers list:") - for line in result.stdout.strip().split("\n"): - if line.strip(): - self.logger.debug(f" {line.strip()}") - else: - self.logger.warning("Could not verify MCP server installation") - - except Exception as e: - self.logger.warning(f"Could not verify MCP installation: {e}") - - if failed_servers: - self.logger.warning(f"Some MCP servers failed to install: {failed_servers}") - self.logger.success( - f"MCP component partially installed ({installed_count} servers)" - ) - else: - self.logger.success( - f"MCP component installed successfully ({installed_count} servers)" - ) - - return self._post_install() - - def _post_install(self) -> bool: - # Update metadata - try: - metadata_mods = self.get_metadata_modifications() - self.settings_manager.update_metadata(metadata_mods) - - # Add component registration to metadata - self.settings_manager.add_component_registration( - "mcp", - { - "version": __version__, - "category": "integration", - "servers_count": len(self.mcp_servers), - }, - ) - - self.logger.info("Updated metadata with MCP component registration") - except Exception as e: - self.logger.error(f"Failed to update metadata: {e}") - return False + display_info("Usage: Call these tools directly in prompts or commands.") + display_info("Example: 'Use mcp__rube__RUBE_SEARCH_TOOLS to find integrations'") return True def uninstall(self) -> bool: - """Uninstall MCP component""" - try: - self.logger.info("Uninstalling SuperClaude MCP servers...") - - # Uninstall each MCP server - uninstalled_count = 0 - - for server_name, server_info in self.mcp_servers.items(): - if server_info.get("documentation_only"): - self.logger.info( - f"Skipping uninstall for documentation-only MCP server: {server_name}" - ) - uninstalled_count += 1 - continue - if self._uninstall_mcp_server(server_name): - uninstalled_count += 1 - - # Update metadata to remove MCP component - try: - if self.settings_manager.is_component_installed("mcp"): - self.settings_manager.remove_component_registration("mcp") - # Also remove MCP configuration from metadata - metadata = self.settings_manager.load_metadata() - if "mcp" in metadata: - del metadata["mcp"] - self.settings_manager.save_metadata(metadata) - self.logger.info("Removed MCP component from metadata") - except Exception as e: - self.logger.warning(f"Could not update metadata: {e}") - - self.logger.success( - f"MCP component uninstalled ({uninstalled_count} servers removed)" - ) - return True - - except Exception as e: - self.logger.exception(f"Unexpected error during MCP uninstallation: {e}") - return False - - def get_dependencies(self) -> List[str]: - """Get dependencies""" - return ["core"] - - def update(self, config: Dict[str, Any]) -> bool: - """Update MCP component""" - try: - self.logger.info("Updating SuperClaude MCP servers...") - - # Check current version - current_version = self.settings_manager.get_component_version("mcp") - target_version = self.get_metadata()["version"] - - if current_version == target_version: - self.logger.info(f"MCP component already at version {target_version}") - return True - - self.logger.info( - f"Updating MCP component from {current_version} to {target_version}" - ) - - # For MCP servers, update means reinstall to get latest versions - updated_count = 0 - failed_servers = [] - - for server_name, server_info in self.mcp_servers.items(): - try: - # Uninstall old version - if self._check_mcp_server_installed(server_name): - self._uninstall_mcp_server(server_name) - - # Install new version - if self._install_mcp_server(server_info, config): - updated_count += 1 - else: - failed_servers.append(server_name) - - except Exception as e: - self.logger.error(f"Error updating MCP server {server_name}: {e}") - failed_servers.append(server_name) - - # Update metadata - try: - # Update component version in metadata - metadata = self.settings_manager.load_metadata() - if "components" in metadata and "mcp" in metadata["components"]: - metadata["components"]["mcp"]["version"] = target_version - metadata["components"]["mcp"]["servers_count"] = len( - self.mcp_servers - ) - if "mcp" in metadata: - metadata["mcp"]["servers"] = list(self.mcp_servers.keys()) - self.settings_manager.save_metadata(metadata) - except Exception as e: - self.logger.warning(f"Could not update metadata: {e}") - - if failed_servers: - self.logger.warning( - f"Some MCP servers failed to update: {failed_servers}" - ) - return False - else: - self.logger.success( - f"MCP component updated to version {target_version}" - ) - return True - - except Exception as e: - self.logger.exception(f"Unexpected error during MCP update: {e}") - return False - - def validate_installation(self) -> Tuple[bool, List[str]]: - """Validate MCP component installation""" - errors = [] - - # Check metadata registration - if not self.settings_manager.is_component_installed("mcp"): - errors.append("MCP component not registered in metadata") - return False, errors - - # Check version matches - installed_version = self.settings_manager.get_component_version("mcp") - expected_version = self.get_metadata()["version"] - if installed_version != expected_version: - errors.append( - f"Version mismatch: installed {installed_version}, expected {expected_version}" - ) - - # Check if Claude CLI is available - try: - result = subprocess.run( - ["claude", "mcp", "list"], - capture_output=True, - text=True, - timeout=60, - shell=(sys.platform == "win32"), - ) - - if result.returncode != 0: - errors.append( - "Could not communicate with Claude CLI for MCP server verification" - ) - else: - # Check if required servers are installed - output = result.stdout.lower() - for server_name, server_info in self.mcp_servers.items(): - if server_info.get("required", False): - if server_name.lower() not in output: - errors.append( - f"Required MCP server not found: {server_name}" - ) - - except Exception as e: - errors.append(f"Could not verify MCP server installation: {e}") - - return len(errors) == 0, errors - - def _get_source_dir(self): - """Get source directory for framework files""" - return None + """No uninstallation needed for native MCP tools.""" + display_info("Native MCP tools are built into Claude Code.") + display_info("No uninstallation needed.") + return True - def get_size_estimate(self) -> int: - """Get estimated installation size""" - # MCP servers are installed via npm, estimate based on typical sizes - base_size = 50 * 1024 * 1024 # ~50MB for all servers combined - return base_size + def update(self) -> bool: + """No update needed for native MCP tools.""" + display_info("Native MCP tools are updated with Claude Code.") + return True - def get_installation_summary(self) -> Dict[str, Any]: - """Get installation summary""" - return { - "component": self.get_metadata()["name"], - "version": self.get_metadata()["version"], - "servers_count": len(self.mcp_servers), - "mcp_servers": list(self.mcp_servers.keys()), - "estimated_size": self.get_size_estimate(), - "dependencies": self.get_dependencies(), - "required_tools": ["node", "npm", "claude"], - } + def validate_installation(self, installSubPath: Optional[Path] = None) -> bool: + """Native MCP tools are always available in Claude Code.""" + return True diff --git a/setup/components/mcp_docs.py b/setup/components/mcp_docs.py index f2433db8..152164da 100644 --- a/setup/components/mcp_docs.py +++ b/setup/components/mcp_docs.py @@ -1,5 +1,8 @@ """ -MCP Documentation component for SuperClaude MCP server documentation +MCP Documentation component for SuperClaude. + +Installs documentation files that describe how to use native MCP tools +(mcp__rube__*, mcp__pal__*) with SuperClaude. """ from pathlib import Path @@ -12,36 +15,33 @@ class MCPDocsComponent(Component): - """MCP documentation component - installs docs for selected MCP servers""" + """MCP documentation component - installs docs for native MCP tools.""" 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 + """Initialize MCP docs component.""" self.selected_servers: List[str] = [] - # Map server names to documentation files + # Map documentation categories to files self.server_docs_map = { - "zen": "MCP_Zen.md", + "pal": "MCP_Pal.md", "rube": "MCP_Rube.md", "linkup": "MCP_LinkUp.md", } - self.default_doc_servers = ["zen", "rube", "linkup"] + self.default_doc_servers = ["pal", "rube", "linkup"] super().__init__(install_dir, Path("")) def get_metadata(self) -> Dict[str, str]: - """Get component metadata""" + """Get component metadata.""" return { "name": "mcp_docs", "version": __version__, - "description": "MCP server documentation and usage guides", + "description": "Native MCP tools documentation and usage guides", "category": "documentation", } def set_selected_servers(self, selected_servers: List[str]) -> None: - """Set which MCP servers were selected for documentation installation""" - # Normalise and filter to the known documentation map while preserving order + """Set which documentation files to install.""" seen = set() filtered: List[str] = [] for server in selected_servers: @@ -49,28 +49,10 @@ def set_selected_servers(self, selected_servers: List[str]) -> None: if server_key in self.server_docs_map and server_key not in seen: filtered.append(server_key) seen.add(server_key) - else: - if server_key not in self.server_docs_map: - self.logger.debug( - f"Skipping unknown MCP documentation target: {server}" - ) self.selected_servers = filtered - if self.selected_servers: - self.logger.debug( - f"MCP docs will be installed for: {self.selected_servers}" - ) - else: - self.logger.debug( - "No valid MCP documentation targets resolved after filtering" - ) 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) - """ + """Return list of documentation files to install.""" source_dir = self._get_source_dir() files = [] @@ -82,204 +64,92 @@ def get_files_to_install(self) -> List[Tuple[Path, Path]]: 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 - """ + """Discover documentation files.""" 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 _install(self, config: Dict[str, Any]) -> bool: - """Install MCP documentation component""" - self.logger.info("Installing MCP server documentation...") - - # Get selected servers from config - selected_servers = config.get("selected_mcp_servers", []) - if not selected_servers: - # Fall back to default bundle when the install runs in non-interactive mode - fallback = [ - srv for srv in self.default_doc_servers if srv in self.server_docs_map - ] - self.logger.info( - f"No MCP servers selected - defaulting to documentation bundle: {', '.join(fallback)}" - ) - selected_servers = fallback - - if "rube" in selected_servers and "linkup" not in selected_servers: - selected_servers = list(selected_servers) + ["linkup"] - - self.set_selected_servers(selected_servers) - if not self.selected_servers: - self.logger.info( - "No MCP documentation targets resolved - skipping installation" - ) - return True - - # Update component files based on selection - 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 True # Not an error - just no docs to install - - # Copy documentation files - success_count = 0 - 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 - 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 - - self.logger.success( - f"MCP documentation installed successfully ({success_count} files for {len(selected_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, - } + def _get_source_dir(self) -> Optional[Path]: + """Get source directory for documentation files.""" + possible_paths = [ + Path(__file__).parent.parent.parent / "SuperClaude" / "MCP", + Path.cwd() / "SuperClaude" / "MCP", + ] + for path in possible_paths: + if path.exists(): + return path + return None + + def validate_prerequisites( + self, installSubPath: Optional[Path] = None + ) -> Tuple[bool, List[str]]: + """No prerequisites for documentation.""" + return True, [] + + def get_metadata_modifications(self) -> Dict[str, Any]: + """Get metadata modifications.""" + return { + "components": { + "mcp_docs": { + "version": __version__, + "installed": True, + "docs_installed": self.selected_servers or self.default_doc_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 + def install(self, **kwargs) -> bool: + """Install documentation files.""" + if not self.selected_servers: + self.selected_servers = self.default_doc_servers + files = self.get_files_to_install() + if not files: + self.logger.info("No documentation files to install") 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 + for source, target in files: 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") + target.parent.mkdir(parents=True, exist_ok=True) + target.write_text(source.read_text(encoding="utf-8"), encoding="utf-8") + self.logger.info(f"Installed: {target.name}") except Exception as e: - self.logger.warning(f"Could not remove mcp directory: {e}") + self.logger.error(f"Failed to install {source.name}: {e}") + return False - # 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 ["core"] - - 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 + # Update CLAUDE.md imports if service available + try: + service = CLAUDEMdService(self.install_dir) + for _, target in files: + service.add_import(f"@{target.name}") + except Exception: + pass - # Minimum size estimate - total_size = max(total_size, 10240) # At least 10KB + return True - return total_size + def uninstall(self) -> bool: + """Remove documentation files.""" + for doc_file in self.server_docs_map.values(): + target = self.install_dir / doc_file + if target.exists(): + target.unlink() + return True + + def validate_installation(self, installSubPath: Optional[Path] = None) -> bool: + """Verify documentation files exist.""" + if not self.selected_servers: + return True + for server_name in self.selected_servers: + doc_file = self.server_docs_map.get(server_name) + if doc_file: + target = self.install_dir / doc_file + if not target.exists(): + return False + return True diff --git a/setup/core/registry.py b/setup/core/registry.py index 60e824bf..8bb320c9 100644 --- a/setup/core/registry.py +++ b/setup/core/registry.py @@ -185,7 +185,9 @@ def get_component_metadata(self, component_name: str) -> Optional[Dict[str, str] if instance: try: return instance.get_metadata() - except Exception: + except Exception as e: + # Metadata retrieval failed; return None to indicate unavailable + self.logger.debug(f"Could not get metadata for {component_name}: {e}") return None return None @@ -310,7 +312,9 @@ def get_components_by_category(self, category: str) -> List[str]: metadata = instance.get_metadata() if metadata.get("category") == category: components.append(name) - except Exception: + except Exception as e: + # Skip components that fail metadata retrieval + self.logger.debug(f"Skipping component {name} due to metadata error: {e}") continue return components @@ -399,7 +403,9 @@ def get_registry_info(self) -> Dict[str, any]: if category not in categories: categories[category] = [] categories[category].append(name) - except Exception: + except Exception as e: + # Categorization failed; place in unknown category + self.logger.debug(f"Could not categorize component {name}: {e}") if "unknown" not in categories: categories["unknown"] = [] categories["unknown"].append(name) diff --git a/setup/core/validator.py b/setup/core/validator.py index df0b3f56..95acbb33 100644 --- a/setup/core/validator.py +++ b/setup/core/validator.py @@ -2,6 +2,7 @@ System validation for SuperClaude installation requirements """ +import logging import re import shutil import subprocess @@ -9,6 +10,8 @@ from pathlib import Path from typing import Any, Dict, List, Optional, Tuple +logger = logging.getLogger(__name__) + # Handle packaging import - if not available, use a simple version comparison try: from packaging import version @@ -543,7 +546,8 @@ def get_system_info(self) -> Dict[str, Any]: "free_gb": stat_result.free / (1024**3), "used_gb": (stat_result.total - stat_result.free) / (1024**3), } - except Exception: + except Exception as e: + logger.debug(f"Could not determine disk space: {e}") info["disk_space"] = {"error": "Could not determine disk space"} return info @@ -571,7 +575,9 @@ def load_installation_commands(self) -> Dict[str, Any]: config_manager = ConfigService(DATA_DIR) requirements = config_manager.load_requirements() return requirements.get("installation_commands", {}) - except Exception: + except Exception as e: + # Config loading failed; return empty commands dict + logger.debug(f"Could not load installation commands: {e}") return {} def get_installation_help( @@ -696,7 +702,9 @@ def _diagnose_path_issues(self, diagnostics: Dict[str, Any]) -> None: if result.returncode == 0: tool_found = True break - except Exception: + except Exception as e: + # Tool check failed; try next alternative + logger.debug(f"Tool check failed for {tool}: {e}") continue if not tool_found: diff --git a/setup/services/files.py b/setup/services/files.py index 46c771ea..eedb1f05 100644 --- a/setup/services/files.py +++ b/setup/services/files.py @@ -4,11 +4,14 @@ import fnmatch import hashlib +import logging import shutil import stat from pathlib import Path from typing import Any, Dict, List, Optional +logger = logging.getLogger(__name__) + class FileService: """Cross-platform file operations manager""" @@ -292,7 +295,9 @@ def get_file_hash( return hasher.hexdigest() - except Exception: + except Exception as e: + # Hash calculation failed; return None to indicate failure + logger.debug(f"Failed to calculate hash for {file_path}: {e}") return None def verify_file_integrity( @@ -330,8 +335,9 @@ def get_directory_size(self, directory: Path) -> int: for file_path in directory.rglob("*"): if file_path.is_file(): total_size += file_path.stat().st_size - except Exception: - pass # Skip files we can't access + except Exception as e: + # Skip files we can't access (permission errors, etc.) + logger.debug(f"Error calculating directory size for {directory}: {e}") return total_size @@ -357,7 +363,9 @@ def find_files( return list(directory.rglob(pattern)) else: return list(directory.glob(pattern)) - except Exception: + except Exception as e: + # File search failed; return empty list + logger.debug(f"Error finding files in {directory} with pattern {pattern}: {e}") return [] def backup_file( @@ -398,7 +406,9 @@ def get_free_space(self, path: Path) -> int: stat_result = shutil.disk_usage(path) return stat_result.free - except Exception: + except Exception as e: + # Disk usage check failed; return 0 as safe default + logger.debug(f"Could not determine free space at {path}: {e}") return 0 def cleanup_tracked_files(self) -> None: @@ -412,16 +422,18 @@ def cleanup_tracked_files(self) -> None: try: if file_path.exists(): file_path.unlink() - except Exception: - pass + except Exception as e: + # Best-effort cleanup; continue even if deletion fails + logger.debug(f"Could not remove file during cleanup {file_path}: {e}") # Remove directories (in reverse order of creation) for directory in reversed(self.created_dirs): try: if directory.exists() and not any(directory.iterdir()): directory.rmdir() - except Exception: - pass + except Exception as e: + # Best-effort cleanup; continue even if deletion fails + logger.debug(f"Could not remove directory during cleanup {directory}: {e}") self.copied_files.clear() self.created_dirs.clear() diff --git a/setup/utils/security.py b/setup/utils/security.py index d211e4e6..571746b0 100644 --- a/setup/utils/security.py +++ b/setup/utils/security.py @@ -27,12 +27,16 @@ - Comprehensive test coverage """ +import logging import os import re import urllib.parse from pathlib import Path from typing import List, Optional, Set, Tuple +# Module-level logger for security-related debug messages +_logger = logging.getLogger(__name__) + class SecurityValidator: """Security validation utilities""" @@ -866,9 +870,10 @@ def _log_security_decision(cls, action: str, message: str) -> None: else: security_logger.info(log_message) - except Exception: + except Exception as e: # Don't fail security validation if logging fails - pass + # Use module logger to capture why the security logger failed + _logger.debug(f"Security audit logging failed (non-fatal): {e}") @classmethod def create_secure_temp_dir(cls, prefix: str = "superclaude_") -> Path: @@ -916,8 +921,10 @@ def secure_delete(cls, path: Path) -> bool: f.write(secrets.token_bytes(file_size)) f.flush() os.fsync(f.fileno()) - except Exception: - pass # If overwrite fails, still try to delete + except Exception as e: + # If overwrite fails, still try to delete + # Note: file content may be recoverable without secure overwrite + _logger.debug(f"Secure overwrite failed for {path}, proceeding with deletion: {e}") path.unlink() @@ -929,5 +936,7 @@ def secure_delete(cls, path: Path) -> bool: return True - except Exception: + except Exception as e: + # Secure deletion failed; return False so caller can handle appropriately + _logger.debug(f"Secure delete failed for {path}: {e}") return False diff --git a/setup/utils/updater.py b/setup/utils/updater.py index ee4063a9..d2eefcfa 100644 --- a/setup/utils/updater.py +++ b/setup/utils/updater.py @@ -76,8 +76,10 @@ def save_check_timestamp(self): try: with open(self.CACHE_FILE) as f: data = json.load(f) - except: - pass + except (json.JSONDecodeError, OSError, IOError) as e: + # Cache file unreadable; continue with empty data dict + if self.logger: + self.logger.debug(f"Cache file unreadable, using defaults: {e}") data["last_check"] = time.time() @@ -149,8 +151,10 @@ def detect_installation_method(self) -> str: ) if "SuperClaude" in result.stdout or "superclaude" in result.stdout: return "pipx" - except: - pass + except (subprocess.SubprocessError, FileNotFoundError, OSError) as e: + # pipx not available; fall through to check pip + if self.logger: + self.logger.debug(f"pipx not available: {e}") # Check if pip installation exists try: @@ -165,8 +169,10 @@ def detect_installation_method(self) -> str: if "--user" in result.stdout or Path.home() in Path(result.stdout): return "pip-user" return "pip" - except: - pass + except (subprocess.SubprocessError, FileNotFoundError, OSError) as e: + # pip check failed; return unknown installation method + if self.logger: + self.logger.debug(f"pip check failed: {e}") return "unknown" diff --git a/tests/quality/test_quality_scorer.py b/tests/quality/test_quality_scorer.py index 5d4005d8..d36882e5 100644 --- a/tests/quality/test_quality_scorer.py +++ b/tests/quality/test_quality_scorer.py @@ -72,16 +72,16 @@ def test_primary_evaluator_short_circuits_default_metrics(): def _primary(_, __, iteration): assert iteration == 0 - metric = QualityMetric(QualityDimension.ZEN_REVIEW, 97, 1.0, "zen review") + metric = QualityMetric(QualityDimension.PAL_REVIEW, 97, 1.0, "pal review") return { "metrics": [metric], "improvements": ["tighten tests"], - "metadata": {"zen": True}, + "metadata": {"pal": True}, } scorer.set_primary_evaluator(_primary) assessment = scorer.evaluate({}, {}, iteration=0) - assert assessment.metrics[0].dimension == QualityDimension.ZEN_REVIEW + assert assessment.metrics[0].dimension == QualityDimension.PAL_REVIEW assert assessment.improvements_needed == ["tighten tests"] - assert assessment.metadata.get("zen") is True + assert assessment.metadata.get("pal") is True scorer.clear_primary_evaluator() diff --git a/tests/test_linkup.py b/tests/test_linkup.py deleted file mode 100644 index 2eee63a9..00000000 --- a/tests/test_linkup.py +++ /dev/null @@ -1,146 +0,0 @@ -"""Tests for LinkUp integration built into RubeIntegration.""" - -from typing import Any, Dict, List - -import pytest - -from SuperClaude.Commands import CommandExecutor, CommandParser, CommandRegistry -from SuperClaude.Commands.executor import CommandContext -from SuperClaude.Commands.parser import ParsedCommand -from SuperClaude.Commands.registry import CommandMetadata -from SuperClaude.MCP.rube_integration import RubeIntegration - - -class DummyRube(RubeIntegration): - """Stub RubeIntegration that records invocations without HTTP calls.""" - - def __init__(self, config: Dict[str, Any] = None) -> None: - super().__init__(config=config or {}) - self.calls: List[Dict[str, Any]] = [] - self._session_ready = True # Skip init for tests - - async def invoke(self, tool: str, payload: Dict[str, Any]) -> Dict[str, Any]: - self.calls.append({"tool": tool, "payload": payload}) - return { - "status": "success", - "tool": tool, - "payload": payload, - } - - -@pytest.mark.asyncio -async def test_linkup_search_invokes_with_expected_payload(): - """Test that linkup_search calls invoke with correct tool and payload.""" - rube = DummyRube(config={"linkup": {"default_output_type": "structured"}}) - - response = await rube.linkup_search("latest pytest news", depth="deep") - - assert response["status"] == "success" - assert rube.calls[0]["tool"] == "LINKUP_SEARCH" - assert rube.calls[0]["payload"]["query"] == "latest pytest news" - assert rube.calls[0]["payload"]["output_type"] == "structured" - assert rube.calls[0]["payload"]["depth"] == "deep" - - -@pytest.mark.asyncio -async def test_linkup_batch_search_processes_multiple_queries(): - """Test that linkup_batch_search handles multiple queries with concurrency.""" - rube = DummyRube() - - queries = ["query one", "query two", "query three"] - responses = await rube.linkup_batch_search(queries) - - assert len(responses) == 3 - assert all(r["status"] == "success" for r in responses) - assert len(rube.calls) == 3 - assert {c["payload"]["query"] for c in rube.calls} == set(queries) - - -@pytest.mark.asyncio -async def test_linkup_batch_search_returns_empty_for_empty_input(): - """Test that linkup_batch_search handles empty query list.""" - rube = DummyRube() - - responses = await rube.linkup_batch_search([]) - - assert responses == [] - assert len(rube.calls) == 0 - - -@pytest.mark.asyncio -async def test_linkup_search_rejects_empty_query(): - """Test that linkup_search raises ValueError for empty queries.""" - rube = DummyRube() - - with pytest.raises(ValueError, match="LinkUp query cannot be empty"): - await rube.linkup_search("") - - with pytest.raises(ValueError, match="LinkUp query cannot be empty"): - await rube.linkup_search(" ") - - -@pytest.mark.asyncio -async def test_execute_linkup_queries_attaches_results(): - """Test executor integration with RubeIntegration linkup methods.""" - registry = CommandRegistry() - parser = CommandParser(registry=registry) - executor = CommandExecutor(registry, parser) - - metadata = CommandMetadata( - name="test", - description="", - category="test", - complexity="standard", - mcp_servers=["rube"], - ) - parsed = ParsedCommand( - name="test", - raw_string="/sc:test --linkup --query 'pytest best practices'", - flags={"linkup": True}, - parameters={"query": "pytest best practices"}, - ) - context = CommandContext(command=parsed, metadata=metadata) - - rube = DummyRube() - executor.active_mcp_servers["rube"] = {"instance": rube, "config": {"linkup": {}}} - - result = await executor._execute_linkup_queries(context, scenario_hint="unit") - - assert result["status"] == "linkup_completed" - assert "linkup_queries" in context.results - stored = context.results["linkup_queries"][0] - assert stored["query"] == "pytest best practices" - assert stored["status"] == "completed" - assert rube.calls[0]["tool"] == "LINKUP_SEARCH" - - -@pytest.mark.asyncio -async def test_execute_linkup_queries_handles_missing_query(): - """Test executor handles missing query parameter gracefully.""" - registry = CommandRegistry() - parser = CommandParser(registry=registry) - executor = CommandExecutor(registry, parser) - - metadata = CommandMetadata( - name="test", - description="", - category="test", - complexity="standard", - mcp_servers=["rube"], - ) - parsed = ParsedCommand( - name="test", - raw_string="/sc:test --linkup", - flags={"linkup": True}, - ) - context = CommandContext(command=parsed, metadata=metadata) - - executor.active_mcp_servers["rube"] = { - "instance": DummyRube(), - "config": {"linkup": {}}, - } - - result = await executor._execute_linkup_queries(context, scenario_hint="unit") - - assert result["status"] == "linkup_failed" - assert any("LinkUp web search requires" in err for err in context.errors) diff --git a/tests/test_mcp_servers.py b/tests/test_mcp_servers.py deleted file mode 100644 index 211df828..00000000 --- a/tests/test_mcp_servers.py +++ /dev/null @@ -1,330 +0,0 @@ -""" -Smoke tests and behaviour checks for MCP integrations. -""" - -import logging -import subprocess -from pathlib import Path -from typing import Any, Dict - -import pytest - -try: - import yaml -except ModuleNotFoundError: # pragma: no cover - optional dev dependency - yaml = None # type: ignore - -import SuperClaude.MCP as mcp_module -from SuperClaude.Commands.executor import CommandContext, CommandExecutor -from SuperClaude.Commands.parser import CommandParser, ParsedCommand -from SuperClaude.Commands.registry import CommandMetadata, CommandRegistry -from SuperClaude.MCP import MCP_SERVERS, get_mcp_integration -from SuperClaude.MCP.rube_integration import RubeIntegration -from SuperClaude.Quality.quality_scorer import QualityDimension - - -def _project_root() -> Path: - return Path(__file__).parent.parent - - -def test_all_mcp_servers_can_be_instantiated(): - """Ensure every server listed in the public configuration activates.""" - if yaml is None: - pytest.skip("PyYAML not installed") - config_path = _project_root() / "SuperClaude" / "Config" / "mcp.yaml" - config_data = yaml.safe_load(config_path.read_text(encoding="utf-8")) or {} - servers = config_data.get("servers", {}) - - assert servers, "Expected MCP configuration to list servers" - - for name, cfg in servers.items(): - if not cfg.get("enabled", True): - continue - - assert name in MCP_SERVERS, f"{name} missing from MCP registry" - - server_config = cfg.get("config") - try: - instance = get_mcp_integration(name, config=server_config) - except TypeError: - instance = get_mcp_integration(name) - - assert instance is not None, f"Failed to instantiate MCP server '{name}'" - - -def test_rube_disabled_via_config(): - """Rube integration refuses to initialize when disabled in config.""" - integration = RubeIntegration(config={"enabled": False}) - assert integration.enabled is False - - with pytest.raises(RuntimeError): - integration.initialize() - - -@pytest.mark.asyncio -async def test_executor_skips_disabled_rube(monkeypatch, caplog): - """Executor logs and skips activation when network mode blocks Rube.""" - monkeypatch.setenv("SC_NETWORK_MODE", "offline") - monkeypatch.delenv("SC_RUBE_MODE", raising=False) - - registry = CommandRegistry() - parser = CommandParser(registry=registry) - executor = CommandExecutor(registry, parser) - - metadata = CommandMetadata( - name="test", - description="", - category="test", - complexity="standard", - mcp_servers=["rube"], - ) - context = CommandContext( - command=ParsedCommand(name="test", raw_string="/sc:test"), - metadata=metadata, - ) - - caplog.set_level(logging.INFO) - await executor._activate_mcp_servers(context) - - assert "Skipping MCP server 'rube'" in caplog.text - assert "rube" not in executor.active_mcp_servers - assert "rube" not in context.mcp_servers - - -@pytest.mark.asyncio -async def test_executor_activates_rube_when_enabled(monkeypatch): - """Executor activates Rube when network is allowed.""" - monkeypatch.setenv("SC_NETWORK_MODE", "online") - monkeypatch.setenv("SC_RUBE_MODE", "dry-run") - - registry = CommandRegistry() - parser = CommandParser(registry=registry) - executor = CommandExecutor(registry, parser) - - metadata = CommandMetadata( - name="test", - description="", - category="test", - complexity="standard", - mcp_servers=["rube"], - ) - context = CommandContext( - command=ParsedCommand(name="test", raw_string="/sc:test"), - metadata=metadata, - ) - - await executor._activate_mcp_servers(context) - - assert "rube" in executor.active_mcp_servers - assert "rube" in context.mcp_servers - - -def test_loop_flag_enables_zen_review(monkeypatch): - """Explicit --loop requests should automatically enable zen-review.""" - registry = CommandRegistry() - parser = CommandParser(registry=registry) - executor = CommandExecutor(registry, parser) - - metadata = CommandMetadata( - name="implement", - description="", - category="dev", - complexity="standard", - mcp_servers=[], - ) - parsed = ParsedCommand( - name="implement", raw_string="/sc:implement --loop", flags={"loop": True} - ) - context = CommandContext(command=parsed, metadata=metadata) - - executor._apply_execution_flags(context) - - assert context.zen_review_enabled is True - assert "zen" in context.metadata.mcp_servers - assert context.results.get("zen_review_enabled") is True - - -@pytest.mark.asyncio -async def test_rube_dry_run_without_network(monkeypatch): - """Rube integration falls back to dry-run when network is unavailable.""" - monkeypatch.setenv("SC_NETWORK_MODE", "offline") - monkeypatch.delenv("SC_RUBE_MODE", raising=False) - - integration = RubeIntegration() - integration.initialize() - await integration.initialize_session() - - response = await integration.invoke("tool", {"foo": "bar"}) - assert response["status"] == "dry-run" - - -@pytest.mark.asyncio -async def test_rube_live_requires_api_key(monkeypatch): - """Live mode should fail fast if API key is missing.""" - monkeypatch.setenv("SC_NETWORK_MODE", "online") - monkeypatch.setenv("SC_RUBE_MODE", "live") - monkeypatch.delenv("SC_RUBE_API_KEY", raising=False) - - monkeypatch.setattr(RubeIntegration, "_should_dry_run", lambda self: False) - integration = RubeIntegration() - integration.initialize() - - with pytest.raises(RuntimeError): - await integration.initialize_session() - - -@pytest.mark.asyncio -async def test_activate_mcp_records_warning_on_failure(monkeypatch, caplog): - monkeypatch.setenv("SC_NETWORK_MODE", "online") - - registry = CommandRegistry() - parser = CommandParser(registry=registry) - executor = CommandExecutor(registry, parser) - - metadata = CommandMetadata( - name="test", - description="", - category="test", - complexity="standard", - mcp_servers=["rube"], - ) - context = CommandContext( - command=ParsedCommand(name="test", raw_string="/sc:test"), - metadata=metadata, - ) - - caplog.set_level(logging.WARNING, logger="SuperClaude.Commands.executor") - - def _failing_get(name, config=None): - raise RuntimeError("boom") - - monkeypatch.setattr(mcp_module, "get_mcp_integration", _failing_get) - from SuperClaude.Commands import executor as executor_module - - monkeypatch.setattr(executor_module, "get_mcp_integration", _failing_get) - monkeypatch.setattr(executor_module.os.path, "exists", lambda path: False) - - await executor._activate_mcp_servers(context) - - assert "rube" not in executor.active_mcp_servers - assert any( - "Skipping MCP server 'rube'" in record.message for record in caplog.records - ) - - -@pytest.mark.asyncio -async def test_run_zen_reviews_attaches_results(monkeypatch): - """Deferred zen-review targets should populate executor results.""" - registry = CommandRegistry() - parser = CommandParser(registry=registry) - executor = CommandExecutor(registry, parser) - - metadata = CommandMetadata( - name="implement", - description="", - category="dev", - complexity="standard", - mcp_servers=["zen"], - ) - parsed = ParsedCommand( - name="implement", raw_string="/sc:implement --loop", flags={"loop": True} - ) - context = CommandContext(command=parsed, metadata=metadata) - context.zen_review_enabled = True - context.results["zen_review_targets"] = [ - {"iteration": 1, "files": ["foo.py"], "diff": "diff data"} - ] - - class _FakeZen: - async def review_code(self, diff, *, files, model, metadata): - assert diff == "diff data" - return {"score": 95, "summary": "looks good", "issues": []} - - executor.active_mcp_servers["zen"] = {"instance": _FakeZen()} - - output: Dict[str, Any] = {} - await executor._run_zen_reviews(context, output) - - assert context.results.get("zen_reviews") - assert output.get("zen_reviews") == context.results.get("zen_reviews") - - -def test_zen_primary_evaluator_overrides_metrics(tmp_path, monkeypatch): - registry = CommandRegistry() - parser = CommandParser(registry=registry) - executor = CommandExecutor(registry, parser) - executor.repo_root = tmp_path - - (tmp_path / ".git").mkdir() - subprocess.run(["git", "init"], cwd=tmp_path, check=True, stdout=subprocess.PIPE) - subprocess.run( - ["git", "config", "user.name", "Test"], - cwd=tmp_path, - check=True, - stdout=subprocess.PIPE, - ) - subprocess.run( - ["git", "config", "user.email", "test@example.com"], - cwd=tmp_path, - check=True, - stdout=subprocess.PIPE, - ) - tracked = tmp_path / "sample.txt" - tracked.write_text("initial", encoding="utf-8") - subprocess.run( - ["git", "add", "sample.txt"], cwd=tmp_path, check=True, stdout=subprocess.PIPE - ) - subprocess.run( - ["git", "commit", "-m", "init"], - cwd=tmp_path, - check=True, - stdout=subprocess.PIPE, - ) - tracked.write_text("changed", encoding="utf-8") - - context = CommandContext( - command=ParsedCommand( - name="implement", raw_string="/sc:implement --loop", flags={"loop": True} - ), - metadata=CommandMetadata( - name="implement", description="", category="dev", complexity="standard" - ), - ) - context.zen_review_enabled = True - - class _FakeZen: - async def review_code(self, diff, *, files, model, metadata): - assert "sample.txt" in diff - return { - "overall_score": 92, - "summary": "Looks solid", - "dimensions": { - "correctness": { - "score": 94, - "issues": ["Nit"], - "suggestions": ["Add test"], - }, - "testability": {"score": 88, "issues": [], "suggestions": []}, - }, - "improvements": ["Add regression tests"], - } - - executor.active_mcp_servers["zen"] = {"instance": _FakeZen()} - - monkeypatch.setattr( - executor, - "_collect_full_repo_diff", - lambda: "diff --git a/sample.txt b/sample.txt", - ) - monkeypatch.setattr(executor, "_list_changed_files", lambda: ["sample.txt"]) - - cleanup = executor._enable_primary_zen_quality(context) - assert cleanup is not None - - assessment = executor.quality_scorer.evaluate({}, {}, iteration=0) - dimensions = {metric.dimension for metric in assessment.metrics} - assert QualityDimension.CORRECTNESS in dimensions - assert assessment.improvements_needed == ["Add regression tests"] - - cleanup() - assert executor.quality_scorer.primary_evaluator is None From 0c933a7fe3711f64854c6edf113ec7354924efe4 Mon Sep 17 00:00:00 2001 From: Tony Date: Mon, 15 Dec 2025 19:50:10 -0500 Subject: [PATCH 2/4] fix: correct documentation and agent file references MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit πŸ€– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- Docs/Developer-Guide/testing-debugging.md | 6 +++--- Docs/Reference/troubleshooting.md | 2 +- Docs/User-Guide/mcp-servers.md | 6 +++--- Docs/memory-optimization-plan.md | 2 +- .../Extended/01-core-development/fullstack-developer.md | 4 ++-- .../Extended/02-language-specialists/nextjs-developer.md | 4 ++-- .../Agents/Extended/04-quality-security/qa-expert.md | 4 ++-- .../Agents/Extended/04-quality-security/test-automator.md | 4 ++-- 8 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Docs/Developer-Guide/testing-debugging.md b/Docs/Developer-Guide/testing-debugging.md index 1f4f0dc3..8f938204 100644 --- a/Docs/Developer-Guide/testing-debugging.md +++ b/Docs/Developer-Guide/testing-debugging.md @@ -106,7 +106,7 @@ directory (command artefacts, metrics JSONL, etc.). Inspecting those artefacts i the fastest way to understand failures because they reflect the actual executor output. -- When API keys are available, `--zen-review` (GPT-5) now becomes the primary - `QualityScorer` evaluator during `--loop`. Tests that stub zen responses should - assert on `QualityDimension.ZEN_REVIEW` metrics or the GPT-provided +- When API keys are available, `--pal-review` (GPT-5) now becomes the primary + `QualityScorer` evaluator during `--loop`. Tests that stub pal responses should + assert on `QualityDimension.PAL_REVIEW` metrics or the GPT-provided `improvements` list as part of their expectations. diff --git a/Docs/Reference/troubleshooting.md b/Docs/Reference/troubleshooting.md index a36633e5..448341c2 100644 --- a/Docs/Reference/troubleshooting.md +++ b/Docs/Reference/troubleshooting.md @@ -14,7 +14,7 @@ Follow these steps when commands do not behave as expected. ## MCP Problems - Run `python -m SuperClaude.MCP --list` to view enabled servers or - `python -m SuperClaude.MCP --describe zen` for details on a specific adapter. + `python -m SuperClaude.MCP --describe pal` for details on a specific adapter. - Set `SC_NETWORK_MODE=debug` to capture detailed HTTP traces. - For Rube automation, confirm `SC_RUBE_API_KEY` is present or switch to dry-run mode. diff --git a/Docs/User-Guide/mcp-servers.md b/Docs/User-Guide/mcp-servers.md index 6df1f3e5..b8f18a9c 100644 --- a/Docs/User-Guide/mcp-servers.md +++ b/Docs/User-Guide/mcp-servers.md @@ -11,13 +11,13 @@ have been removed. - The CLI honours `SC_NETWORK_MODE`. Set it to `offline` to skip network calls, `online` for full access, or `debug` to log request payloads. - Server-specific environment variables: - - `SC_ZEN_OFFLINE=1` to force Zen into offline mode (requires manual executor + - `SC_PAL_OFFLINE=1` to force PAL into offline mode (requires manual executor registration). - `SC_RUBE_API_KEY` for Rube automation calls and LinkUp web searches. -## 2. Zen Integration (Consensus) +## 2. PAL Integration (Consensus) -- The Zen adapter now uses `ModelRouterFacade.run_consensus`, which means it +- The PAL adapter now uses `ModelRouterFacade.run_consensus`, which means it requires the same provider executors as the rest of the framework. - When no executors are available the integration raises `RuntimeError` and the command fails fastβ€”there is no heuristic fallback. diff --git a/Docs/memory-optimization-plan.md b/Docs/memory-optimization-plan.md index 85f71226..c774344f 100644 --- a/Docs/memory-optimization-plan.md +++ b/Docs/memory-optimization-plan.md @@ -19,7 +19,7 @@ Each milestone will be checked off as the work lands. - **Core component** installs every Markdown file in `SuperClaude/Core/` (e.g., `RULES_*`, `OPERATIONS.md`, `AGENTS*.md`, `BUSINESS_*`). The heaviest contributors are `OPERATIONS.md`, `WORKFLOWS.md`, `AGENTS_EXTENDED.md`, and the business panel guides (>2β€―k tokens each). - **Agents component** copies all top-level persona `.md` files in `SuperClaude/Agents/`, including the extended catalogues and business assistants. - **Modes component** imports all `MODE_*.md` files even though most sessions only require `MODE_Normal.md` and `MODE_Task_Management.md`. -- **MCP docs** default to installing `MCP_Zen.md`, `MCP_Rube.md`, and `MCP_LinkUp.md`. Their footprint is modest, but they still count toward the memory bundle. +- **MCP docs** default to installing `MCP_Pal.md`, `MCP_Rube.md`, and `MCP_LinkUp.md`. Their footprint is modest, but they still count toward the memory bundle. ### Profile Definitions (current state) diff --git a/SuperClaude/Agents/Extended/01-core-development/fullstack-developer.md b/SuperClaude/Agents/Extended/01-core-development/fullstack-developer.md index e7970445..717b896b 100644 --- a/SuperClaude/Agents/Extended/01-core-development/fullstack-developer.md +++ b/SuperClaude/Agents/Extended/01-core-development/fullstack-developer.md @@ -1,7 +1,7 @@ --- name: fullstack-developer description: End-to-end feature owner with expertise across the entire stack. Delivers complete solutions from database to UI with focus on seamless integration and optimal user experience. -tools: Read, Write, MultiEdit, Bash, Docker, database, redis, postgresql, zen +tools: Read, Write, MultiEdit, Bash, Docker, database, redis, postgresql, pal --- You are a senior fullstack developer specializing in complete feature development with expertise across backend and frontend technologies. Your primary focus is delivering cohesive, end-to-end solutions that work seamlessly from database to user interface. @@ -112,7 +112,7 @@ Context acquisition query: ## MCP Tool Utilization - **database/postgresql**: Schema design, query optimization, migration management - **redis**: Cross-stack caching, session management, real-time pub/sub -- **zen**: Architecture analysis consensus, risk validation, implementation planning +- **pal**: Architecture analysis consensus, risk validation, implementation planning - **rube**: Trigger CI/CD pipelines, create tickets, and broadcast deployment status - **docker**: Full-stack containerization, development environment consistency - **UnifiedStore**: Session persistence and cross-stack decision logging diff --git a/SuperClaude/Agents/Extended/02-language-specialists/nextjs-developer.md b/SuperClaude/Agents/Extended/02-language-specialists/nextjs-developer.md index 061c0f3e..f392fe44 100644 --- a/SuperClaude/Agents/Extended/02-language-specialists/nextjs-developer.md +++ b/SuperClaude/Agents/Extended/02-language-specialists/nextjs-developer.md @@ -1,7 +1,7 @@ --- name: nextjs-developer description: Expert Next.js developer mastering Next.js 14+ with App Router and full-stack features. Specializes in server components, server actions, performance optimization, and production deployment with focus on building fast, SEO-friendly applications. -tools: next, vercel, turbo, prisma, zen, npm, typescript, tailwind +tools: next, vercel, turbo, prisma, pal, npm, typescript, tailwind --- You are a senior Next.js developer with expertise in Next.js 14+ App Router and full-stack development. Your focus spans server components, edge runtime, performance optimization, and production deployment with emphasis on creating blazing-fast applications that excel in SEO and user experience. @@ -128,7 +128,7 @@ Testing approach: - **vercel**: Deployment and hosting - **turbo**: Monorepo build system - **prisma**: Database ORM -- **zen**: Architectural reasoning, performance strategy validation +- **pal**: Architectural reasoning, performance strategy validation - **rube**: Coordinate releases, status updates, and ticket automation - **npm**: Package management - **typescript**: Type safety diff --git a/SuperClaude/Agents/Extended/04-quality-security/qa-expert.md b/SuperClaude/Agents/Extended/04-quality-security/qa-expert.md index 56bc1591..e54bdd33 100644 --- a/SuperClaude/Agents/Extended/04-quality-security/qa-expert.md +++ b/SuperClaude/Agents/Extended/04-quality-security/qa-expert.md @@ -1,7 +1,7 @@ --- name: qa-expert description: Expert QA engineer specializing in comprehensive quality assurance, test strategy, and quality metrics. Masters manual and automated testing, test planning, and quality processes with focus on delivering high-quality software through systematic testing. -tools: Read, Grep, selenium, cypress, postman, jira, testrail, browserstack, zen +tools: Read, Grep, selenium, cypress, postman, jira, testrail, browserstack, pal --- You are a senior QA expert with expertise in comprehensive quality assurance strategies, test methodologies, and quality metrics. Your focus spans test planning, execution, automation, and quality advocacy with emphasis on preventing defects, ensuring user satisfaction, and maintaining high quality standards throughout the development lifecycle. @@ -132,7 +132,7 @@ Security testing: - **jira**: Defect tracking - **testrail**: Test management - **browserstack**: Cross-browser testing -- **zen**: Risk analysis, test strategy refinement +- **pal**: Risk analysis, test strategy refinement - **rube**: Publish QA gates to external trackers and notify stakeholders - **UnifiedStore**: QA session persistence and regression insights diff --git a/SuperClaude/Agents/Extended/04-quality-security/test-automator.md b/SuperClaude/Agents/Extended/04-quality-security/test-automator.md index f24df16e..11f08c9c 100644 --- a/SuperClaude/Agents/Extended/04-quality-security/test-automator.md +++ b/SuperClaude/Agents/Extended/04-quality-security/test-automator.md @@ -1,7 +1,7 @@ --- name: test-automator description: Expert test automation engineer specializing in building robust test frameworks, CI/CD integration, and comprehensive test coverage. Masters multiple automation tools and frameworks with focus on maintainable, scalable, and efficient automated testing solutions. -tools: Read, Write, selenium, cypress, pytest, jest, appium, k6, jenkins, zen +tools: Read, Write, selenium, cypress, pytest, jest, appium, k6, jenkins, pal --- You are a senior test automation engineer with expertise in designing and implementing comprehensive test automation strategies. Your focus spans framework development, test script creation, CI/CD integration, and test maintenance with emphasis on achieving high coverage, fast feedback, and reliable test execution. @@ -133,7 +133,7 @@ Reporting and analytics: - **appium**: Mobile automation - **k6**: Performance testing - **jenkins**: CI/CD integration -- **zen**: Automation strategy design, flakiness analysis, pipeline triage +- **pal**: Automation strategy design, flakiness analysis, pipeline triage - **rube**: Update test management systems and notify stakeholders automatically - **UnifiedStore**: Persistent automation playbook and regression memory From 204d03ef25bca221d436889e4b9fc16f910969cc Mon Sep 17 00:00:00 2001 From: Tony Date: Mon, 15 Dec 2025 21:11:27 -0500 Subject: [PATCH 3/4] fix: address ruff lint errors for CI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove unused imports (threading, QualityDimension, QualityMetric) - Fix undefined logger -> self.logger in clean.py - Remove redundant IOError alias (OSError covers it) πŸ€– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .codex-os/product/analysis.md | 2 +- .codex-os/product/decisions.md | 2 +- .../product/fast-codex-execution-plan.md | 2 +- .../product/hallucination-mitigation-plan.md | 2 +- CHANGELOG.md | 2 +- README.md | 16 +++++----- SECURITY.md | 2 +- SuperClaude/Commands/brainstorm.md | 8 ++--- SuperClaude/Commands/estimate.md | 6 ++-- SuperClaude/Commands/executor.py | 3 -- SuperClaude/Commands/explain.md | 6 ++-- SuperClaude/Commands/implement.md | 8 ++--- SuperClaude/Commands/improve.md | 6 ++-- SuperClaude/Commands/workflow.md | 6 ++-- SuperClaude/Core/CLAUDE_CORE.md | 2 +- SuperClaude/Core/CLAUDE_EXTENDED.md | 4 +-- SuperClaude/Core/REFERENCE.md | 2 +- SuperClaude/Core/TOOLS.md | 4 +-- SuperClaude/Core/models.yaml | 2 +- SuperClaude/Modes/MODE_Introspection.md | 2 +- SuperClaude/Modes/MODE_Orchestration.md | 2 +- SuperClaude/Modes/MODE_Task_Management.md | 2 +- examples/business/BUSINESS_SYMBOLS.md | 2 +- scripts/setup_pal_api_keys.sh | 14 ++++---- scripts/test_pal_integration.sh | 32 +++++++++---------- setup/cli/commands/clean.py | 2 +- setup/cli/commands/uninstall.py | 2 +- setup/utils/ui.py | 2 +- setup/utils/updater.py | 2 +- 29 files changed, 72 insertions(+), 75 deletions(-) diff --git a/.codex-os/product/analysis.md b/.codex-os/product/analysis.md index 813bbcdd..51539a3c 100644 --- a/.codex-os/product/analysis.md +++ b/.codex-os/product/analysis.md @@ -23,7 +23,7 @@ repo_ref: main@d151479 # 2. Product Context - Decisions log (2025-10-17, 2025-10-25, 2025-10-26) documents MCP consolidation, UnifiedStore adoption, and stricter `requires_evidence` handling, but no mission/roadmap docs exist locally. - Intended users are Claude Code operators who need verifiable diffs with offline guarantees; success metrics would center on executed vs plan-only rates, loop iterations required, and quality scores. -- Constraints: offline mode by default, limited MCP roster (Sequential, Zen, Deepwiki), reliance on git/git tests for evidence, and absence of networked verification. +- Constraints: offline mode by default, limited MCP roster (Sequential, PAL, Deepwiki), reliance on git/git tests for evidence, and absence of networked verification. # 3. Architecture Overview - **Entry:** `/sc:` commands parsed via registry metadata (`SuperClaude/Commands/registry.py`) and executed through `CommandExecutor`. diff --git a/.codex-os/product/decisions.md b/.codex-os/product/decisions.md index a07b244b..75d1ba2a 100644 --- a/.codex-os/product/decisions.md +++ b/.codex-os/product/decisions.md @@ -12,7 +12,7 @@ ## 2025-10-25 – MCP Simplification & UnifiedStore - **Context:** Maintaining six local MCP stubs created redundant documentation, extra configuration, and brittle command dependencies. Serena’s JSON persistence also diverged from the desired SQLite-backed storage. -- **Decision:** Retire Context7, Magic, MorphLLM, Playwright, and Serena MCP integrations. Introduce the `UnifiedStore` SQLite backend with a migration helper, and update commands/modes/docs to rely on Sequential, Zen, and Deepwiki only. +- **Decision:** Retire Context7, Magic, MorphLLM, Playwright, and Serena MCP integrations. Introduce the `UnifiedStore` SQLite backend with a migration helper, and update commands/modes/docs to rely on Sequential, PAL, and Deepwiki only. - **Consequences:** MCP registry, installer components, and command playbooks now reference a minimal, actively-supported toolset. Session persistence flows through UnifiedStore, and automated tests cover the new storage path (`tests/test_worktree_state.py`). ## 2025-10-25 – Auto-Stub Hygiene & Agent Telemetry diff --git a/.codex-os/product/fast-codex-execution-plan.md b/.codex-os/product/fast-codex-execution-plan.md index 6ba10455..74e84f0d 100644 --- a/.codex-os/product/fast-codex-execution-plan.md +++ b/.codex-os/product/fast-codex-execution-plan.md @@ -3,7 +3,7 @@ ## 0. Context - Suggestion: extend `/sc:implement` with a streamlined `--fast-codex` flag that keeps the existing command executor but runs a simplified persona and validation path. - Motivation: reduce friction for routine edits while preserving guardrails such as evidence capture, MCP activation, and telemetry hooks. -- Constraints: offline-first operation, limited MCP roster (Zen + sequential stubs), `requires_evidence` guardrail must remain intact, and docs/tests must stay aligned with `.codex-os` standards. +- Constraints: offline-first operation, limited MCP roster (PAL + sequential stubs), `requires_evidence` guardrail must remain intact, and docs/tests must stay aligned with `.codex-os` standards. - Assumptions: command metadata remains YAML front matter, executor logic is centralized in `SuperClaude/Commands/executor.py`, and consensus policies live in `SuperClaude/Config/consensus_policies.yaml`. ## 1. Goals & Success Metrics diff --git a/.codex-os/product/hallucination-mitigation-plan.md b/.codex-os/product/hallucination-mitigation-plan.md index 338e1ee6..70a0a157 100644 --- a/.codex-os/product/hallucination-mitigation-plan.md +++ b/.codex-os/product/hallucination-mitigation-plan.md @@ -3,7 +3,7 @@ ## 0. Context - Source analysis: `.codex-os/product/analysis.md` (2025-10-27). - Target outcomes: Reduce plan-only completions, ensure consensus uses real ensembles, surface hallucination regressions within CI/observability, and ground agent outputs with verifiable evidence. -- Constraints: Offline-first runtime, limited MCP roster (Sequential, Zen, Deepwiki), rely on git evidence and local tests. +- Constraints: Offline-first runtime, limited MCP roster (Sequential, PAL, Deepwiki), rely on git evidence and local tests. ## 1. Goals & Success Metrics - **G1 – Reliable consensus:** All `requires_evidence` commands succeed only after multi-model agreement. diff --git a/CHANGELOG.md b/CHANGELOG.md index 07f9f575..640426e2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 setup CLI against regressions when file lists change. ### Changed -- Removed Context7, Magic, MorphLLM, Playwright, Serena, and Deepwiki MCP integrations; streamlined registry to Sequential and Zen. +- Removed Context7, Magic, MorphLLM, Playwright, Serena, and Deepwiki MCP integrations; streamlined registry to Sequential and PAL. - Updated commands, modes, docs, and agents to reference UnifiedStore and remaining MCP servers. - Simplified installer components and MCP documentation to match current server lineup. - Core and Modes installer components now persist the selected profile, expanded file manifests, diff --git a/README.md b/README.md index 57c314e4..ec1d4d99 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ SuperClaude is a sophisticated AI orchestration framework that enhances Claude C - **100+ Specialized Agents**: From backend architects to security auditors - **Behavioral Modes**: Normal, Task Management, Token Efficiency, Orchestration - **Quality Validation**: Multi-stage pipelines with syntax, security, and performance checks -- **MCP Server Integration**: Rube (web/app automation), Zen (consensus), LinkUp (web search) +- **MCP Server Integration**: Rube (web/app automation), PAL (consensus), LinkUp (web search) ```mermaid graph TB @@ -58,7 +58,7 @@ graph TB Executor --> MCP[MCP Integrations] MCP --> Rube[Rube MCP] - MCP --> Zen[Zen MCP] + MCP --> PAL[PAL MCP] Executor --> Quality[Quality Pipeline] Quality --> Validation[Validation Stages] @@ -107,7 +107,7 @@ flowchart TB API_G[Google] API_X[xAI] MCP_R[Rube MCP] - MCP_Z[Zen MCP] + MCP_P[PAL MCP] end subgraph Storage["Storage & State"] @@ -495,7 +495,7 @@ graph TB Executor[Command Executor] Executor --> RubeInt[Rube Integration] - Executor --> ZenInt[Zen Integration] + Executor --> PALInt[PAL Integration] subgraph "Rube MCP" RubeInt --> Tools[500+ App Tools] @@ -506,8 +506,8 @@ graph TB Tools --> LinkUp[LinkUp Search] end - subgraph "Zen MCP" - ZenInt --> Consensus[Consensus Engine] + subgraph "PAL MCP" + PALInt --> Consensus[Consensus Engine] Consensus --> Review[Code Review] Review --> GPT5[GPT-5 Analysis] end @@ -827,7 +827,7 @@ SuperClaude integrates with Claude Code via `CLAUDE.md` configuration files: # MCP Documentation @SuperClaude/Core/MCP_Rube.md -@SuperClaude/Core/MCP_Zen.md +@SuperClaude/Core/MCP_Pal.md ``` ### Project-Level Configuration @@ -1042,7 +1042,7 @@ SuperClaude/ β”‚ β”œβ”€β”€ MCP/ β”‚ β”‚ β”œβ”€β”€ __init__.py # Native MCP tools reference β”‚ β”‚ β”œβ”€β”€ MCP_Rube.md # Rube MCP documentation -β”‚ β”‚ β”œβ”€β”€ MCP_Zen.md # PAL MCP documentation +β”‚ β”‚ β”œβ”€β”€ MCP_Pal.md # PAL MCP documentation β”‚ β”‚ └── MCP_LinkUp.md # LinkUp search documentation β”‚ β”‚ β”‚ β”œβ”€β”€ ModelRouter/ diff --git a/SECURITY.md b/SECURITY.md index 95beae1e..ace959be 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -278,7 +278,7 @@ For organizations requiring extended security support: **Individual Server Security:** -**Zen**: Consensus orchestration with deterministic validation paths +**PAL**: Consensus orchestration with deterministic validation paths **Rube**: Automation hub with scoped OAuth delegation and dry-run defaults **Browser**: Local Chromium bridge with sandboxed automation and credential gating **UnifiedStore**: Session persistence with secure local storage and access controls diff --git a/SuperClaude/Commands/brainstorm.md b/SuperClaude/Commands/brainstorm.md index 5e6d9fdd..b8e51cad 100644 --- a/SuperClaude/Commands/brainstorm.md +++ b/SuperClaude/Commands/brainstorm.md @@ -3,7 +3,7 @@ name: brainstorm description: "Interactive requirements discovery through Socratic dialogue and systematic exploration" category: orchestration complexity: advanced -mcp-servers: [zen] +mcp-servers: [pal] personas: [architect, analyzer, frontend, backend, security, devops, project-manager] --- @@ -38,7 +38,7 @@ Key behaviors: ## MCP Integration - **Repository Knowledge Base**: Framework-specific feasibility assessment and pattern analysis -- **Zen MCP**: Consensus building for conflicting stakeholder priorities +- **PAL MCP**: Consensus building for conflicting stakeholder priorities - **UnifiedStore**: Cross-session persistence, memory management, and project context enhancement ## Tool Coordination @@ -59,14 +59,14 @@ Key behaviors: ``` /sc:brainstorm "AI-powered project management tool" --strategy systematic --depth deep # Multi-persona analysis: architect (system design), analyzer (feasibility), project-manager (requirements) -# Zen MCP provides structured exploration framework +# PAL MCP provides structured exploration framework ``` ### Agile Feature Exploration ``` /sc:brainstorm "real-time collaboration features" --strategy agile --parallel # Parallel exploration paths with frontend, backend, and security personas -# Repository pattern references with Zen MCP-driven analysis +# Repository pattern references with PAL MCP-driven analysis ``` ### Enterprise Solution Validation diff --git a/SuperClaude/Commands/estimate.md b/SuperClaude/Commands/estimate.md index 15229ac1..c602abbe 100644 --- a/SuperClaude/Commands/estimate.md +++ b/SuperClaude/Commands/estimate.md @@ -3,7 +3,7 @@ name: estimate description: "Provide development estimates for tasks, features, or projects with intelligent analysis" category: special complexity: standard -mcp-servers: [zen] +mcp-servers: [pal] personas: [architect, performance, project-manager] --- @@ -29,13 +29,13 @@ personas: [architect, performance, project-manager] Key behaviors: - Multi-persona coordination (architect, performance, project-manager) based on estimation scope -- Zen MCP integration for consensus-backed analysis and complexity assessment +- PAL MCP integration for consensus-backed analysis and complexity assessment - Repository pattern library for framework-specific benchmarks and estimation templates - Intelligent breakdown analysis with confidence intervals and risk factors ## Knowledge Inputs - **Repository Standards**: Framework-specific estimation patterns and historical benchmark data -- **Zen MCP**: Calibration of estimates through multi-perspective validation +- **PAL MCP**: Calibration of estimates through multi-perspective validation - **Persona Coordination**: Architect (design complexity), Performance (optimization effort), Project Manager (timeline) ## Tool Coordination diff --git a/SuperClaude/Commands/executor.py b/SuperClaude/Commands/executor.py index e19cf3dc..94b99698 100644 --- a/SuperClaude/Commands/executor.py +++ b/SuperClaude/Commands/executor.py @@ -18,7 +18,6 @@ import subprocess import tempfile import textwrap -import threading from dataclasses import asdict, dataclass, field from datetime import datetime from pathlib import Path @@ -40,8 +39,6 @@ from ..Modes.behavioral_manager import BehavioralMode, BehavioralModeManager from ..Quality.quality_scorer import ( QualityAssessment, - QualityDimension, - QualityMetric, QualityScorer, ) from .artifact_manager import CommandArtifactManager diff --git a/SuperClaude/Commands/explain.md b/SuperClaude/Commands/explain.md index a5573b29..96d92d7b 100644 --- a/SuperClaude/Commands/explain.md +++ b/SuperClaude/Commands/explain.md @@ -3,7 +3,7 @@ name: explain description: "Provide clear explanations of code, concepts, and system behavior with educational clarity" category: workflow complexity: standard -mcp-servers: [zen] +mcp-servers: [pal] personas: [educator, architect, security] --- @@ -30,12 +30,12 @@ personas: [educator, architect, security] Key behaviors: - Multi-persona coordination for domain expertise (educator, architect, security) - Framework-specific explanations sourced from curated repository standards -- Consensus-backed clarification via Zen MCP when multiple perspectives required +- Consensus-backed clarification via PAL MCP when multiple perspectives required - Adaptive explanation depth based on audience and complexity ## Knowledge Inputs - **Repository Standards**: Framework documentation and official pattern explanations -- **Zen MCP**: Cross-perspective validation for nuanced topics +- **PAL MCP**: Cross-perspective validation for nuanced topics - **Persona Coordination**: Educator (learning), Architect (systems), Security (practices) ## Tool Coordination diff --git a/SuperClaude/Commands/implement.md b/SuperClaude/Commands/implement.md index 43f8cbf7..a35aa51e 100644 --- a/SuperClaude/Commands/implement.md +++ b/SuperClaude/Commands/implement.md @@ -3,7 +3,7 @@ name: implement description: "Feature and code implementation with intelligent persona activation, task orchestration, and MCP integration" category: workflow complexity: standard -mcp-servers: [zen, rube] +mcp-servers: [pal, rube] personas: [architect, frontend, backend, security, qa-specialist, project-manager, devops] requires_evidence: true aliases: [task, spawn] @@ -81,11 +81,11 @@ flags: Key behaviors: - Context-based persona activation (architect, frontend, backend, security, qa) - Framework-specific implementation via curated repository guidance and playbooks -- Consensus validation on risky changes via Zen MCP +- Consensus validation on risky changes via PAL MCP - Evidence-driven reporting β€” never claim code exists without showing diff + tests ## Knowledge Inputs -- **Zen MCP**: Consensus building for architectural and security-sensitive decisions +- **PAL MCP**: Consensus building for architectural and security-sensitive decisions - **Rube MCP**: External automation (ticketing, notifications, CI hooks) aligned to task outputs - **Repository Standards**: Framework documentation, patterns, and best practices - **UnifiedStore**: Cross-session implementation state, learnings, and checkpoints @@ -136,7 +136,7 @@ When activated, enables meta-system task orchestration: ``` /sc:implement payment processing system --type feature --with-tests # Multi-persona coordination: architect, frontend, backend, security -# Zen MCP validates complex implementation steps +# PAL MCP validates complex implementation steps # Return diff + tests or explicitly note pending work ``` diff --git a/SuperClaude/Commands/improve.md b/SuperClaude/Commands/improve.md index 82e8897d..e3e07890 100644 --- a/SuperClaude/Commands/improve.md +++ b/SuperClaude/Commands/improve.md @@ -3,7 +3,7 @@ name: improve description: "Apply systematic improvements to code quality, performance, maintainability, and cleanup" category: workflow complexity: standard -mcp-servers: [zen, rube] +mcp-servers: [pal, rube] personas: [architect, performance, quality, security] aliases: [cleanup] flags: @@ -59,12 +59,12 @@ flags: Key behaviors: - Multi-persona coordination (architect, performance, quality, security) based on improvement type - Framework-specific optimization via curated repository standards and best practices -- Consensus validation via Zen MCP for complex multi-component improvements +- Consensus validation via PAL MCP for complex multi-component improvements - Safe refactoring with comprehensive validation and rollback capabilities ## Knowledge Inputs - **Repository Standards**: Framework-specific best practices and optimization patterns -- **Zen MCP**: Consensus-backed validation for high-impact changes +- **PAL MCP**: Consensus-backed validation for high-impact changes - **Rube MCP**: Coordinate code-quality follow-ups (tickets, release announcements, alerts) - **Persona Coordination**: Architect (structure), Performance (speed), Quality (maintainability), Security (safety) diff --git a/SuperClaude/Commands/workflow.md b/SuperClaude/Commands/workflow.md index e01dc904..1036c6b0 100644 --- a/SuperClaude/Commands/workflow.md +++ b/SuperClaude/Commands/workflow.md @@ -3,7 +3,7 @@ name: workflow description: "Generate structured implementation workflows from PRDs and feature requirements" category: orchestration complexity: advanced -mcp-servers: [zen, rube] +mcp-servers: [pal, rube] personas: [architect, analyzer, frontend, backend, security, devops, project-manager] --- @@ -34,7 +34,7 @@ Key behaviors: - Cross-session workflow management with comprehensive dependency tracking ## Knowledge Inputs -- **Zen MCP**: Consensus validation for high-risk implementation decisions +- **PAL MCP**: Consensus validation for high-risk implementation decisions - **Repository Standards**: Framework-specific workflow patterns and implementation best practices - **Rube MCP**: Automate backlog updates, notifications, and downstream workflow triggers - **UnifiedStore**: Cross-session workflow persistence, memory management, and project context @@ -64,7 +64,7 @@ Key behaviors: ``` /sc:workflow "user authentication system" --strategy agile --parallel # Agile workflow generation with parallel task coordination -# Repository patterns for framework workflows and Zen MCP for dependency planning +# Repository patterns for framework workflows and PAL MCP for dependency planning ``` ### Enterprise Implementation Planning diff --git a/SuperClaude/Core/CLAUDE_CORE.md b/SuperClaude/Core/CLAUDE_CORE.md index 3f950cba..41025445 100644 --- a/SuperClaude/Core/CLAUDE_CORE.md +++ b/SuperClaude/Core/CLAUDE_CORE.md @@ -30,7 +30,7 @@ The following components load automatically when their triggers are detected: - **Loads**: Relevant MODE_*.md files ### MCP Servers -- **Trigger**: MCP usage like Zen consensus, Rube automation, LinkUp web searches +- **Trigger**: MCP usage like PAL consensus, Rube automation, LinkUp web searches - **Loads**: Relevant MCP_*.md documentation ## πŸ’‘ Quick Commands diff --git a/SuperClaude/Core/CLAUDE_EXTENDED.md b/SuperClaude/Core/CLAUDE_EXTENDED.md index 38becef1..2ee50bbc 100644 --- a/SuperClaude/Core/CLAUDE_EXTENDED.md +++ b/SuperClaude/Core/CLAUDE_EXTENDED.md @@ -27,7 +27,7 @@ Loads when specific MCP servers are used: @MCP_Rube.md # Activated by: external automation workflows @MCP_LinkUp.md # Activated by: LinkUp web intelligence workflows -@MCP_Zen.md # Activated by: consensus validation, model comparisons +@MCP_Pal.md # Activated by: consensus validation, model comparisons ### Extended Rules & Operations Additional guidelines and frameworks: @@ -60,7 +60,7 @@ The framework intelligently loads components based on these triggers: ### MCP Server Usage - External automation β†’ Loads MCP_Rube.md - LinkUp web intelligence β†’ Loads MCP_LinkUp.md -- Consensus validation β†’ Loads MCP_Zen.md +- Consensus validation β†’ Loads MCP_Pal.md ### Quality & Optimization - Performance issues β†’ Loads RULES_RECOMMENDED.md diff --git a/SuperClaude/Core/REFERENCE.md b/SuperClaude/Core/REFERENCE.md index 32d869d9..8720c146 100644 --- a/SuperClaude/Core/REFERENCE.md +++ b/SuperClaude/Core/REFERENCE.md @@ -87,7 +87,7 @@ MCP Servers > Native Tools > Basic Tools | Task | Recommended Tool | |------|------------------| | Automation | Rube MCP | -| Consensus Checks | Zen MCP | +| Consensus Checks | PAL MCP | | Web Research | LinkUp via Rube | | Symbol Operations | UnifiedStore | | Documentation | Repository templates | diff --git a/SuperClaude/Core/TOOLS.md b/SuperClaude/Core/TOOLS.md index 9d2923e9..79595bad 100644 --- a/SuperClaude/Core/TOOLS.md +++ b/SuperClaude/Core/TOOLS.md @@ -65,7 +65,7 @@ Located in `Agents/Extended/` - organized by category for specialized needs: Specialized tools for enhanced capabilities. ### Core Development -- **Zen**: Multi-model consensus and validation +- **PAL**: Multi-model consensus and validation - Use for: Design reviews, risk assessments, cross-model agreement - **Rube**: External automation and system orchestration - Use for: Ticketing, notifications, CI/CD hooks @@ -114,7 +114,7 @@ Quality dimensions: Correctness (40%), Completeness (30%), Code Quality (20%), P Unknown scope? β†’ Task(general-purpose) Debugging? β†’ Task(root-cause-analyst) Need automation? β†’ Rube -Need consensus? β†’ Zen +Need consensus? β†’ PAL Bulk edits? β†’ MultiEdit Complex reasoning? β†’ Sequential Need web research? β†’ LinkUp search via Rube diff --git a/SuperClaude/Core/models.yaml b/SuperClaude/Core/models.yaml index caf75727..feaca993 100644 --- a/SuperClaude/Core/models.yaml +++ b/SuperClaude/Core/models.yaml @@ -55,7 +55,7 @@ tasks: token_budget: 50000 description: "Complex multi-step planning and strategy" - # Thinkdeep: Multi-angle analysis via Zen MCP + # Thinkdeep: Multi-angle analysis via PAL MCP thinkdeep: tier: deep preferred: gpt-5 diff --git a/SuperClaude/Modes/MODE_Introspection.md b/SuperClaude/Modes/MODE_Introspection.md index cc0a6431..3055b861 100644 --- a/SuperClaude/Modes/MODE_Introspection.md +++ b/SuperClaude/Modes/MODE_Introspection.md @@ -31,7 +31,7 @@ When GPT-5 is unavailable, Claude Opus 4.1 provides comparable reasoning depth. - **Token Efficiency**: Self-optimize for resource usage ## Common Tools -- **Zen MCP**: Structured multi-perspective self-analysis +- **PAL MCP**: Structured multi-perspective self-analysis - **UnifiedStore reflection helpers**: Built-in think_about_* routines - **Task (root-cause-analyst)**: Deep problem investigation diff --git a/SuperClaude/Modes/MODE_Orchestration.md b/SuperClaude/Modes/MODE_Orchestration.md index 23f417af..53851e2d 100644 --- a/SuperClaude/Modes/MODE_Orchestration.md +++ b/SuperClaude/Modes/MODE_Orchestration.md @@ -29,7 +29,7 @@ | Task Type | Best Tool | Alternative | |-----------|-----------|-------------| | UI components | Repository docs | Manual coding | -| Deep analysis | Zen MCP | Native reasoning | +| Deep analysis | PAL MCP | Native reasoning | | Symbol operations | UnifiedStore | Manual search | | Pattern edits | MultiEdit | Individual edits | | Documentation | Repository docs | Web search | diff --git a/SuperClaude/Modes/MODE_Task_Management.md b/SuperClaude/Modes/MODE_Task_Management.md index 628d220f..5e2fc17c 100644 --- a/SuperClaude/Modes/MODE_Task_Management.md +++ b/SuperClaude/Modes/MODE_Task_Management.md @@ -65,7 +65,7 @@ | Task Type | Primary Tool | Memory Key | |-----------|-------------|------------| -| Analysis | Zen MCP | "analysis_results" | +| Analysis | PAL MCP | "analysis_results" | | Implementation | MultiEdit | "code_changes" | | UI Components | Repository docs | "ui_components" | | Testing | External Playwright/Cypress | "test_results" | diff --git a/examples/business/BUSINESS_SYMBOLS.md b/examples/business/BUSINESS_SYMBOLS.md index f48979b6..b892729f 100644 --- a/examples/business/BUSINESS_SYMBOLS.md +++ b/examples/business/BUSINESS_SYMBOLS.md @@ -185,7 +185,7 @@ business_panel_config: expert_voice_preservation: 0.85 # Integration - mcp_zen_validation: true + mcp_pal_validation: true persona_coordination: true ``` diff --git a/scripts/setup_pal_api_keys.sh b/scripts/setup_pal_api_keys.sh index d8b561cd..e43028d6 100755 --- a/scripts/setup_pal_api_keys.sh +++ b/scripts/setup_pal_api_keys.sh @@ -1,10 +1,10 @@ #!/bin/bash -# Zen MCP API Keys Setup Script -# This script helps set up the necessary API keys for Zen MCP multi-model orchestration +# PAL MCP API Keys Setup Script +# This script helps set up the necessary API keys for PAL MCP multi-model orchestration echo "===================================" -echo " Zen MCP API Keys Setup" +echo " PAL MCP API Keys Setup" echo "===================================" echo "" @@ -127,12 +127,12 @@ echo "πŸ“ You may need to manually configure:" echo " - ~/.claude/settings.json (if using Claude settings)" echo " - ~/.config/Claude/claude_desktop_config.json (for MCP servers)" echo "" -echo "⚠️ NOTE: Zen MCP Server integration is planned for future versions" +echo "⚠️ NOTE: PAL MCP Server integration is planned for future versions" echo "" echo "These features are planned for future releases:" -echo " --zen : Enable multi-model orchestration" +echo " --pal : Enable multi-model orchestration" echo " --consensus : Get consensus from multiple models" -echo " --zen-review : Production validation with multiple models" +echo " --pal-review : Production validation with multiple models" echo " --thinkdeep : Deep multi-angle analysis" echo "" echo "Context-aware model routing:" @@ -140,5 +140,5 @@ echo " Standard ops (≀400K): GPT-5 β†’ Claude Opus 4.1 β†’ GPT-4.1" echo " Long context (>400K): Gemini-2.5-pro β†’ GPT-4.1 β†’ GPT-5" echo "" echo "Long context examples:" -echo " 'Analyze entire codebase --zen-review --extended-context'" +echo " 'Analyze entire codebase --pal-review --extended-context'" echo " 'Review all files --thinkdeep --bulk-analysis src/ docs/'" \ No newline at end of file diff --git a/scripts/test_pal_integration.sh b/scripts/test_pal_integration.sh index 6d3a9200..4f73058f 100755 --- a/scripts/test_pal_integration.sh +++ b/scripts/test_pal_integration.sh @@ -1,10 +1,10 @@ #!/bin/bash -# Zen MCP Integration Test Script -# Tests the configuration and integration of Zen MCP with SuperClaude Framework +# PAL MCP Integration Test Script +# Tests the configuration and integration of PAL MCP with SuperClaude Framework echo "=======================================" -echo " Zen MCP Integration Test" +echo " PAL MCP Integration Test" echo "=======================================" echo "" @@ -46,9 +46,9 @@ check_file_content() { echo "1. Configuration Files" echo "----------------------" test_condition "~/.claude/settings.json exists" "[ -f ~/.claude/settings.json ]" -test_condition "settings.json has zen config" "check_file_content ~/.claude/settings.json 'ZEN_MCP'" +test_condition "settings.json has pal config" "check_file_content ~/.claude/settings.json 'PAL_MCP'" test_condition "Claude Desktop config exists" "[ -f ~/.config/Claude/claude_desktop_config.json ]" -test_condition "Desktop config has zen-mcp" "check_file_content ~/.config/Claude/claude_desktop_config.json 'zen-mcp'" +test_condition "Desktop config has pal-mcp" "check_file_content ~/.config/Claude/claude_desktop_config.json 'pal-mcp'" echo "" echo "2. API Keys" @@ -85,19 +85,19 @@ else fi echo "" -echo "3. Zen MCP Server Installation" +echo "3. PAL MCP Server Installation" echo "-------------------------------" -test_condition "zen-mcp-server directory exists" "[ -d ~/.zen-mcp-server ]" -test_condition "zen server.py exists" "[ -f ~/.zen-mcp-server/server.py ]" -test_condition "zen virtual environment exists" "[ -d ~/.zen-mcp-server/.zen_venv ]" +test_condition "pal-mcp-server directory exists" "[ -d ~/.pal-mcp-server ]" +test_condition "pal server.py exists" "[ -f ~/.pal-mcp-server/server.py ]" +test_condition "pal virtual environment exists" "[ -d ~/.pal-mcp-server/.pal_venv ]" echo "" echo "4. SuperClaude Framework Integration" echo "-------------------------------------" test_condition "FLAGS.md exists" "[ -f ~/.claude/FLAGS.md ]" -test_condition "FLAGS.md contains --zen flag" "check_file_content ~/.claude/FLAGS.md 'zen'" +test_condition "FLAGS.md contains --pal flag" "check_file_content ~/.claude/FLAGS.md 'pal'" test_condition "FLAGS.md contains --consensus" "check_file_content ~/.claude/FLAGS.md 'consensus'" -test_condition "FLAGS.md contains --zen-review" "check_file_content ~/.claude/FLAGS.md 'zen-review'" +test_condition "FLAGS.md contains --pal-review" "check_file_content ~/.claude/FLAGS.md 'pal-review'" echo "" echo "5. Environment Validation" @@ -114,12 +114,12 @@ echo -e "Tests Failed: ${RED}$tests_failed${NC}" echo "" if [ $tests_failed -eq 0 ]; then - echo -e "${GREEN}πŸŽ‰ All required tests passed! Zen MCP is properly configured.${NC}" + echo -e "${GREEN}πŸŽ‰ All required tests passed! PAL MCP is properly configured.${NC}" echo "" echo "You can now use these SuperClaude features:" - echo " β€’ Multi-model orchestration with --zen" + echo " β€’ Multi-model orchestration with --pal" echo " β€’ Consensus decisions with --consensus" - echo " β€’ Production validation with --zen-review" + echo " β€’ Production validation with --pal-review" echo " β€’ Deep analysis with --thinkdeep" echo "" echo "Context-aware model routing enabled:" @@ -127,13 +127,13 @@ if [ $tests_failed -eq 0 ]; then echo " β€’ Long context (>400K): Gemini-2.5-pro β†’ GPT-4.1 β†’ GPT-5" echo "" echo "Long context examples:" - echo " β€’ --zen-review --extended-context (bulk codebase analysis)" + echo " β€’ --pal-review --extended-context (bulk codebase analysis)" echo " β€’ --thinkdeep --bulk-analysis src/ docs/ (multi-file processing)" else echo -e "${RED}⚠️ Some tests failed. Please review the configuration.${NC}" echo "" echo "To fix issues:" - echo " 1. Run: ./scripts/setup_zen_api_keys.sh" + echo " 1. Run: ./scripts/setup_pal_api_keys.sh" echo " 2. Restart Claude Desktop" echo " 3. Check the configuration files manually" fi diff --git a/setup/cli/commands/clean.py b/setup/cli/commands/clean.py index 6c62afcc..bbed6508 100644 --- a/setup/cli/commands/clean.py +++ b/setup/cli/commands/clean.py @@ -214,7 +214,7 @@ def clean_worktrees(self) -> bool: ) except (subprocess.SubprocessError, OSError) as e: # Fallback to direct removal if git command fails - logger.debug(f"Git worktree remove failed, using fallback: {e}") + self.logger.debug(f"Git worktree remove failed, using fallback: {e}") shutil.rmtree(wt, ignore_errors=True) self.cleaned_items.append( diff --git a/setup/cli/commands/uninstall.py b/setup/cli/commands/uninstall.py index 9473f768..011e58fc 100644 --- a/setup/cli/commands/uninstall.py +++ b/setup/cli/commands/uninstall.py @@ -76,7 +76,7 @@ def verify_superclaude_file(file_path: Path, component: str) -> bool: "MODE_Task_Management.md", "MODE_Token_Efficiency.md", ], - "mcp_docs": ["MCP_Zen.md", "MCP_Rube.md", "MCP_LinkUp.md"], + "mcp_docs": ["MCP_Pal.md", "MCP_Rube.md", "MCP_LinkUp.md"], } # For commands component, verify it's in the sc/ subdirectory diff --git a/setup/utils/ui.py b/setup/utils/ui.py index 78777e41..cd9d58dc 100644 --- a/setup/utils/ui.py +++ b/setup/utils/ui.py @@ -365,7 +365,7 @@ def prompt_api_key(service_name: str, env_var_name: str) -> Optional[str]: Prompt for API key with security and UX best practices Args: - service_name: Human-readable service name (e.g., "Zen", "Rube") + service_name: Human-readable service name (e.g., "PAL", "Rube") env_var_name: Environment variable name (e.g., "TWENTYFIRST_API_KEY") Returns: diff --git a/setup/utils/updater.py b/setup/utils/updater.py index d2eefcfa..46dc60d6 100644 --- a/setup/utils/updater.py +++ b/setup/utils/updater.py @@ -76,7 +76,7 @@ def save_check_timestamp(self): try: with open(self.CACHE_FILE) as f: data = json.load(f) - except (json.JSONDecodeError, OSError, IOError) as e: + except (json.JSONDecodeError, OSError) as e: # Cache file unreadable; continue with empty data dict if self.logger: self.logger.debug(f"Cache file unreadable, using defaults: {e}") From ae4dd225ba907544f957db6a88dfe7104e8b5065 Mon Sep 17 00:00:00 2001 From: Tony Date: Mon, 15 Dec 2025 21:14:54 -0500 Subject: [PATCH 4/4] style: apply ruff formatting MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit πŸ€– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- setup/cli/commands/clean.py | 4 +++- setup/core/registry.py | 4 +++- setup/services/files.py | 8 ++++++-- setup/utils/security.py | 4 +++- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/setup/cli/commands/clean.py b/setup/cli/commands/clean.py index bbed6508..a6242197 100644 --- a/setup/cli/commands/clean.py +++ b/setup/cli/commands/clean.py @@ -214,7 +214,9 @@ def clean_worktrees(self) -> bool: ) except (subprocess.SubprocessError, OSError) as e: # Fallback to direct removal if git command fails - self.logger.debug(f"Git worktree remove failed, using fallback: {e}") + self.logger.debug( + f"Git worktree remove failed, using fallback: {e}" + ) shutil.rmtree(wt, ignore_errors=True) self.cleaned_items.append( diff --git a/setup/core/registry.py b/setup/core/registry.py index 8bb320c9..5bf8aa74 100644 --- a/setup/core/registry.py +++ b/setup/core/registry.py @@ -314,7 +314,9 @@ def get_components_by_category(self, category: str) -> List[str]: components.append(name) except Exception as e: # Skip components that fail metadata retrieval - self.logger.debug(f"Skipping component {name} due to metadata error: {e}") + self.logger.debug( + f"Skipping component {name} due to metadata error: {e}" + ) continue return components diff --git a/setup/services/files.py b/setup/services/files.py index eedb1f05..370b2944 100644 --- a/setup/services/files.py +++ b/setup/services/files.py @@ -365,7 +365,9 @@ def find_files( return list(directory.glob(pattern)) except Exception as e: # File search failed; return empty list - logger.debug(f"Error finding files in {directory} with pattern {pattern}: {e}") + logger.debug( + f"Error finding files in {directory} with pattern {pattern}: {e}" + ) return [] def backup_file( @@ -433,7 +435,9 @@ def cleanup_tracked_files(self) -> None: directory.rmdir() except Exception as e: # Best-effort cleanup; continue even if deletion fails - logger.debug(f"Could not remove directory during cleanup {directory}: {e}") + logger.debug( + f"Could not remove directory during cleanup {directory}: {e}" + ) self.copied_files.clear() self.created_dirs.clear() diff --git a/setup/utils/security.py b/setup/utils/security.py index 571746b0..cf826d01 100644 --- a/setup/utils/security.py +++ b/setup/utils/security.py @@ -924,7 +924,9 @@ def secure_delete(cls, path: Path) -> bool: except Exception as e: # If overwrite fails, still try to delete # Note: file content may be recoverable without secure overwrite - _logger.debug(f"Secure overwrite failed for {path}, proceeding with deletion: {e}") + _logger.debug( + f"Secure overwrite failed for {path}, proceeding with deletion: {e}" + ) path.unlink()