* fix: check PATH for rust-analyzer before common locations, with functionality validation
Fixes#800 - rust-analyzer fails if rustup is not installed even when
rust-analyzer exists in PATH (e.g. NixOS, distro packages).
Changes:
- Move PATH check (shutil.which) before common location fallbacks
- Add _is_rust_analyzer_functional() to validate PATH-found binaries
by running --version, catching broken rustup proxy symlinks
- Add tests for Nix PATH detection and broken proxy skip scenarios
* fix: make test_skip_broken_rustup_proxy_in_path work on Windows
The test used hardcoded Unix paths (/usr/bin/rust-analyzer) and
os.path.expanduser("~/.cargo/bin/rust-analyzer") which doesn't
include the .exe extension. On Windows, the production code builds
common paths using pathlib with "rust-analyzer.exe", so the mock
paths never matched, causing RuntimeError instead of finding the
cargo fallback.
Use platform-appropriate paths: on Windows, use .exe extension and
pathlib.Path.home() to match how the production code constructs paths.
---------
Co-authored-by: VoidChecksum <Admin@CyberNord>
quote_arg() only wrapped arguments containing spaces in double quotes.
Shell metacharacters ($, backtick, ;, |, &, etc.) were left unescaped.
On POSIX, use shlex.quote() which single-quotes to prevent all shell
interpretation. Retain original Windows behavior since cmd.exe does not
interpret single-quoted strings.
Three related bugs preventing proper cleanup of language server processes:
1. SerenaAgent.shutdown() checked `hasattr(self, "_is_initialized")` but that
attribute was never set, making shutdown always return early (no-op).
Replace with `hasattr(self, "_active_project")` which is set early in
__init__ and correctly guards against __del__ on partial construction.
2. _activate_project() replaced self._active_project without shutting down
the previous project first, orphaning its language server processes.
Now calls old_project.shutdown() before switching.
3. MCP server_lifespan() logged "shutting down" but never called
agent.shutdown(), so language servers were orphaned on MCP server exit.
Now calls agent.shutdown() in a try/finally block.
1. agent.py: f-string had literal 'f' before variable, producing
"Find the current log file here: f/Users/..." instead of the path.
2. ls.py: delete_text_between_positions logged "insert_text_at_position
called before Language Server started" — wrong method name.
When a registered project path points to a stale or unreachable
filesystem (e.g. a disconnected SSHFS mount), `path.exists()` raises
`OSError: [Errno 5] Input/output error` instead of returning False.
This uncaught exception crashes the entire MCP server on startup,
making all Serena tools unavailable.
Wrap the `path.exists()` call in a try/except OSError so that
inaccessible paths are gracefully skipped with a warning, matching
the existing behavior for non-existent paths.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previously, only project.yml resave due to incomplete config accounted for this,
but dynamic language changes triggered via the dashboard (which triggered a save
to update the language list) did not.
Since ProjectConfig can always contain local overrides,
* we handle configuration updates by explicitly updating on disk only the
keys known to have been changed
* we explicitly represent the presence of local overrides, such that
inadmissible save operations are detectable.
References and definition not working yet. Since ansible resolves same files as yaml LS, we will need to add disambiguation later.
Work in progress, improvements on the language server itself are being worked on, ansible support in Serena will be extended accordingly in the future.
The base _shutdown() calls process.terminate() directly on the subprocess,
which on Windows with shell=True only kills the cmd.exe wrapper, leaving
the shader-language-server binary running as an orphan. Override stop() in
HlslLanguageServer to use psutil to terminate the full process tree before
the standard shutdown.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Integrates the Nomic Foundation @nomicfoundation/solidity-language-server
as a new Language.SOLIDITY backend (experimental). Supports .sol files with
go-to-definition, find references, document symbols, hover, and diagnostics.
The server is automatically installed via npm on first use.
Fix PHP symbol retrieval via Intelephense LSP
* intelephense.py: Add missing client capability declarations for
documentSymbol (with hierarchical support), references, hover, and
workspace symbol. Without these, Intelephense does not advertise
documentSymbolProvider and returns empty results for get_symbols_overview.
Add PHP tests validating hierarchical symbols and LS routing fix
- test_document_symbols_hierarchical_structure: verifies Intelephense
returns DocumentSymbol[] with class/method hierarchy (not flat
SymbolInformation[]) when hierarchicalDocumentSymbolSupport is declared
- test_full_symbol_tree_within_file: verifies request_full_symbol_tree
scoped to sample.php returns Dog/Animal/greet/fetch with Dog containing
greet as a child (not at root level)
- test_find_symbol_within_php_file: verifies find_symbol with a PHP
file path (relative_path=) routes to the PHP language server via
get_language_server() rather than iterating all servers
Peripheral changes:
- symbol.py (LanguageServerSymbolRetriever.find_symbols): When searching
within a specific file, route to the file-type-appropriate language server
via get_language_server() instead of querying all servers. This ensures
PHP files are served by Intelephense and not silently skipped.
Previously, ProjectConfig.autogenerate() raised a ValueError when no
recognized source files were found (e.g. empty dir, JetBrains project,
or project with only gitignored files). This prevented users from
creating Serena projects in valid scenarios, especially with the
JetBrains backend where language servers are not used at all.
Now, autogenerate() creates the project with an empty languages list
and logs a warning explaining that symbol tools will be unavailable
for the LSP backend. Users can add languages later via the dashboard
or by editing the project configuration manually.
Fixes#1053
Co-Authored-By: Claude <noreply@anthropic.com>
Simplify dependency injections by depending on Project instead of low-level instances
* LanguageServerSymbolRetriever(Project) - contains the instance
* LanguageServerCodeEditor(LanguageServerSymbolRetriever)
* CodeEditor(Project)
Move retrieval methods for LS manager from SerenaAgent to Project, including
the exception-based problem report
* Keep unset in project.yml by default (only explicit override)
* Fix member docstrings and member grouping in SerenaConfig
* Fix missing migration in SerenaConfig (ensure setting is saved)