Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions codemcp/git_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,30 @@ def append_metadata_to_message(message: str, metadata: dict[str, str]) -> str:
Returns:
The updated commit message with trailers added
"""
# Ensure there's a blank line before trailers if the message doesn't end with one
processed_message = message
if message and not message.endswith("\n\n"):
if message.endswith("\n"):
processed_message = message + "\n"
else:
processed_message = message + "\n\n"

return subprocess.check_output(
result = subprocess.check_output(
[
"git",
"interpret-trailers",
*[f"--trailer={k}: {v}" for k, v in metadata.items()],
],
input=message.encode("utf-8"),
input=processed_message.encode("utf-8"),
).decode("utf-8")

# git interpret-trailers adds a trailing newline that we need to handle properly
# Remove one trailing newline if there are multiple
if result.endswith("\n\n"):
result = result[:-1]

return result


def update_commit_message_with_description(
current_commit_message: str,
Expand Down
24 changes: 12 additions & 12 deletions codemcp/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@
from starlette.routing import Mount

from .mcp import mcp
from .tools.chmod import chmod
from .tools.edit_file import edit_file
from .tools.glob import glob
from .tools.grep import grep
from .tools.init_project import init_project
from .tools.ls import ls
from .tools.mv import mv
from .tools.read_file import read_file
from .tools.rm import rm
from .tools.run_command import run_command
from .tools.think import think
from .tools.write_file import write_file
from .tools.chmod import chmod # noqa: F401
from .tools.edit_file import edit_file # noqa: F401
from .tools.glob import glob # noqa: F401
from .tools.grep import grep # noqa: F401
from .tools.init_project import init_project # noqa: F401
from .tools.ls import ls # noqa: F401
from .tools.mv import mv # noqa: F401
from .tools.read_file import read_file # noqa: F401
from .tools.rm import rm # noqa: F401
from .tools.run_command import run_command # noqa: F401
from .tools.think import think # noqa: F401
from .tools.write_file import write_file # noqa: F401


def get_files_respecting_gitignore(dir_path: Path, pattern: str = "**/*") -> List[Path]:
Expand Down
8 changes: 6 additions & 2 deletions codemcp/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,9 @@ async def call_tool_assert_error(
"Session cannot be None when in_process=False"
)
# Convert subtool name to lowercase snake case (e.g., ReadFile -> read_file)
subtool_snake_case = ''.join(['_' + c.lower() if c.isupper() else c for c in subtool]).lstrip('_')
subtool_snake_case = "".join(
["_" + c.lower() if c.isupper() else c for c in subtool]
).lstrip("_")
# Call the subtool directly instead of calling the codemcp tool
result = await session.call_tool(subtool_snake_case, kwargs) # type: ignore
self.assertTrue(result.isError, result)
Expand Down Expand Up @@ -405,7 +407,9 @@ async def call_tool_assert_success(
else:
assert session is not None, "Session cannot be None when in_process=False"
# Convert subtool name to lowercase snake case (e.g., ReadFile -> read_file)
subtool_snake_case = ''.join(['_' + c.lower() if c.isupper() else c for c in subtool]).lstrip('_')
subtool_snake_case = "".join(
["_" + c.lower() if c.isupper() else c for c in subtool]
).lstrip("_")
# Call the subtool directly instead of calling the codemcp tool
result = await session.call_tool(subtool_snake_case, kwargs) # type: ignore
self.assertFalse(result.isError, result)
Expand Down
12 changes: 11 additions & 1 deletion codemcp/tools/init_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import tomli

from ..common import MAX_LINE_LENGTH, MAX_LINES_TO_READ, normalize_file_path
from ..common import normalize_file_path
from ..git import get_repository_root, is_git_repository
from ..mcp import mcp

Expand Down Expand Up @@ -295,6 +295,16 @@ async def init_project(
This project uses Git commit hashes to track changes across conversations. After each operation that modifies files, the current Git commit hash will be reported. The commit hash represents the current state of the repository.
"""

# Add command information if commands are available
if command_help:
system_prompt += (
f"\n- The run_command tool accepts these commands: {command_help}"
)

# Add command documentation if available
if command_docs:
system_prompt += _generate_command_docs(command_docs)

# Combine system prompt, global prompt
combined_prompt = system_prompt
if project_prompt:
Expand Down
2 changes: 1 addition & 1 deletion codemcp/tools/run_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@

from ..code_command import get_command_from_config, run_code_command
from ..common import normalize_file_path
from .commit_utils import append_commit_hash
from ..mcp import mcp
from .commit_utils import append_commit_hash

__all__ = [
"run_command",
Expand Down
Loading