mirror of
https://github.com/tiennm99/serena.git
synced 2026-10-13 16:15:29 +00:00
Merge remote-tracking branch 'origin/main' into multilspy-update
Conflicts: src/multilspy/language_server.py
This commit is contained in:
commit
c80cf59a59
6 files changed
+88
-40
No files matched your search
+7
-1
@@ -2,8 +2,14 @@
|
||||
|
||||
Changes prior to the next official version change will appear here.
|
||||
|
||||
* Serena core:
|
||||
* bugfix in find_symbol tool (a bug fixed in LS)
|
||||
* merged the two overview tools (for dir and file) int a single one
|
||||
* one-click setup for Cline enabled
|
||||
|
||||
* Language Servers:
|
||||
* Add further file extensions considered by the language servers for Python (.pyi), JavaScript (.jsx) and TypeScript (.tsx, .jsx)
|
||||
* Add further file extensions considered by the language servers for Python (.pyi), JavaScript (.jsx) and TypeScript (.tsx, .jsx)
|
||||
|
||||
|
||||
# 2025-04-07
|
||||
|
||||
|
||||
@@ -586,8 +586,7 @@ Here is the full list of Serena's tools with a short description (output of `uv
|
||||
* `find_referencing_symbols`: Finds symbols that reference the symbol at the given location (optionally filtered by type).
|
||||
* `find_symbol`: Performs a global (or local) search for symbols with/containing a given name/substring (optionally filtered by type).
|
||||
* `get_active_project`: Gets the name of the currently active project (if any) and lists existing projects
|
||||
* `get_dir_overview`: Gets an overview of the top-level symbols defined in all files within a given directory.
|
||||
* `get_document_overview`: Gets an overview of the top-level symbols defined in a given file.
|
||||
* `get_symbols_overview`: Gets an overview of the top-level symbols defined in a given file or directory.
|
||||
* `insert_after_symbol`: Inserts content after the end of the definition of a given symbol.
|
||||
* `insert_at_line`: Inserts content at a given line in a file.
|
||||
* `insert_before_symbol`: Inserts content before the beginning of the definition of a given symbol.
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# MCP Installation instructions
|
||||
|
||||
This document is mainly used as instructions for AI-assistants like Cline and others that
|
||||
try to do an automatic install based on freeform instructions.
|
||||
|
||||
0. Make sure `uv` is installed. If not, install it using either `curl -LsSf https://astral.sh/uv/install.sh | sh` (macOS, Linux) or
|
||||
`powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"` (Windows). Find the path to the `uv` executable,
|
||||
you'll need it later.
|
||||
1. Clone the repo with `git clone git@github.com:oraios/serena.git` and change into its dir (e.g., `cd serena`)
|
||||
2. Check if `serena_config.yml` exists. If not, create it with `cp serena_config.template.yml serena_config.yml`. Read the instructions in the config.
|
||||
3. In the config, check if the path to your project was added. If not, add it to the `projects` section
|
||||
4. In your project, create a `.serena` if needed and check whether `project.yml` exists there.
|
||||
5. If no `project.yml` was found, create it using `cp /path/to/serena/myproject.template.yml /path/to/your/project/.serena/project.yml`
|
||||
6. Read the instructions in `project.yml`. Make sure the `project.yml` has the correct project language configured.
|
||||
Remove the project_root entry there.
|
||||
7. Finally, add the Serena MCP server config like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
...
|
||||
"serena": {
|
||||
"command": "/abs/path/to/uv",
|
||||
"args": ["run", "--directory", "/abs/path/to/serena", "serena-mcp-server", "/path/to/your/project/.serena/project.yml"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
@@ -31,7 +31,7 @@ projects:
|
||||
#
|
||||
# Limitations: doesn't seem to work with the community version of Claude Desktop for Linux
|
||||
# Might also cause problems with some MCP clients - if you have any issues, try disabling this
|
||||
gui_log_window: True
|
||||
gui_log_window: False
|
||||
|
||||
# minimum log level for the GUI log window (10 = debug, 20 = info, 30 = warning, 40 = error)
|
||||
gui_log_level: 20
|
||||
@@ -886,13 +886,18 @@ class LanguageServer:
|
||||
|
||||
:return: A list of root symbols representing the top-level packages/modules in the project.
|
||||
"""
|
||||
if within_relative_path is not None and os.path.isfile(within_relative_path):
|
||||
if self.should_ignore_path(within_relative_path):
|
||||
self.logger.log(f"You passed a file explicitly, but it is ignored. This is probably an error. File: {within_relative_path}", logging.ERROR)
|
||||
return []
|
||||
|
||||
_, root_nodes = await self.request_document_symbols(within_relative_path, include_body=include_body)
|
||||
return root_nodes
|
||||
if within_relative_path is not None:
|
||||
within_abs_path = os.path.join(self.repository_root_path, within_relative_path)
|
||||
if not os.path.exists(within_abs_path):
|
||||
raise FileNotFoundError(f"File or directory not found: {within_abs_path}")
|
||||
if os.path.isfile(within_abs_path):
|
||||
if self.should_ignore_path(within_relative_path):
|
||||
self.logger.log(f"You passed a file explicitly, but it is ignored. This is probably an error. File: {within_relative_path}", logging.ERROR)
|
||||
return []
|
||||
else:
|
||||
_, root_nodes = await self.request_document_symbols(within_relative_path, include_body=include_body)
|
||||
return root_nodes
|
||||
|
||||
# Helper function to recursively process directories
|
||||
async def process_directory(dir_path: str) -> List[multilspy_types.UnifiedSymbolInformation]:
|
||||
@@ -1040,6 +1045,23 @@ class LanguageServer:
|
||||
for root in document_roots
|
||||
]
|
||||
|
||||
async def request_overview(self, within_relative_path: str) -> dict[str, list[tuple[str, multilspy_types.SymbolKind, int, int]]]:
|
||||
"""
|
||||
An overview of all symbols in the given file or directory.
|
||||
|
||||
:param within_relative_path: the relative path to the file or directory to get the overview of.
|
||||
:return: A mapping of all relative paths analyzed to lists of tuples (name, kind, line, column) of all top-level symbols in the corresponding file.
|
||||
"""
|
||||
abs_path = (Path(self.repository_root_path) / within_relative_path).resolve()
|
||||
if not abs_path.exists():
|
||||
raise FileNotFoundError(f"File or directory not found: {abs_path}")
|
||||
|
||||
if abs_path.is_file():
|
||||
symbols_overview = await self.request_document_overview(within_relative_path)
|
||||
return {within_relative_path: symbols_overview}
|
||||
else:
|
||||
return await self.request_dir_overview(within_relative_path)
|
||||
|
||||
async def request_hover(self, relative_file_path: str, line: int, column: int) -> Union[multilspy_types.Hover, None]:
|
||||
"""
|
||||
Raise a [textDocument/hover](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_hover) request to the Language Server
|
||||
@@ -1788,6 +1810,19 @@ class SyncLanguageServer:
|
||||
).result(timeout=self.timeout)
|
||||
return result
|
||||
|
||||
def request_overview(self, within_relative_path: str) -> dict[str, list[tuple[str, multilspy_types.SymbolKind, int, int]]]:
|
||||
"""
|
||||
An overview of all symbols in the given file or directory.
|
||||
|
||||
:param within_relative_path: the relative path to the file or directory to get the overview of.
|
||||
:return: A mapping of all relative paths analyzed to lists of tuples (name, kind, line, column) of all top-level symbols in the corresponding file.
|
||||
"""
|
||||
assert self.loop
|
||||
result = asyncio.run_coroutine_threadsafe(
|
||||
self.language_server.request_overview(within_relative_path), self.loop
|
||||
).result()
|
||||
return result
|
||||
|
||||
def request_hover(self, relative_file_path: str, line: int, column: int) -> Union[multilspy_types.Hover, None]:
|
||||
"""
|
||||
Raise a [textDocument/hover](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_hover) request to the Language Server
|
||||
|
||||
+9
-30
@@ -125,7 +125,7 @@ class SerenaConfig:
|
||||
self.projects[project_config.project_name] = project_config
|
||||
self.project_names = list(self.projects.keys())
|
||||
|
||||
self.gui_log_window_enabled = config_yaml.get("gui_log_window", True)
|
||||
self.gui_log_window_enabled = config_yaml.get("gui_log_window", False)
|
||||
self.gui_log_window_level = config_yaml.get("gui_log_level", logging.INFO)
|
||||
self.enable_project_activation = config_yaml.get("enable_project_activation", True)
|
||||
|
||||
@@ -590,25 +590,26 @@ class ListDirTool(Tool):
|
||||
return self._limit_length(result, max_answer_chars)
|
||||
|
||||
|
||||
class GetDirOverviewTool(Tool):
|
||||
class GetSymbolsOverviewTool(Tool):
|
||||
"""
|
||||
Gets an overview of the top-level symbols defined in all files within a given directory.
|
||||
Gets an overview of the top-level symbols defined in a given file or directory.
|
||||
"""
|
||||
|
||||
def apply(self, relative_path: str, max_answer_chars: int = _DEFAULT_MAX_ANSWER_LENGTH) -> str:
|
||||
"""
|
||||
Gets an overview of the given directory.
|
||||
For each file in the directory, we list the top-level symbols in the file (name, kind, line).
|
||||
Use this tool to get a high-level understanding of the code symbols inside a directory.
|
||||
Gets an overview of the given file or directory.
|
||||
For each analyzed file, we list the top-level symbols in the file (name, kind, line).
|
||||
Use this tool to get a high-level understanding of the code symbols.
|
||||
Calling this is often a good idea before more targeted reading, searching or editing operations on the code symbols.
|
||||
|
||||
:param relative_path: the relative path to the directory to get the overview of
|
||||
:param relative_path: the relative path to the file or directory to get the overview of
|
||||
:param max_answer_chars: if the overview is longer than this number of characters,
|
||||
no content will be returned. Don't adjust unless there is really no other way to get the content
|
||||
required for the task. If the overview is too long, you should use a smaller directory instead,
|
||||
(e.g. a subdirectory).
|
||||
:return: a JSON object mapping relative paths of all contained files to info about top-level symbols in the file (name, kind, line, column).
|
||||
"""
|
||||
path_to_symbol_infos = self.language_server.request_dir_overview(relative_path)
|
||||
path_to_symbol_infos = self.language_server.request_overview(relative_path)
|
||||
result = {}
|
||||
for file_path, symbols in path_to_symbol_infos.items():
|
||||
result[file_path] = [_tuple_to_info(*symbol_info) for symbol_info in symbols]
|
||||
@@ -617,28 +618,6 @@ class GetDirOverviewTool(Tool):
|
||||
return self._limit_length(result_json_str, max_answer_chars)
|
||||
|
||||
|
||||
class GetDocumentOverviewTool(Tool):
|
||||
"""
|
||||
Gets an overview of the top-level symbols defined in a given file.
|
||||
"""
|
||||
|
||||
def apply(self, relative_path: str, max_answer_chars: int = _DEFAULT_MAX_ANSWER_LENGTH) -> str:
|
||||
"""
|
||||
Use this tool to get a high-level understanding of the code symbols in a file. It often makes sense
|
||||
to call this before targeted reading, searching or editing operations on the code symbols in the file,
|
||||
as the output will contain a lot of information about names and lines.
|
||||
|
||||
:param relative_path: the relative path to the file to get the overview of
|
||||
:param max_answer_chars: if the overview is longer than this number of characters,
|
||||
no content will be returned. Don't adjust unless there is really no other way to get the content
|
||||
required for the task.
|
||||
:return: a JSON object with the info (name, kind, line, column) of all top-level symbols in the file.
|
||||
"""
|
||||
result = self.language_server.request_document_overview(relative_path)
|
||||
result_json_str = json.dumps([_tuple_to_info(*symbol_info) for symbol_info in result])
|
||||
return self._limit_length(result_json_str, max_answer_chars)
|
||||
|
||||
|
||||
class FindSymbolTool(Tool):
|
||||
"""
|
||||
Performs a global (or local) search for symbols with/containing a given name/substring (optionally filtered by type).
|
||||
|
||||
Reference in new issue
Block a user