From aab65f016d2275649225a4c85d3956e15ee3f5fc Mon Sep 17 00:00:00 2001 From: "Edward Z. Yang" Date: Tue, 25 Mar 2025 19:43:52 +0800 Subject: [PATCH] Update [ghstack-poisoned] --- codemcp/tools/chmod.py | 4 +--- codemcp/tools/edit_file.py | 14 ++++++++++---- codemcp/tools/git_blame.py | 2 -- codemcp/tools/git_diff.py | 2 -- codemcp/tools/git_log.py | 2 -- codemcp/tools/git_show.py | 2 -- codemcp/tools/glob.py | 6 +----- codemcp/tools/grep.py | 8 ++------ codemcp/tools/init_project.py | 7 ++++--- codemcp/tools/rm.py | 2 +- codemcp/tools/run_command.py | 7 +++++-- codemcp/tools/write_file.py | 2 +- 12 files changed, 25 insertions(+), 33 deletions(-) diff --git a/codemcp/tools/chmod.py b/codemcp/tools/chmod.py index 77d04a28..9b78e0f9 100644 --- a/codemcp/tools/chmod.py +++ b/codemcp/tools/chmod.py @@ -31,7 +31,6 @@ async def chmod( path: str, mode: Literal["a+x", "a-x"], chat_id: str | None = None, - signal=None, ) -> dict[str, Any]: """Change file permissions using chmod. @@ -39,7 +38,6 @@ async def chmod( path: The absolute path to the file to modify mode: The chmod mode to apply, only "a+x" and "a-x" are supported chat_id: The unique ID of the current chat session - signal: Optional abort signal to terminate the subprocess Returns: A dictionary with chmod output @@ -104,7 +102,7 @@ async def chmod( success, commit_message = await commit_changes( directory, description, - chat_id, + chat_id if chat_id is not None else "", ) if not success: diff --git a/codemcp/tools/edit_file.py b/codemcp/tools/edit_file.py index a4dac425..90aed0ed 100644 --- a/codemcp/tools/edit_file.py +++ b/codemcp/tools/edit_file.py @@ -7,6 +7,7 @@ import os import re from difflib import SequenceMatcher +from typing import Any from ..common import get_edit_snippet from ..file_utils import ( @@ -53,7 +54,7 @@ async def apply_edit( file_path: str, old_string: str, new_string: str, -) -> tuple[list[dict], str]: +) -> tuple[list[dict[str, Any]], str]: """Apply an edit to a file using robust matching strategies. Args: @@ -322,7 +323,7 @@ def try_dotdotdots(whole: str, part: str, replace: str) -> str | None: part_pieces = [part_pieces[i] for i in range(0, len(part_pieces), 2)] replace_pieces = [replace_pieces[i] for i in range(0, len(replace_pieces), 2)] - pairs = zip(part_pieces, replace_pieces, strict=False) + pairs = list(zip(part_pieces, replace_pieces)) for part, replace in pairs: if not part and not replace: continue @@ -415,8 +416,13 @@ def find_similar_lines( search_lines = search_lines.splitlines() content_lines = content_lines.splitlines() + # Handle empty input cases + if not search_lines or not content_lines: + return "" + best_ratio = 0 - best_match = None + best_match = [] # Initialize with empty list to avoid None checks + best_match_i = 0 # Initialize to avoid unbound variable errors for i in range(len(content_lines) - len(search_lines) + 1): chunk = content_lines[i : i + len(search_lines)] @@ -730,7 +736,7 @@ async def edit_file_content( ) # Apply the edit with advanced matching if needed - patch, updated_file = await apply_edit(full_file_path, old_string, new_string) + _, updated_file = await apply_edit(full_file_path, old_string, new_string) # If no changes were made (which should never happen at this point), # log a warning but continue diff --git a/codemcp/tools/git_blame.py b/codemcp/tools/git_blame.py index c434d72c..07ad1d4e 100644 --- a/codemcp/tools/git_blame.py +++ b/codemcp/tools/git_blame.py @@ -34,7 +34,6 @@ async def git_blame( arguments: str | None = None, path: str | None = None, chat_id: str | None = None, - signal=None, ) -> dict[str, Any]: """Execute git blame with the provided arguments. @@ -42,7 +41,6 @@ async def git_blame( arguments: Optional arguments to pass to git blame as a string path: The directory to execute the command in (must be in a git repository) chat_id: The unique ID of the current chat session - signal: Optional abort signal to terminate the subprocess Returns: A dictionary with git blame output diff --git a/codemcp/tools/git_diff.py b/codemcp/tools/git_diff.py index 8182bae1..b91a45db 100644 --- a/codemcp/tools/git_diff.py +++ b/codemcp/tools/git_diff.py @@ -35,7 +35,6 @@ async def git_diff( arguments: str | None = None, path: str | None = None, chat_id: str | None = None, - signal=None, ) -> dict[str, Any]: """Execute git diff with the provided arguments. @@ -43,7 +42,6 @@ async def git_diff( arguments: Optional arguments to pass to git diff as a string path: The directory to execute the command in (must be in a git repository) chat_id: The unique ID of the current chat session - signal: Optional abort signal to terminate the subprocess Returns: A dictionary with git diff output diff --git a/codemcp/tools/git_log.py b/codemcp/tools/git_log.py index 58426c29..a1370913 100644 --- a/codemcp/tools/git_log.py +++ b/codemcp/tools/git_log.py @@ -34,7 +34,6 @@ async def git_log( arguments: str | None = None, path: str | None = None, chat_id: str | None = None, - signal=None, ) -> dict[str, Any]: """Execute git log with the provided arguments. @@ -42,7 +41,6 @@ async def git_log( arguments: Optional arguments to pass to git log as a string path: The directory to execute the command in (must be in a git repository) chat_id: The unique ID of the current chat session - signal: Optional abort signal to terminate the subprocess Returns: A dictionary with git log output diff --git a/codemcp/tools/git_show.py b/codemcp/tools/git_show.py index b3e8843c..2d68592a 100644 --- a/codemcp/tools/git_show.py +++ b/codemcp/tools/git_show.py @@ -36,7 +36,6 @@ async def git_show( arguments: str | None = None, path: str | None = None, chat_id: str | None = None, - signal=None, ) -> dict[str, Any]: """Execute git show with the provided arguments. @@ -44,7 +43,6 @@ async def git_show( arguments: Optional arguments to pass to git show as a string path: The directory to execute the command in (must be in a git repository) chat_id: The unique ID of the current chat session - signal: Optional abort signal to terminate the subprocess Returns: A dictionary with git show output diff --git a/codemcp/tools/glob.py b/codemcp/tools/glob.py index 705e4e6b..a70a900b 100644 --- a/codemcp/tools/glob.py +++ b/codemcp/tools/glob.py @@ -22,7 +22,6 @@ async def glob( pattern: str, path: str, options: Optional[Dict[str, Any]] = None, - signal=None, ) -> Dict[str, Any]: """Find files matching a glob pattern. @@ -30,7 +29,6 @@ async def glob( pattern: The glob pattern to match files against path: The directory to search in options: Optional parameters for pagination (limit, offset) - signal: Optional abort signal to terminate the operation Returns: A dictionary with matched files and metadata @@ -148,7 +146,6 @@ async def glob_files( limit: int = MAX_RESULTS, offset: int = 0, chat_id: str | None = None, - signal=None, ) -> Dict[str, Any]: """Search for files matching a glob pattern. @@ -158,7 +155,6 @@ async def glob_files( limit: Maximum number of results to return offset: Number of results to skip (for pagination) chat_id: The unique ID of the current chat session - signal: Optional abort signal to terminate the operation Returns: A dictionary with matched files @@ -174,7 +170,7 @@ async def glob_files( } # Execute glob - result = await glob(pattern, path, options, signal) + result = await glob(pattern, path, options) # Get matching files files = result.get("files", []) diff --git a/codemcp/tools/grep.py b/codemcp/tools/grep.py index 3cd4f43d..b4110b96 100644 --- a/codemcp/tools/grep.py +++ b/codemcp/tools/grep.py @@ -36,7 +36,6 @@ async def git_grep( pattern: str, path: str | None = None, include: str | None = None, - signal=None, ) -> list[str]: """Execute git grep to search for pattern in files. @@ -44,7 +43,6 @@ async def git_grep( pattern: The regular expression pattern to search for path: The directory or file to search in (must be in a git repository) include: Optional file pattern to filter the search - signal: Optional abort signal to terminate the subprocess Returns: A list of file paths with matches @@ -119,7 +117,7 @@ async def git_grep( raise subprocess.SubprocessError(f"git grep failed: {result.stderr}") # Process results - split by newline and filter empty lines - matches = [line.strip() for line in result.stdout.split("\n") if line.strip()] + matches = [line.strip() for line in result.stdout.split() if line.strip()] # Convert to absolute paths matches = [os.path.join(absolute_path, match) for match in matches] @@ -160,7 +158,6 @@ async def grep_files( path: str | None = None, include: str | None = None, chat_id: str | None = None, - signal=None, ) -> dict[str, Any]: """Search for a pattern in files within a directory or in a specific file. @@ -169,7 +166,6 @@ async def grep_files( path: The directory or file to search in (must be in a git repository) include: Optional file pattern to filter the search chat_id: The unique ID of the current chat session - signal: Optional abort signal to terminate the subprocess Returns: A dictionary with matched files @@ -177,7 +173,7 @@ async def grep_files( """ # Execute git grep asynchronously - matches = await git_grep(pattern, path, include, signal) + matches = await git_grep(pattern, path, include) # Sort matches # Use asyncio for getting file stats diff --git a/codemcp/tools/init_project.py b/codemcp/tools/init_project.py index 94db8441..20a97549 100644 --- a/codemcp/tools/init_project.py +++ b/codemcp/tools/init_project.py @@ -4,6 +4,7 @@ import logging import os import re +from typing import Dict, Optional import tomli @@ -37,7 +38,7 @@ def _slugify(text: str) -> str: return text[:50] -def _generate_command_docs(command_docs: dict) -> str: +def _generate_command_docs(command_docs: Dict[str, str]) -> str: """Generate documentation for commands from the command_docs dictionary. Args: @@ -56,7 +57,7 @@ def _generate_command_docs(command_docs: dict) -> str: return "\n\nCommand documentation:" + "".join(docs) -async def _generate_chat_id(directory: str, description: str = None) -> str: +async def _generate_chat_id(directory: str, description: Optional[str] = None) -> str: """Generate a unique chat ID based on a counter stored in the git repository. Args: @@ -198,7 +199,7 @@ async def init_project( # Create a commit reference instead of creating a regular commit # This will not advance HEAD but store the commit in refs/codemcp/ - message, commit_hash = await create_commit_reference( + _, _ = await create_commit_reference( full_dir_path, chat_id=chat_id, commit_msg=commit_msg, diff --git a/codemcp/tools/rm.py b/codemcp/tools/rm.py index 04cdb169..0c04ff4c 100644 --- a/codemcp/tools/rm.py +++ b/codemcp/tools/rm.py @@ -16,7 +16,7 @@ async def rm_file( path: str, description: str, - chat_id: str = None, + chat_id: str = "", ) -> str: """Remove a file using git rm. diff --git a/codemcp/tools/run_command.py b/codemcp/tools/run_command.py index 4a1961d0..23b52b86 100644 --- a/codemcp/tools/run_command.py +++ b/codemcp/tools/run_command.py @@ -14,7 +14,7 @@ async def run_command( project_dir: str, command: str, arguments: Optional[str] = None, - chat_id: str = None, + chat_id: str = "", ) -> str: """Run a command that is configured in codemcp.toml. @@ -38,6 +38,9 @@ async def run_command( parsed_args = shlex.split(arguments) command_list.extend(parsed_args) + # Don't pass None to run_code_command + actual_command = command_list if command_list is not None else [] + return await run_code_command( - project_dir, command, command_list, f"Auto-commit {command} changes", chat_id + project_dir, command, actual_command, f"Auto-commit {command} changes", chat_id ) diff --git a/codemcp/tools/write_file.py b/codemcp/tools/write_file.py index ea1e679f..5ac56fea 100644 --- a/codemcp/tools/write_file.py +++ b/codemcp/tools/write_file.py @@ -16,7 +16,7 @@ async def write_file_content( - file_path: str, content: str, description: str = "", chat_id: str = None + file_path: str, content: str, description: str = "", chat_id: str = "" ) -> str: """Write content to a file.