mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-13 08:15:59 +00:00
Add ClientSetupHandler and setup CLI command
Add first implementation: ClaudeCode
This commit is contained in:
1 parent
25f5f5095f
commit
2c4174f3bd
2 files changed
+73
No files matched your search
@@ -19,6 +19,7 @@ from tqdm import tqdm
|
||||
|
||||
from serena import serena_version
|
||||
from serena.agent import SerenaAgent
|
||||
from serena.config.client_setup import client_setup_handlers
|
||||
from serena.config.context_mode import SerenaAgentContext, SerenaAgentMode
|
||||
from serena.config.serena_config import (
|
||||
LanguageBackend,
|
||||
@@ -176,6 +177,32 @@ class TopLevelCommands(AutoRegisteringGroup):
|
||||
click.echo(f"Language backend: {language_backend}")
|
||||
click.echo("\nSerena has been initialised successfully.\n")
|
||||
|
||||
@staticmethod
|
||||
@click.command(
|
||||
"setup",
|
||||
help="Set up Serena for use with a specific client by registering it as an MCP server.",
|
||||
context_settings={"max_content_width": _MAX_CONTENT_WIDTH},
|
||||
)
|
||||
@click.argument(
|
||||
"client",
|
||||
type=click.Choice([h.name for h in client_setup_handlers]),
|
||||
)
|
||||
def setup(client: str) -> None:
|
||||
# find the matching handler
|
||||
handler = next(h for h in client_setup_handlers if h.name == client)
|
||||
|
||||
# check applicability
|
||||
if not handler.is_applicable():
|
||||
click.echo(f"\nCannot apply setup for client '{client}' (not found or not functional).\n")
|
||||
raise SystemExit(1)
|
||||
|
||||
# apply the setup
|
||||
if handler.apply():
|
||||
click.echo(f"\nSerena has been successfully set up for {client}.\n")
|
||||
else:
|
||||
click.echo(f"\nFailed to set up Serena for {client}.\n")
|
||||
raise SystemExit(1)
|
||||
|
||||
@staticmethod
|
||||
@click.command("start-mcp-server", help="Starts the Serena MCP server.", context_settings={"max_content_width": _MAX_CONTENT_WIDTH})
|
||||
@click.option("--project", "project", type=PROJECT_TYPE, default=None, help="Path or name of project to activate at startup.")
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
from serena.util.shell import execute_shell_command
|
||||
|
||||
|
||||
class ClientSetupHandler(ABC):
|
||||
def __init__(self, name: str) -> None:
|
||||
self.name = name
|
||||
|
||||
@abstractmethod
|
||||
def is_applicable(self) -> bool:
|
||||
"""
|
||||
:return: whether the client setup can applied (respective client is available)
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def get_mcp_server_options(self) -> list[str]:
|
||||
pass
|
||||
|
||||
def get_mcp_server_command(self) -> str:
|
||||
return f"serena start-mcp-server {' '.join(self.get_mcp_server_options())}"
|
||||
|
||||
@abstractmethod
|
||||
def apply(self) -> bool:
|
||||
"""
|
||||
Applies the client setup
|
||||
"""
|
||||
|
||||
|
||||
class ClientSetupHandlerClaudeCode(ClientSetupHandler):
|
||||
def __init__(self) -> None:
|
||||
super().__init__("ClaudeCode")
|
||||
|
||||
def is_applicable(self) -> bool:
|
||||
result = execute_shell_command("claude --version")
|
||||
return result.return_code == 0 and "Claude" in result.stdout
|
||||
|
||||
def get_mcp_server_options(self) -> list[str]:
|
||||
return ["--context=claude-code", "--project-from-cwd"]
|
||||
|
||||
def apply(self) -> bool:
|
||||
result = execute_shell_command(f"claude mcp add --scope user serena -- {self.get_mcp_server_command()}")
|
||||
return result.return_code == 0
|
||||
|
||||
|
||||
client_setup_handlers = [ClientSetupHandlerClaudeCode()]
|
||||
Reference in new issue
Block a user