SerenaAgent now tracks an initial/startup project activation error and appends it
to the system prompt, instead of the failure being visible only in the log.
This applies both to a failed activation of an explicitly given project and to a
failed --project-from-cwd auto-detection.
Also fix the --project-from-cwd help text, which falsely promised a fallback to the CWD
Resolves#1773
`ansible-language-server` doesn't implement `textDocument/documentSymbol`
and the request used to map diagnostics onto owning symbols just threw. `AnsibleLanguageServer` now
overrides that request to return `None` directly, so diagnostics fall back to being grouped under
the file-level path #1758
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Four items in .serena/memories/adding_new_language_support_guide.md are
wrong against the current source. Two are references that no longer
resolve:
- the subprocess helper lives at solidlsp.util.subprocess_util and is a
module-level function, not a method on a class; the guide named
solidlsp.utils.subprocess_utils, which does not exist
- pytest markers are declared under [tool.pytest.ini_options].markers in
pyproject.toml; there is no pytest.ini in the repository
and two are formatting defects:
- the Documentation section used "### 5" while every other step uses
"## Step N:", so it nested under Step 4 in rendered output
- a stray double colon in the "Implementation Pointers" label
Promoting Documentation to a top-level step also completes the Overview
list, which stopped at four.
Step 5 gains src/serena/resources/project.template.yml, which the
checklist omitted even though a new language server has to appear in its
commented list. The instruction uses `uv run` because the script imports
solidlsp and fails under an ambient interpreter, and it notes the
trailing spaces the script pads each line with, which the committed list
does not carry.
Several backends that are registered and tested were absent from the
user-facing lists: six from the README (pascal, qml, rego, systemverilog,
terraform, vue), six from the Language Support docs page (matlab,
powershell, rego, systemverilog, terraform, toml), and two from the
commented language-server list in the project template
(python_basedpyright, qml).
The drift is long-standing and runs in both directions: matlab,
powershell and toml reached the README but never the docs page; pascal,
vue and qml reached the docs page but never the README; terraform, rego
and systemverilog reached neither, the oldest of them since 2025-07-06.
The two template omissions are the most recent, from #1705 and #1635.
The guide's Documentation step does ask for the README and the docs page,
so most of this was missed rather than unspecified; it does not mention
the project template at all.
The setup notes on the new docs-page entries name the versions Serena
actually pins, taken from the corresponding language-server modules:
MATLAB extension 1.3.9, PowerShell Editor Services 4.4.0 and
PSScriptAnalyzer 1.25.0, Verible v0.0-4051-g9fdb4057, terraform-ls
0.36.5, and Taplo 0.10.0. The PowerShell entry mentions both automatic
installations, since enabling that backend also runs Save-Module against
the user's configured PowerShell repository.
The new Regal link points at open-policy-agent/regal, the current
canonical repository; StyraInc/regal still redirects there, and the
adapter and the CI workflow have not been changed.
The template block is refreshed from scripts/print_language_list.py,
which is why its column widths change: python_basedpyright is longer than
any identifier the previous list contained. The pointer directly below it
still named the Language enum, renamed to LanguageServerId in d2cf18dd.
The previous fix for #1490 depended on four fragments being combined
correctly by hand at the _start() call site: convert_shell_cmd's exec
prefix, the preexec_fn registration, routing through
popen_preserving_pdeathsig, and the Linux/own-session condition.
Nothing enforced their co-occurrence.
Reify "launch a subprocess whose lifecycle is tied to the parent
process (on Linux)" as LanguageServerSubprocessLauncher, a lazily
constructed singleton with a single public method:
launch(process_launch_info: ProcessLaunchInfo, start_new_session: bool) -> Popen[bytes]
Internalizes the libc/prctl preexec_fn, the exec prefixing, the
platform/own-session gate, and the dedicated long-lived spawner
thread (created lazily, only for own-session launches on Linux). The
singleton is required because the spawner thread it owns must be the
one thread in the process performing pdeathsig-registering fork()
calls; launch() takes start_new_session per call so the instance
itself carries no configuration state.
convert_shell_cmd loses the use_exec flag it gained for this fix: its
other callers (solidlsp.language_servers.common, serena.agent) never
used it, and it is invalid on Windows. The exec prefix now lives
entirely inside the launcher, applied to convert_shell_cmd's plain
output, so it can never be requested without the machinery it depends
on.
StdioLanguageServer._start() now calls
LanguageServerSubprocessLauncher.instance().launch(...) instead of
assembling the four fragments itself.
Adapted test/solidlsp/test_pdeathsig.py: the two existing end-to-end
regression tests (short-lived calling thread, SIGKILLed driver) are
unchanged in behavior since they exercise _start()/start() end-to-end
and now transparently go through the new launcher. Added three
targeted tests: convert_shell_cmd's reverted signature, the
launcher's singleton identity, and that its spawner thread is not
created for a non-own-session launch.
tasks are now cancelled on timeout and the executor recovers
Previously, Tool.apply_ex issued its task without a timeout, so a hung tool
would block the TaskExecutor's dispatcher thread forever: the caller received
a TimeoutError after tool_timeout, but no further tasks were ever processed.
Changes:
- Tool.apply_ex now passes the configured tool timeout to issue_task, bounding
the dispatcher's wait as well as the caller's.
- TaskExecutor.Task.result gained cancel_on_timeout (default True): on timeout,
the task is cancelled, preventing execution of tasks still waiting in the
queue and discarding the result of tasks already running.
- Task.wait_until_done no longer takes a timeout parameter; it uses the task's
own timeout and returns whether the task completed. The dispatcher logs a
warning and continues with the next task if the timeout was reached.
- TaskExecutor.execute_task now propagates its timeout to result() instead of
waiting indefinitely, thus also benefiting from cancel-on-timeout.
- Corrected the docstring of Task.result to match the actual semantics.
Tool calls and language server startup dispatch Popen() onto a short-lived
thread (e.g. LanguageServerManager's per-server StartLSThread), which
terminates moments after Popen() returns. PR_SET_PDEATHSIG ties its
registration to that specific calling thread, not the process, so the
language server received SIGTERM and died within milliseconds of a normal
startup on Linux CI, independent of any real SIGKILL scenario.
Route Popen() calls that set preexec_fn=set_pdeathsig_on_parent_exit through
one dedicated, permanently-running daemon thread instead, so the registration
stays tied to a thread that only ever dies alongside the whole process. Added
a regression test that starts a language server on a short-lived thread and
checks it survives past that thread's exit.
find_referencing_symbols/request_references could return incomplete results on
large TypeScript projects. _wait_for_indexing_start_or_completion waits only
_INDEXING_START_GRACE_S (hardcoded 2.0s) for tsserver to *start* emitting
$/progress after opening files; if nothing has appeared by then, it assumes no
indexing is needed and proceeds immediately. On a large project, tsserver can
take longer than that just to resolve the project graph before it even creates
the first progress token, so the first cross-file reference query can race a
project that is still loading.
Every caller of _wait_for_indexing_start_or_completion (the base TypeScript
path and the Svelte companion) always calls expect_indexing() first, so the
"no progress observed" branch is reached specifically when indexing is already
expected; it cannot distinguish "nothing to do" from "not started yet",
because the two look identical from the client for as long as tsserver stays
quiet. That ambiguity cannot be resolved from client-observable signals alone,
so this makes the grace an ls_specific_settings knob (`indexing_start_grace`),
the same way indexing_timeout and server_ready_timeout already are, and raises
the default from 2.0s to 5.0s.
Fixes#1586
On Linux, a SIGKILLed Serena (or an OOM kill, or a crash) leaves its language server process
running: it is launched in its own session so our graceful-shutdown code can clean up the whole
tree, but that code never runs if Serena itself dies uncleanly, and no signal from our process
group reaches a detached session either.
Fix via prctl(PR_SET_PDEATHSIG) at spawn time. Since the process runs under shell=True, the
registration alone only protects the intermediate shell; prefixing the command with `exec` makes
the shell replace itself with the language server so the same PID (and PDEATHSIG registration)
carries through.
Fixes#1490
Bare `*.log` no longer crosses `/` after #1732, so the exclude glob in
the search_files parametrization is anchored to data/ to keep excluding
data/b.log. Matches the repo convention that `**` is required to cross
directory boundaries (see test_search_files_glob_patterns).
Adds first-class support for xAI's Grok Build CLI, following the
existing client-integration pattern (Claude Code, CodeBuddy, Codex):
- grok context: single-project, shaped like claude-code.yml, with the
file-tool exclusions appropriate for a CLI agent that has its own
read/edit/shell tools. structured_tool_output is left at the auto
default (as in the codex and codebuddy contexts); claude-code's
explicit false is a Claude-Code-specific bug workaround that is not
carried over.
- serena setup grok: registers Serena as a user-scoped MCP server via
"grok mcp add" after detecting a compatible grok CLI.
- serena-hooks --client=grok: Grok-native PreToolUse output
({decision, reason}) instead of the Claude-style hookSpecificOutput
envelope; grep/read detection extended to Grok's tool names and
shell payloads (target_file/targetFile path keys, non-string command
values handled defensively). The payload-parsing refinements live in
the remind hook's client-agnostic parsing and apply to all hook
clients: a non-string command value previously raised, and
target_file/targetFile paths were not recognized.
- Docs (030_clients.md #grok), unit tests for setup/hooks/context, and
scripts/live_test_grok.py - a zero-inference, state-preserving live
smoke test against a real grok installation (documented in
CONTRIBUTING.md). Its M5 check verifies the structured-output wire
shape: the grok context (auto default) serves an output schema and
structuredContent for string-returning tools, while the claude-code
context (explicit false workaround) serves plain text only.