diff --git a/README.md b/README.md index 02bf39b..2b123d2 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,8 @@ The ultimate development partner for Claude - a Model Context Protocol server th - **Tools Reference** - [`chat`](#1-chat---general-development-chat--collaborative-thinking) - Collaborative thinking - [`think_deeper`](#2-think_deeper---extended-reasoning-partner) - Extended reasoning - - [`review_code`](#3-review_code---professional-code-review) - Code review - - [`review_changes`](#4-review_changes---pre-commit-validation) - Pre-commit validation + - [`codereview`](#3-codereview---professional-code-review) - Code review + - [`precommit`](#4-precommit---pre-commit-validation) - Pre-commit validation - [`debug`](#5-debug---expert-debugging-assistant) - Debugging help - [`analyze`](#6-analyze---smart-file-analysis) - File analysis @@ -42,8 +42,8 @@ The ultimate development partner for Claude - a Model Context Protocol server th Claude is brilliant, but sometimes you need: - **A senior developer partner** to validate and extend ideas ([`chat`](#1-chat---general-development-chat--collaborative-thinking)) - **A second opinion** on complex architectural decisions - augment Claude's extended thinking with Gemini's perspective ([`think_deeper`](#2-think_deeper---extended-reasoning-partner)) -- **Professional code reviews** with actionable feedback across entire repositories ([`review_code`](#3-review_code---professional-code-review)) -- **Pre-commit validation** with deep analysis that finds edge cases, validates your implementation against original requirements, and catches subtle bugs Claude might miss ([`review_changes`](#4-review_changes---pre-commit-validation)) +- **Professional code reviews** with actionable feedback across entire repositories ([`codereview`](#3-codereview---professional-code-review)) +- **Pre-commit validation** with deep analysis that finds edge cases, validates your implementation against original requirements, and catches subtle bugs Claude might miss ([`precommit`](#4-precommit---pre-commit-validation)) - **Expert debugging** for tricky issues with full system context ([`debug`](#5-debug---expert-debugging-assistant)) - **Massive context window** (1M tokens) - Gemini 2.5 Pro can analyze entire codebases, read hundreds of files at once, and provide comprehensive insights ([`analyze`](#6-analyze---smart-file-analysis)) - **Deep code analysis** across massive codebases that exceed Claude's context limits ([`analyze`](#6-analyze---smart-file-analysis)) @@ -562,7 +562,7 @@ about event ordering and failure scenarios. Then integrate gemini's insights and **Triggers:** think deeper, ultrathink, extend my analysis, validate my approach -### 3. `review_code` - Professional Code Review +### 3. `codereview` - Professional Code Review **Comprehensive code analysis with prioritized feedback** **Thinking Mode:** Default is `medium` (8,192 tokens). Use `high` for security-critical code (worth the extra tokens) or `low` for quick style checks (saves ~6k tokens). @@ -607,7 +607,7 @@ make any necessary adjustments and show me the final secure implementation." **Triggers:** review code, check for issues, find bugs, security check -### 4. `review_changes` - Pre-Commit Validation +### 4. `precommit` - Pre-Commit Validation **Comprehensive review of staged/unstaged git changes across multiple repositories** **Thinking Mode:** Default is `medium` (8,192 tokens). Use `high` or `max` for critical releases when thorough validation justifies the token cost. diff --git a/prompts/__init__.py b/prompts/__init__.py index 970b456..d02ab89 100644 --- a/prompts/__init__.py +++ b/prompts/__init__.py @@ -5,14 +5,14 @@ System prompts for Gemini tools from .tool_prompts import ( ANALYZE_PROMPT, CHAT_PROMPT, + CODEREVIEW_PROMPT, DEBUG_ISSUE_PROMPT, - REVIEW_CODE_PROMPT, THINK_DEEPER_PROMPT, ) __all__ = [ "THINK_DEEPER_PROMPT", - "REVIEW_CODE_PROMPT", + "CODEREVIEW_PROMPT", "DEBUG_ISSUE_PROMPT", "ANALYZE_PROMPT", "CHAT_PROMPT", diff --git a/prompts/tool_prompts.py b/prompts/tool_prompts.py index dfcd4ee..d5c5b6f 100644 --- a/prompts/tool_prompts.py +++ b/prompts/tool_prompts.py @@ -38,7 +38,7 @@ Be direct and technical. Assume Claude and the user are experienced developers w deep, nuanced analysis rather than basic explanations. Your goal is to be the perfect development partner that extends Claude's capabilities.""" -REVIEW_CODE_PROMPT = """You are an expert code reviewer with deep knowledge of software engineering best practices. +CODEREVIEW_PROMPT = """You are an expert code reviewer with deep knowledge of software engineering best practices. Your expertise spans security, performance, maintainability, and architectural patterns. IMPORTANT: If you need additional context (e.g., related files, configuration, dependencies) to provide @@ -171,7 +171,7 @@ the ideal thinking partner who helps explore ideas deeply, validates approaches, insights that might be missed in solo analysis. Think step by step through complex problems and don't hesitate to explore tangential but relevant considerations.""" -REVIEW_CHANGES_PROMPT = """You are an expert code change analyst specializing in pre-commit review of git diffs. +PRECOMMIT_PROMPT = """You are an expert code change analyst specializing in pre-commit review of git diffs. Your role is to act as a seasoned senior developer performing a final review before code is committed. IMPORTANT: If you need additional context (e.g., related files not in the diff, test files, configuration) diff --git a/server.py b/server.py index 2153439..49bd057 100644 --- a/server.py +++ b/server.py @@ -40,9 +40,9 @@ from config import ( from tools import ( AnalyzeTool, ChatTool, + CodeReviewTool, DebugIssueTool, - ReviewChanges, - ReviewCodeTool, + Precommit, ThinkDeeperTool, ) @@ -60,11 +60,11 @@ server: Server = Server("gemini-server") # Tools are instantiated once and reused across requests (stateless design) TOOLS = { "think_deeper": ThinkDeeperTool(), # Extended reasoning for complex problems - "review_code": ReviewCodeTool(), # Comprehensive code review and quality analysis + "codereview": CodeReviewTool(), # Comprehensive code review and quality analysis "debug": DebugIssueTool(), # Root cause analysis and debugging assistance "analyze": AnalyzeTool(), # General-purpose file and code analysis "chat": ChatTool(), # Interactive development chat and brainstorming - "review_changes": ReviewChanges(), # Pre-commit review of git changes + "precommit": Precommit(), # Pre-commit validation of git changes } diff --git a/tests/test_docker_path_integration.py b/tests/test_docker_path_integration.py index 3deacd5..5d61c0d 100644 --- a/tests/test_docker_path_integration.py +++ b/tests/test_docker_path_integration.py @@ -156,10 +156,10 @@ def test_review_changes_docker_path_translation(): utils.file_utils.CONTAINER_WORKSPACE = container_workspace # Import after reloading to get updated environment - from tools.review_changes import ReviewChanges + from tools.precommit import Precommit # Create tool instance - tool = ReviewChanges() + tool = Precommit() # Test path translation in prepare_prompt request = tool.get_request_model()( @@ -209,10 +209,10 @@ def test_review_changes_docker_path_error(): utils.file_utils.CONTAINER_WORKSPACE = container_workspace # Import after reloading to get updated environment - from tools.review_changes import ReviewChanges + from tools.precommit import Precommit # Create tool instance - tool = ReviewChanges() + tool = Precommit() # Test path translation with an inaccessible path request = tool.get_request_model()( diff --git a/tests/test_large_prompt_handling.py b/tests/test_large_prompt_handling.py index c314041..ff1bca9 100644 --- a/tests/test_large_prompt_handling.py +++ b/tests/test_large_prompt_handling.py @@ -18,9 +18,9 @@ from mcp.types import TextContent from config import MCP_PROMPT_SIZE_LIMIT from tools.analyze import AnalyzeTool from tools.chat import ChatTool +from tools.codereview import CodeReviewTool from tools.debug import DebugIssueTool -from tools.review_changes import ReviewChanges -from tools.review_code import ReviewCodeTool +from tools.precommit import Precommit from tools.think_deeper import ThinkDeeperTool @@ -141,9 +141,9 @@ class TestLargePromptHandling: assert output["status"] == "requires_file_prompt" @pytest.mark.asyncio - async def test_review_code_large_focus(self, large_prompt): - """Test that review_code tool detects large focus_on field.""" - tool = ReviewCodeTool() + async def test_codereview_large_focus(self, large_prompt): + """Test that codereview tool detects large focus_on field.""" + tool = CodeReviewTool() result = await tool.execute( { "files": ["/some/file.py"], @@ -159,7 +159,7 @@ class TestLargePromptHandling: @pytest.mark.asyncio async def test_review_changes_large_original_request(self, large_prompt): """Test that review_changes tool detects large original_request.""" - tool = ReviewChanges() + tool = Precommit() result = await tool.execute({"path": "/some/path", "original_request": large_prompt}) assert len(result) == 1 diff --git a/tests/test_review_changes.py b/tests/test_precommit.py similarity index 81% rename from tests/test_review_changes.py rename to tests/test_precommit.py index e692756..4eff5f4 100644 --- a/tests/test_review_changes.py +++ b/tests/test_precommit.py @@ -1,5 +1,5 @@ """ -Tests for the review_changes tool +Tests for the precommit tool """ import json @@ -7,22 +7,22 @@ from unittest.mock import Mock, patch import pytest -from tools.review_changes import ReviewChanges, ReviewChangesRequest +from tools.precommit import Precommit, PrecommitRequest -class TestReviewChangesTool: - """Test the review_changes tool""" +class TestPrecommitTool: + """Test the precommit tool""" @pytest.fixture def tool(self): """Create tool instance""" - return ReviewChanges() + return Precommit() def test_tool_metadata(self, tool): """Test tool metadata""" - assert tool.get_name() == "review_changes" - assert "REVIEW PENDING GIT CHANGES" in tool.get_description() - assert "pre-commit review" in tool.get_description() + assert tool.get_name() == "precommit" + assert "PRECOMMIT VALIDATION" in tool.get_description() + assert "pre-commit" in tool.get_description() # Check schema schema = tool.get_input_schema() @@ -34,7 +34,7 @@ class TestReviewChangesTool: def test_request_model_defaults(self): """Test request model default values""" - request = ReviewChangesRequest(path="/some/absolute/path") + request = PrecommitRequest(path="/some/absolute/path") assert request.path == "/some/absolute/path" assert request.original_request is None assert request.compare_to is None @@ -56,21 +56,21 @@ class TestReviewChangesTool: assert "./relative/path" in response["content"] @pytest.mark.asyncio - @patch("tools.review_changes.find_git_repositories") + @patch("tools.precommit.find_git_repositories") async def test_no_repositories_found(self, mock_find_repos, tool): """Test when no git repositories are found""" mock_find_repos.return_value = [] - request = ReviewChangesRequest(path="/absolute/path/no-git") + request = PrecommitRequest(path="/absolute/path/no-git") result = await tool.prepare_prompt(request) assert result == "No git repositories found in the specified path." mock_find_repos.assert_called_once_with("/absolute/path/no-git", 5) @pytest.mark.asyncio - @patch("tools.review_changes.find_git_repositories") - @patch("tools.review_changes.get_git_status") - @patch("tools.review_changes.run_git_command") + @patch("tools.precommit.find_git_repositories") + @patch("tools.precommit.get_git_status") + @patch("tools.precommit.run_git_command") async def test_no_changes_found(self, mock_run_git, mock_status, mock_find_repos, tool): """Test when repositories have no changes""" mock_find_repos.return_value = ["/test/repo"] @@ -89,15 +89,15 @@ class TestReviewChangesTool: (True, ""), # unstaged files (empty) ] - request = ReviewChangesRequest(path="/absolute/repo/path") + request = PrecommitRequest(path="/absolute/repo/path") result = await tool.prepare_prompt(request) assert result == "No pending changes found in any of the git repositories." @pytest.mark.asyncio - @patch("tools.review_changes.find_git_repositories") - @patch("tools.review_changes.get_git_status") - @patch("tools.review_changes.run_git_command") + @patch("tools.precommit.find_git_repositories") + @patch("tools.precommit.get_git_status") + @patch("tools.precommit.run_git_command") async def test_staged_changes_review( self, mock_run_git, @@ -126,7 +126,7 @@ class TestReviewChangesTool: (True, ""), # unstaged files (empty) ] - request = ReviewChangesRequest( + request = PrecommitRequest( path="/absolute/repo/path", original_request="Add hello message", review_type="security", @@ -143,9 +143,9 @@ class TestReviewChangesTool: assert "## Git Diffs" in result @pytest.mark.asyncio - @patch("tools.review_changes.find_git_repositories") - @patch("tools.review_changes.get_git_status") - @patch("tools.review_changes.run_git_command") + @patch("tools.precommit.find_git_repositories") + @patch("tools.precommit.get_git_status") + @patch("tools.precommit.run_git_command") async def test_compare_to_invalid_ref(self, mock_run_git, mock_status, mock_find_repos, tool): """Test comparing to an invalid git ref""" mock_find_repos.return_value = ["/test/repo"] @@ -156,14 +156,14 @@ class TestReviewChangesTool: (False, "fatal: not a valid ref"), # rev-parse fails ] - request = ReviewChangesRequest(path="/absolute/repo/path", compare_to="invalid-branch") + request = PrecommitRequest(path="/absolute/repo/path", compare_to="invalid-branch") result = await tool.prepare_prompt(request) # When all repos have errors and no changes, we get this message assert "No pending changes found in any of the git repositories." in result @pytest.mark.asyncio - @patch("tools.review_changes.ReviewChanges.execute") + @patch("tools.precommit.Precommit.execute") async def test_execute_integration(self, mock_execute, tool): """Test execute method integration""" # Mock the execute to return a standardized response @@ -183,9 +183,9 @@ class TestReviewChangesTool: assert tool.get_default_temperature() == TEMPERATURE_ANALYTICAL @pytest.mark.asyncio - @patch("tools.review_changes.find_git_repositories") - @patch("tools.review_changes.get_git_status") - @patch("tools.review_changes.run_git_command") + @patch("tools.precommit.find_git_repositories") + @patch("tools.precommit.get_git_status") + @patch("tools.precommit.run_git_command") async def test_mixed_staged_unstaged_changes( self, mock_run_git, @@ -211,7 +211,7 @@ class TestReviewChangesTool: (True, "diff --git a/file2.py..."), # diff for file2.py ] - request = ReviewChangesRequest( + request = PrecommitRequest( path="/absolute/repo/path", focus_on="error handling", severity_filter="high", @@ -225,10 +225,10 @@ class TestReviewChangesTool: assert "Reviewing: staged and unstaged changes" in result @pytest.mark.asyncio - @patch("tools.review_changes.find_git_repositories") - @patch("tools.review_changes.get_git_status") - @patch("tools.review_changes.run_git_command") - @patch("tools.review_changes.read_files") + @patch("tools.precommit.find_git_repositories") + @patch("tools.precommit.get_git_status") + @patch("tools.precommit.run_git_command") + @patch("tools.precommit.read_files") async def test_files_parameter_with_context( self, mock_read_files, @@ -257,7 +257,7 @@ class TestReviewChangesTool: # Mock read_files mock_read_files.return_value = "=== FILE: config.py ===\nCONFIG_VALUE = 42\n=== END FILE ===" - request = ReviewChangesRequest( + request = PrecommitRequest( path="/absolute/repo/path", files=["/absolute/repo/path/config.py"], ) @@ -271,9 +271,9 @@ class TestReviewChangesTool: assert "CONFIG_VALUE = 42" in result @pytest.mark.asyncio - @patch("tools.review_changes.find_git_repositories") - @patch("tools.review_changes.get_git_status") - @patch("tools.review_changes.run_git_command") + @patch("tools.precommit.find_git_repositories") + @patch("tools.precommit.get_git_status") + @patch("tools.precommit.run_git_command") async def test_files_request_instruction( self, mock_run_git, @@ -298,7 +298,7 @@ class TestReviewChangesTool: ] # Request without files - request = ReviewChangesRequest(path="/absolute/repo/path") + request = PrecommitRequest(path="/absolute/repo/path") result = await tool.prepare_prompt(request) # Should include instruction for requesting files @@ -306,7 +306,7 @@ class TestReviewChangesTool: assert "standardized JSON response format" in result # Request with files - should not include instruction - request_with_files = ReviewChangesRequest(path="/absolute/repo/path", files=["/some/file.py"]) + request_with_files = PrecommitRequest(path="/absolute/repo/path", files=["/some/file.py"]) # Need to reset mocks for second call mock_find_repos.return_value = ["/test/repo"] @@ -317,7 +317,7 @@ class TestReviewChangesTool: ] # Mock read_files to return empty (file not found) - with patch("tools.review_changes.read_files") as mock_read: + with patch("tools.precommit.read_files") as mock_read: mock_read.return_value = "" result_with_files = await tool.prepare_prompt(request_with_files) diff --git a/tests/test_prompt_regression.py b/tests/test_prompt_regression.py index ad63ca9..db66877 100644 --- a/tests/test_prompt_regression.py +++ b/tests/test_prompt_regression.py @@ -12,9 +12,9 @@ import pytest from tools.analyze import AnalyzeTool from tools.chat import ChatTool +from tools.codereview import CodeReviewTool from tools.debug import DebugIssueTool -from tools.review_changes import ReviewChanges -from tools.review_code import ReviewCodeTool +from tools.precommit import Precommit from tools.think_deeper import ThinkDeeperTool @@ -105,9 +105,9 @@ class TestPromptRegression: assert "deeper analysis" in output["content"] @pytest.mark.asyncio - async def test_review_code_normal_review(self, mock_model_response): - """Test review_code tool with normal inputs.""" - tool = ReviewCodeTool() + async def test_codereview_normal_review(self, mock_model_response): + """Test codereview tool with normal inputs.""" + tool = CodeReviewTool() with patch.object(tool, "create_model") as mock_create_model: mock_model = MagicMock() @@ -117,7 +117,7 @@ class TestPromptRegression: mock_create_model.return_value = mock_model # Mock file reading - with patch("tools.review_code.read_files") as mock_read_files: + with patch("tools.codereview.read_files") as mock_read_files: mock_read_files.return_value = "def main(): pass" result = await tool.execute( @@ -137,7 +137,7 @@ class TestPromptRegression: @pytest.mark.asyncio async def test_review_changes_normal_request(self, mock_model_response): """Test review_changes tool with normal original_request.""" - tool = ReviewChanges() + tool = Precommit() with patch.object(tool, "create_model") as mock_create_model: mock_model = MagicMock() @@ -147,8 +147,8 @@ class TestPromptRegression: mock_create_model.return_value = mock_model # Mock git operations - with patch("tools.review_changes.find_git_repositories") as mock_find_repos: - with patch("tools.review_changes.get_git_status") as mock_git_status: + with patch("tools.precommit.find_git_repositories") as mock_find_repos: + with patch("tools.precommit.get_git_status") as mock_git_status: mock_find_repos.return_value = ["/path/to/repo"] mock_git_status.return_value = { "modified": ["file.py"], diff --git a/tests/test_server.py b/tests/test_server.py index 3a78088..06cc743 100644 --- a/tests/test_server.py +++ b/tests/test_server.py @@ -20,11 +20,11 @@ class TestServerTools: # Check all core tools are present assert "think_deeper" in tool_names - assert "review_code" in tool_names + assert "codereview" in tool_names assert "debug" in tool_names assert "analyze" in tool_names assert "chat" in tool_names - assert "review_changes" in tool_names + assert "precommit" in tool_names assert "get_version" in tool_names # Should have exactly 7 tools diff --git a/tests/test_thinking_modes.py b/tests/test_thinking_modes.py index f1d2883..d786624 100644 --- a/tests/test_thinking_modes.py +++ b/tests/test_thinking_modes.py @@ -7,8 +7,8 @@ from unittest.mock import Mock, patch import pytest from tools.analyze import AnalyzeTool +from tools.codereview import CodeReviewTool from tools.debug import DebugIssueTool -from tools.review_code import ReviewCodeTool from tools.think_deeper import ThinkDeeperTool @@ -27,7 +27,7 @@ class TestThinkingModes: tools = [ (ThinkDeeperTool(), "high"), (AnalyzeTool(), "medium"), - (ReviewCodeTool(), "medium"), + (CodeReviewTool(), "medium"), (DebugIssueTool(), "medium"), ] @@ -77,7 +77,7 @@ class TestThinkingModes: ) mock_create_model.return_value = mock_model - tool = ReviewCodeTool() + tool = CodeReviewTool() result = await tool.execute( { "files": ["/absolute/path/test.py"], diff --git a/tests/test_tools.py b/tests/test_tools.py index e8a1b97..ba7f16a 100644 --- a/tests/test_tools.py +++ b/tests/test_tools.py @@ -7,7 +7,7 @@ from unittest.mock import Mock, patch import pytest -from tools import AnalyzeTool, ChatTool, DebugIssueTool, ReviewCodeTool, ThinkDeeperTool +from tools import AnalyzeTool, ChatTool, CodeReviewTool, DebugIssueTool, ThinkDeeperTool class TestThinkDeeperTool: @@ -54,16 +54,16 @@ class TestThinkDeeperTool: assert "Extended analysis" in output["content"] -class TestReviewCodeTool: - """Test the review_code tool""" +class TestCodeReviewTool: + """Test the codereview tool""" @pytest.fixture def tool(self): - return ReviewCodeTool() + return CodeReviewTool() def test_tool_metadata(self, tool): """Test tool metadata""" - assert tool.get_name() == "review_code" + assert tool.get_name() == "codereview" assert "PROFESSIONAL CODE REVIEW" in tool.get_description() assert tool.get_default_temperature() == 0.2 @@ -214,9 +214,9 @@ class TestAbsolutePathValidation: assert "./relative/path.py" in response["content"] @pytest.mark.asyncio - async def test_review_code_tool_relative_path_rejected(self): - """Test that review_code tool rejects relative paths""" - tool = ReviewCodeTool() + async def test_codereview_tool_relative_path_rejected(self): + """Test that codereview tool rejects relative paths""" + tool = CodeReviewTool() result = await tool.execute( { "files": ["../parent/file.py"], diff --git a/tools/__init__.py b/tools/__init__.py index 98f2de5..df21aed 100644 --- a/tools/__init__.py +++ b/tools/__init__.py @@ -4,16 +4,16 @@ Tool implementations for Gemini MCP Server from .analyze import AnalyzeTool from .chat import ChatTool +from .codereview import CodeReviewTool from .debug import DebugIssueTool -from .review_changes import ReviewChanges -from .review_code import ReviewCodeTool +from .precommit import Precommit from .think_deeper import ThinkDeeperTool __all__ = [ "ThinkDeeperTool", - "ReviewCodeTool", + "CodeReviewTool", "DebugIssueTool", "AnalyzeTool", "ChatTool", - "ReviewChanges", + "Precommit", ] diff --git a/tools/analyze.py b/tools/analyze.py index 040a8c1..adc2aa1 100644 --- a/tools/analyze.py +++ b/tools/analyze.py @@ -37,8 +37,7 @@ class AnalyzeTool(BaseTool): return ( "ANALYZE FILES & CODE - General-purpose analysis for understanding code. " "Supports both individual files and entire directories. " - "Use this for examining files, understanding architecture, or investigating specific aspects. " - "Triggers: 'analyze these files', 'examine this code', 'understand this'. " + "Use this when you need to analyze files, examine code, or understand specific aspects of a codebase. " "Perfect for: codebase exploration, dependency analysis, pattern detection. " "Always uses file paths for clean terminal output." ) diff --git a/tools/chat.py b/tools/chat.py index 6427a92..b0766d6 100644 --- a/tools/chat.py +++ b/tools/chat.py @@ -40,8 +40,8 @@ class ChatTool(BaseTool): "Perfect for: bouncing ideas during your own analysis, getting second opinions on your plans, " "collaborative brainstorming, validating your checklists and approaches, exploring alternatives. " "Also great for: explanations, comparisons, general development questions. " - "Triggers: 'ask gemini', 'brainstorm with gemini', 'get gemini's opinion', 'discuss with gemini', " - "'share my thinking with gemini', 'explain', 'what is', 'how do I'." + "Use this when you want to ask Gemini questions, brainstorm ideas, get opinions, discuss topics, " + "share your thinking, or need explanations about concepts and approaches." ) def get_input_schema(self) -> dict[str, Any]: diff --git a/tools/review_code.py b/tools/codereview.py similarity index 95% rename from tools/review_code.py rename to tools/codereview.py index e02393f..4f99807 100644 --- a/tools/review_code.py +++ b/tools/codereview.py @@ -20,14 +20,14 @@ from mcp.types import TextContent from pydantic import Field from config import TEMPERATURE_ANALYTICAL -from prompts import REVIEW_CODE_PROMPT +from prompts import CODEREVIEW_PROMPT from utils import read_files from .base import BaseTool, ToolRequest from .models import ToolOutput -class ReviewCodeRequest(ToolRequest): +class CodeReviewRequest(ToolRequest): """ Request model for the code review tool. @@ -53,7 +53,7 @@ class ReviewCodeRequest(ToolRequest): ) -class ReviewCodeTool(BaseTool): +class CodeReviewTool(BaseTool): """ Professional code review tool implementation. @@ -63,14 +63,13 @@ class ReviewCodeTool(BaseTool): """ def get_name(self) -> str: - return "review_code" + return "codereview" def get_description(self) -> str: return ( "PROFESSIONAL CODE REVIEW - Comprehensive analysis for bugs, security, and quality. " "Supports both individual files and entire directories/projects. " - "Use this for thorough code review with actionable feedback. " - "Triggers: 'review this code', 'check for issues', 'find bugs', 'security audit'. " + "Use this when you need to review code, check for issues, find bugs, or perform security audits. " "I'll identify issues by severity (Critical→High→Medium→Low) with specific fixes. " "Supports focused reviews: security, performance, or quick checks. " "Choose thinking_mode based on review scope: 'low' for small code snippets, " @@ -132,13 +131,13 @@ class ReviewCodeTool(BaseTool): } def get_system_prompt(self) -> str: - return REVIEW_CODE_PROMPT + return CODEREVIEW_PROMPT def get_default_temperature(self) -> float: return TEMPERATURE_ANALYTICAL def get_request_model(self): - return ReviewCodeRequest + return CodeReviewRequest async def execute(self, arguments: dict[str, Any]) -> list[TextContent]: """Override execute to check focus_on size before processing""" @@ -155,7 +154,7 @@ class ReviewCodeTool(BaseTool): # Continue with normal execution return await super().execute(arguments) - async def prepare_prompt(self, request: ReviewCodeRequest) -> str: + async def prepare_prompt(self, request: CodeReviewRequest) -> str: """ Prepare the code review prompt with customized instructions. @@ -239,7 +238,7 @@ Please provide a code review aligned with the user's context and expectations, f return full_prompt - def format_response(self, response: str, request: ReviewCodeRequest) -> str: + def format_response(self, response: str, request: CodeReviewRequest) -> str: """ Format the review response with appropriate headers. diff --git a/tools/debug.py b/tools/debug.py index 93ccdbb..7d54984 100644 --- a/tools/debug.py +++ b/tools/debug.py @@ -37,8 +37,8 @@ class DebugIssueTool(BaseTool): def get_description(self) -> str: return ( "DEBUG & ROOT CAUSE ANALYSIS - Expert debugging for complex issues with 1M token capacity. " - "Use this when you need help tracking down bugs or understanding errors. " - "Triggers: 'debug this', 'why is this failing', 'root cause', 'trace error', 'diagnose issue'. " + "Use this when you need to debug code, find out why something is failing, identify root causes, " + "trace errors, or diagnose issues. " "IMPORTANT: Share diagnostic files liberally! Gemini can handle up to 1M tokens, so include: " "large log files, full stack traces, memory dumps, diagnostic outputs, multiple related files, " "entire modules, test results, configuration files - anything that might help debug the issue. " diff --git a/tools/review_changes.py b/tools/precommit.py similarity index 94% rename from tools/review_changes.py rename to tools/precommit.py index 1aa89a4..6b3ebba 100644 --- a/tools/review_changes.py +++ b/tools/precommit.py @@ -1,5 +1,5 @@ """ -Tool for reviewing pending git changes across multiple repositories. +Tool for pre-commit validation of git changes across multiple repositories. """ import os @@ -9,7 +9,7 @@ from mcp.types import TextContent from pydantic import Field from config import MAX_CONTEXT_TOKENS -from prompts.tool_prompts import REVIEW_CHANGES_PROMPT +from prompts.tool_prompts import PRECOMMIT_PROMPT from utils.file_utils import read_files, translate_file_paths, translate_path_for_environment from utils.git_utils import find_git_repositories, get_git_status, run_git_command from utils.token_utils import estimate_tokens @@ -18,8 +18,8 @@ from .base import BaseTool, ToolRequest from .models import ToolOutput -class ReviewChangesRequest(ToolRequest): - """Request model for review_changes tool""" +class PrecommitRequest(ToolRequest): + """Request model for precommit tool""" path: str = Field( ..., @@ -71,21 +71,21 @@ class ReviewChangesRequest(ToolRequest): ) -class ReviewChanges(BaseTool): - """Tool for reviewing git changes across multiple repositories.""" +class Precommit(BaseTool): + """Tool for pre-commit validation of git changes across multiple repositories.""" def get_name(self) -> str: - return "review_changes" + return "precommit" def get_description(self) -> str: return ( - "REVIEW PENDING GIT CHANGES BEFORE COMMITTING - ALWAYS use this tool before creating any git commit! " + "PRECOMMIT VALIDATION FOR GIT CHANGES - ALWAYS use this tool before creating any git commit! " "Comprehensive pre-commit validation that catches bugs, security issues, incomplete implementations, " "and ensures changes match the original requirements. Searches all git repositories recursively and " "provides deep analysis of staged/unstaged changes. Essential for code quality and preventing bugs. " - "Triggers: 'before commit', 'review changes', 'check my changes', 'validate changes', 'pre-commit review', " - "'about to commit', 'ready to commit'. Claude should proactively suggest using this tool whenever " - "the user mentions committing or when changes are complete. " + "Use this before committing, when reviewing changes, checking your changes, validating changes, " + "or when you're about to commit or ready to commit. Claude should proactively suggest using this tool " + "whenever the user mentions committing or when changes are complete. " "Choose thinking_mode based on changeset size: 'low' for small focused changes, " "'medium' for standard commits (default), 'high' for large feature branches or complex refactoring, " "'max' for critical releases or when reviewing extensive changes across multiple systems." @@ -103,10 +103,10 @@ class ReviewChanges(BaseTool): return schema def get_system_prompt(self) -> str: - return REVIEW_CHANGES_PROMPT + return PRECOMMIT_PROMPT def get_request_model(self): - return ReviewChangesRequest + return PrecommitRequest def get_default_temperature(self) -> float: """Use analytical temperature for code review.""" @@ -129,7 +129,7 @@ class ReviewChanges(BaseTool): # Continue with normal execution return await super().execute(arguments) - async def prepare_prompt(self, request: ReviewChangesRequest) -> str: + async def prepare_prompt(self, request: PrecommitRequest) -> str: """Prepare the prompt with git diff information.""" # Check for prompt.txt in files prompt_content, updated_files = self.handle_prompt_file(request.files) @@ -409,6 +409,6 @@ class ReviewChanges(BaseTool): return full_prompt - def format_response(self, response: str, request: ReviewChangesRequest) -> str: + def format_response(self, response: str, request: PrecommitRequest) -> str: """Format the response with commit guidance""" return f"{response}\n\n---\n\n**Commit Status:** If no critical issues found, changes are ready for commit. Otherwise, address issues first and re-run review. Check with user before proceeding with any commit." diff --git a/tools/think_deeper.py b/tools/think_deeper.py index de29ce6..9978a52 100644 --- a/tools/think_deeper.py +++ b/tools/think_deeper.py @@ -39,9 +39,8 @@ class ThinkDeeperTool(BaseTool): def get_description(self) -> str: return ( "EXTENDED THINKING & REASONING - Your deep thinking partner for complex problems. " - "Use this when you need to extend your analysis, explore alternatives, or validate approaches. " + "Use this when you need to think deeper about a problem, extend your analysis, explore alternatives, or validate approaches. " "Perfect for: architecture decisions, complex bugs, performance challenges, security analysis. " - "Triggers: 'think deeper', 'ultrathink', 'extend my analysis', 'explore alternatives'. " "I'll challenge assumptions, find edge cases, and provide alternative solutions. " "IMPORTANT: Choose the appropriate thinking_mode based on task complexity - " "'low' for quick analysis, 'medium' for standard problems, 'high' for complex issues (default), "