Commit Graph
3328 Commits
Author SHA1 Message Date
Scott McLeod bcb3fc74ff Detect FreeBSD as a platform (#1947)
Language server initialization failed on FreeBSD with "Unknown platform" as there was no mapping for FreeBSD.
2026-09-03 17:15:10 +02:00
ef30801377 fix(config): persist removed registered projects (#1925)
Fixes regression introduced in unreleased commit 8a4d116

Co-authored-by: Yu-0312 <2.66498311e+08+Yu-0312@users.noreply.github.com>
Co-authored-by: Dr. Dominik Jain <dominik.jain@oraios-ai.de>
2026-09-03 15:54:09 +02:00
MaxandYu-0312 24940a1560 fix(process): reap language server descendants (#1918)
* fix(process): reap language server descendants

* fix(process): preserve descendant snapshot for kill fallback

* fix(process): share termination timeout deadline

* fix(process): reap descendants in process-group cleanup

* fix(process): reap leader after descendant kill timeout

---------

Co-authored-by: Yu-0312 <2.66498311e+08+Yu-0312@users.noreply.github.com>
2026-09-03 15:28:05 +02:00
MaxandYu-0312 6f86ae308e fix(solidity): isolate Hardhat state on macOS (#1910)
* fix(solidity): isolate Hardhat state on macOS

---------

Co-authored-by: Yu-0312 <2.66498311e+08+Yu-0312@users.noreply.github.com>
2026-09-03 15:21:15 +02:00
Amir Fathi 14f1a3ce11 fix(memories): stop losing memory content on an interrupted write (#1969)
* fix(memories): stop losing memory content on an interrupted write

save_memory() and edit_memory() wrote the memory file with a plain
open(path, "w") followed by f.write(content). That truncates the file
before the new content is complete, so a crash, an OOM kill, or a
disk-full error partway through the write can leave the file empty or
holding a stale tail instead of either the old or the new content.

Add write_file_atomic() to util/file_system.py: it writes to a temp
file in the same directory, then os.replaces it into place, with the
same short PermissionError retry save_yaml() already uses for a
transient Windows sharing violation. save_memory() and edit_memory()
now go through it instead of the direct open().

CodeEditor._save_edited_file() is left out of this change: os.replace
makes the destination inherit the temp file's permissions rather than
the original's, and tempfile.mkstemp creates that temp file 0600, so
an executable source file would lose its +x bit on save. Memory files
are always plain text Serena itself creates, so this doesn't apply to
them.

Refs #1958

* fix(memories): preserve file mode in write_file_atomic

mkstemp() creates the temp file with mode 0600 regardless of umask, and
os.replace() carries that mode into the destination. save_memory() and
edit_memory() going through write_file_atomic() silently tightened an
existing memory file's permissions (e.g. 0644 -> 0600) on every save or
edit, dropping group/other read access.

Restore the target's existing mode before the replace, or fall back to
what a plain open(path, "w") would give a brand-new file (0666 masked
by the process umask) when there is nothing to preserve.

Refs #1958

* test(memories): skip POSIX permission-preservation tests on Windows

os.chmod does not set POSIX group/other bits on Windows, so
test_save_memory_preserves_existing_file_permissions and
test_edit_memory_preserves_existing_file_permissions assert a mode
the platform cannot produce. Matches the existing skipif convention
used elsewhere in this suite for POSIX-only filesystem behavior.

Signed-off-by: Amir Fathi <amirfathi.me@gmail.com>

---------

Signed-off-by: Amir Fathi <amirfathi.me@gmail.com>
2026-09-03 15:04:12 +02:00
Yu-0312 69ab73dc7f fix(mcp): report Serena version in initialize 2026-09-03 14:55:31 +02:00
Johan Larsson 25631db556 feat(solidlsp): add Fatou support
Refs #1931
2026-09-03 14:43:25 +02:00
TANIGUCHI KoheiandClaude Opus 5 e771adedb5 Update the flake inputs
The inputs had been pinned for a year.

Verified on aarch64-darwin: `nix build` succeeds and the resulting `bin/serena`
reports `Serena 1.7.1.dev0`. The Linux packages and devShell evaluate cleanly.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-03 13:05:51 +02:00
TANIGUCHI KoheiandClaude Opus 5 6d387aa8ec Adapt the flake to nixpkgs' deprecation of the stdenv platform predicates
nixpkgs now warns on every access to the `stdenv.is*` shorthands, which hide
the build/host/target distinction
(https://github.com/NixOS/nixpkgs/pull/518407). The nixpkgs pinned here
predates that change, but a future update will surface the warnings.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-03 13:05:51 +02:00
TANIGUCHI KoheiandClaude Opus 5 4ec3ce398e Ignore the symlink a Nix build leaves at the repository root
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-03 13:05:51 +02:00
Amir Fathi e1322a3b99 fix(dart): wait for analyzer readiness signal before returning from start()
DartLanguageServer registered handlers for $/analyzerStatus and
experimental/serverStatus but both were no-ops, so start() returned as
soon as initialized was sent instead of waiting for either signal, unlike
every other backend (pyright, basedpyright, rust-analyzer, clojure-lsp,
jedi, omnisharp, clangd) that receives the same notifications. A request
issued right after activation could return before the workspace scan
finished.

Gate on a threading.Event set by either notification, bounded by 60s,
mirroring pyright_server.py's analysis_complete pattern.
2026-09-03 13:02:50 +02:00
Dominik Jain 813fd98f4f CLI: Fix project index-file command not using only the relevant language server to index the given file
Resolves #1965
2026-09-02 15:12:16 +02:00
Dr. Dominik Jain c8ef9d358e Merge pull request #1872 from AmirF194/fix/1871-nextflow-scan-flush-flag
fix(nextflow): don't mark workspace scan flushed when both probes fail
2026-09-02 13:46:24 +02:00
Amir Fathi 47c0a4bb66 fix(hooks): reset reminder counters after a successful Codex Serena call
Codex's documented hook wiring only routes `serena-hooks remind` through
PreToolUse on the `Bash` matcher, so `ToolUseCounter.update()`'s
reset-on-Serena-tool-use branch is never reached there: it only fires when
`remind` itself is invoked for a `mcp__serena__*` tool name, which the
Bash-only matcher excludes. Reminder counters therefore never clear after a
successful Serena call, and an unrelated grep/read burst afterwards can trip
the deny threshold on state that should have been reset.

Add a `serena-hooks reset` command, wired to PostToolUse on Serena's own
tools, that resets the counters after a successful call. Gated on the call
having succeeded (`tool_response` carrying no `isError: true`, the MCP
`tools/call` result shape) so a failed Serena call does not mask a real
grep/read streak, per the issue's own acceptance criteria. The symbolic-tool
classification is shared with the existing PreToolUse hook via a small
extracted helper so both agree on what counts as a Serena tool.

Fixes #1852
2026-09-02 13:21:42 +02:00
Amir Fathi 9f4a2b4830 fix(jetbrains): serialize IDE launches across concurrent Serena sessions
_init_active_project_language_backend launched the configured IDE with a
fire-and-forget subprocess.Popen whenever no plugin server matched the
activating project, independently in every session. Two or more sessions
activating different projects at (nearly) the same time each decided
independently that no server was running and raced jetbrains_launch_command
against the same IDE config directory; only one IDE instance can hold that
directory's lock, so the rest failed with a native DirectoryLock modal that
never surfaces as a subprocess exit code, leaving Serena with no plugin
server and no indication why.

Add JetBrainsLaunchCoordinator.launch_and_wait_for_plugin_server, which
serializes launches on a file lock keyed by jetbrains_launch_command and
re-checks for a plugin server both before and after acquiring it, so a
session that loses the race waits for the winner's IDE instead of starting
its own. It also polls for the plugin server to become reachable after the
launch command exits, closing the second gap the issue names: the launcher
process exiting is not the same as the IDE being ready to serve.

Fixes #1864
2026-09-02 13:17:53 +02:00
Dr. Dominik Jain f41f33c904 Merge branch 'main' into fix/1871-nextflow-scan-flush-flag 2026-09-02 13:06:49 +02:00
mameikagou e473dd64b5 docs: fix issue template user guide link 2026-09-02 13:02:27 +02:00
Amir Fathi dc59a8931c Fix: Exceptions raised during LanguageServerManager.start did not stop the language server subprocess if it was already started
start() now catches an exception from _start_server(), stops the process if it is
already running, and re-raises. 

Fixes #1949
2026-09-02 12:53:41 +02:00
Dominik Jain 43ae0211d7 Fix: read_only restriction in project definition was not applied to base tool set when in single-project context
Fixes #1938
2026-08-30 17:37:14 +02:00
Michael Panchenko 7fcbca7e62 Merge pull request #1848 from AmirF194/fix/1814-tsserver-crash-silent-empty-result
Fix: surface a mid-indexing tsserver crash instead of returning {}
2026-08-20 08:51:14 +02:00
Michael Panchenko 2561478a70 fix(clojure): declare didChangeWatchedFiles client capability (#1884)
Serena notifies language servers about files changed outside its own edit tools (a git checkout, another editor, a build step) by sending workspace/didChangeWatchedFiles from LanguageServerManager.poll_and_notify, whose docstring names this exact case: such edits are 'otherwise invisible to a warm language server, causing symbolic queries to answer from a stale index'.

ClojureLSP never declared the corresponding client capability, so clojure-lsp was not told those notifications are sent and need not treat them as a reason to invalidate its analysis. DefaultInitializeParamsBuilder does not supply a default capabilities block, so nothing filled this in on the server's behalf.

Relates to #1593, where find_symbol returned a body from a comment mentioning the symbol rather than its definition, at a position the symbol had previously occupied.
2026-08-18 09:47:19 +02:00
aayushbaluni d4dbcecaae fix(clojure): declare didChangeWatchedFiles client capability
Serena notifies language servers about files changed outside its own edit tools (a git checkout, another editor, a build step) by sending workspace/didChangeWatchedFiles from LanguageServerManager.poll_and_notify, whose docstring names this exact case: such edits are 'otherwise invisible to a warm language server, causing symbolic queries to answer from a stale index'.

ClojureLSP never declared the corresponding client capability, so clojure-lsp was not told those notifications are sent and need not treat them as a reason to invalidate its analysis. DefaultInitializeParamsBuilder does not supply a default capabilities block, so nothing filled this in on the server's behalf.

Relates to #1593, where find_symbol returned a body from a comment mentioning the symbol rather than its definition, at a position the symbol had previously occupied.
2026-08-17 11:39:28 +05:30
xor 19f1c33bbf Format 2026-08-16 16:57:13 +02:00
Amir Fathi c72c07ae29 fix(nextflow): don't mark workspace scan flushed when both probes fail
_flush_deferred_workspace_scan sets _workspace_scan_flushed unconditionally after its
two completion() flush attempts, even when both raised. A later find_referencing_symbols
call then silently skips the flush and answers from a possibly-incomplete workspace AST
cache for the rest of the session, with no exception and no retry.

Fixes #1871
2026-08-15 19:05:13 +00:00
Dominik Jain 93ec043105 Updated interprompt sync commit identifiers (push) 2026-08-14 20:50:47 +02:00
Dominik Jain 1814fc9a0f interprompt edbee70392dca692d36d136c47a61513f4a2b222
commit edbee70392dca692d36d136c47a61513f4a2b222
  Author: Dominik Jain <dominik.jain@outlook.com>
  Date:   Fri Aug 14 20:49:45 2026 +0200

      Sync reframer

        commit 8f0e933cca9481a57ccabf1ef9419815274cdfa1
        Author: Dominik Jain <dominik.jain@outlook.com>
        Date:   Fri Aug 14 19:56:51 2026 +0200

            Allow to configure name of generated class

        reframer/interprompt/prompt_factory.py

        commit 7eb3472cec8179a19e1f127ecbdeadf50becab01
        Author: Dominik Jain <dominik.jain@outlook.com>
        Date:   Fri Aug 14 19:48:49 2026 +0200

            Allow to configure interprompt package name and fix imports in generated code (must include PromptList)

        reframer/interprompt/prompt_factory.py

        commit 015781ed2b6b0e2311d9938788403e0b33b19e17
        Author: Dominik Jain <dominik.jain@outlook.com>
        Date:   Fri Aug 14 19:36:07 2026 +0200

            Fix: Language code was read at the wrong level

        reframer/interprompt/multilang_prompt.py

        commit 487e9eed63d435257ee03eda03e668b4e7a73019
        Author: Dominik Jain <dominik.jain@outlook.com>
        Date:   Fri Aug 14 19:08:18 2026 +0200

            Use relative imports

        reframer/interprompt/jinja_template.py

  src/interprompt/jinja_template.py
  src/interprompt/multilang_prompt.py
  src/interprompt/prompt_factory.py
2026-08-14 20:50:47 +02:00
Dominik Jain 3ad624f511 Merge branch 'main' of github.com:oraios/serena 2026-08-14 15:57:04 +02:00
Dominik Jain 36e5e981e7 Updated interprompt sync commit identifiers (pull) 2026-08-14 15:56:20 +02:00
Dominik Jain 17e39c9655 Fix duplicate section 2026-08-14 15:46:51 +02:00
Jia Tianzhao 27644053ad fix(dart): handle analyzer status notifications (#1863)
The Dart analysis server emits $/analyzerStatus while it analyzes a workspace.
The Dart adapter did not register this server-specific notification, so the
generic notification dispatcher logged every event as an unhandled-method
warning even though no client action is required.

Register the method with the adapter's existing no-op notification handler,
keeping the global behavior for genuinely unknown notifications unchanged. Add
a startup regression test that sends the notification through the production
dispatcher, and document the fix in the changelog.

Fixes #1855
2026-08-13 22:39:50 +02:00
Amir Fathi ffcb66ba43 Fix: surface a mid-indexing tsserver crash instead of returning {}
typescript-language-server sends a $/progress "end" for the in-flight
token as part of tearing its connection down after tsserver aborts (e.g.
a V8 heap OOM). _wait_for_indexing_start_or_completion could not
distinguish that from a real completion, so find_referencing_symbols
logged "TypeScript cross-file indexing complete" and returned {} with
isError: false, indistinguishable from a symbol genuinely having no
references.

The crash is already observed independently via window/logMessage
(type Error, "[tsserver] Exited"), but the handler only logged it. Wire
that signal into a _crash_message flag and raise TypeScriptServerCrashedError
from every path that would otherwise report indexing as complete
(wait_for_indexing and both early-return branches of
_wait_for_indexing_start_or_completion), so a crash propagates as a tool
error instead of a silent empty result.

Fixes #1814
2026-08-13 12:18:34 +00:00
Dominik Jain 25610cb280 Improve docstrings 2026-08-13 13:10:37 +02:00
Eshin KunishimaandClaude Opus 5 7067f566c0 Remove redundant dotenv dependency (#1844)
`dotenv` was added in 605bca19 together with the `from dotenv import
load_dotenv` call in `src/serena/agno.py`, six days after `python-dotenv` had
already been added in 276f6a84. The `dotenv` module that the code imports is
provided by `python-dotenv`. The separately named `dotenv` distribution on PyPI
is an unrelated, deprecated project by another author, republished as a
metadata-only stub whose only content is `Requires-Dist: python-dotenv`; its
wheel ships no Python module at all, so the dependency has never contributed
anything at runtime.

The redundancy survived the bulk pinning pass in 45cd8ca1, which mechanically
rewrote `dotenv>=0.9.9` to `dotenv==0.9.9`.

Dropping it removes a third-party PyPI name from the set of distributions
trusted at install time, with no behavioural change. Verified that `from dotenv
import load_dotenv` resolves with only `python-dotenv==1.2.2` installed.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-13 12:36:34 +02:00
Dominik Jain 8a4d116c13 Fix: Parallel agents auto-registering projects could overwrite each other's changes
to the global project list in `serena_config.yml`

Fixes #1850
2026-08-13 12:21:45 +02:00
Merlin Hughes a9f99c679b Scala: wait for Metals' reported work, not a fixed 5 seconds (#1859)
Cross-file queries waited 5s after the first file was opened. On a cold Metals
that is long before it has imported the build, indexed, and — crucially —
compiled: references come from SemanticDB, which the build server writes as it
compiles, so a query made in between returns some of the references rather than
none, with nothing to mark it partial. Against a ~700-file Scala 3 build the
first find-references returned 124 of 242.

Metals already reports all of this as work-done progress; Serena did not declare
`window.workDoneProgress`, so none of it arrived. Declare it, track the tokens,
and wait for them before the first cross-file query — the same event-based shape
as TypeScript's indexing wait (#1639), whose hooks this uses.

Readiness is "nothing outstanding for a moment", not "nothing outstanding":
Metals hands off between its phases rather than overlapping them, so the token
set empties for around a second between the import ending and indexing starting,
and a plain drain returns in that gap. Measured on the same build, the first
find-references now returns all 242, taking 32s rather than 22s.
2026-08-13 11:43:24 +02:00
Merlin Hughes 5107b11fb3 Merge pull request #1847 from merlinorg/scala-document-project-root-settings
docs: document the three Scala settings the configuration page omitted
2026-08-12 15:06:48 +02:00
Dominik Jain f1d78a88ce Update docstring of web_dashboard_interface 2026-08-10 19:02:05 +02:00
Dr. Dominik Jain 946ad98178 Merge pull request #1836 from oraios/release-1.7
Release v1.7.0
2026-08-09 20:37:45 +02:00
Dominik Jain 2cb9d87227 Set version to v1.7.1.dev0 2026-08-09 20:14:38 +02:00
Dominik Jain 949a27ef1e Release v1.7.0 2026-08-09 20:14:37 +02:00
Dominik Jain be5cf4e41e Merge remote-tracking branch 'origin/main' into release-1.7 2026-08-09 20:13:17 +02:00
Dr. Dominik Jain 3c8e9854f6 Improve identification of container/low-level symbols (#1834)
This affects results returned for request_containing_symbol,
some tests were adjusted accordingly.
2026-08-09 20:12:51 +02:00
Dominik Jain bad11d825c Update news item 2026-08-09 17:51:16 +02:00
Dominik Jain 140d0b03ee Merge branch 'main' into release-1.7 2026-08-09 17:42:14 +02:00
Dr. Dominik Jain 281e9db2eb Merge pull request #1823 from AmirF194/fix/1818-process-group-cleanup-without-enumeration 2026-08-09 17:37:16 +02:00
Dominik Jain bd86cf840a Introduce ManagedSubprocess to encapsulate subprocess lifecycle management
The knowledge that a process launched with start_new_session=True is its own
group leader (and thus that its PGID equals its PID) was previously held by
StdioLanguageServer, i.e. the consumer had to know how the launcher works in
order to terminate the process correctly.

ManagedSubprocess now owns the process group ID alongside the Popen instance,
deriving it at construction time, and provides the termination logic; the
launcher returns instances of it. StdioLanguageServer merely holds one and
accesses the process through its interface.

LanguageServerSubprocessLauncher now returns ManagedSubprocess instances and
is renamed to ManagedSubprocessLauncher accordingly.
2026-08-09 17:09:57 +02:00
xor c9f0ab80f1 SolidLSP: admit Struct, Interface and Constant symbols as reference containers (#1831)
find_referencing_symbols degraded to file-level attribution for any
reference located inside a Go struct body, interface body or const
group: request_containing_symbol found no admissible container, so
request_referencing_symbols logged "Could not find containing symbol
... Returning file symbol instead" and fell back to the file symbol,
losing the answer the tool exists to give.

Root cause: the candidate-container filter admitted only Python's
container kinds {Method, Function, Class} (plus Variable via the
one-liner-exempt path). The language server is not at fault:
hierarchicalDocumentSymbolSupport is declared and the DocumentSymbol
tree is complete, but Go structs arrive as SymbolKind.Struct,
interfaces as Interface and const-group members as Constant - none of
which were admitted, so every candidate was rejected.

Fix, mirroring the existing structure of the filter:
- Struct and Interface join the multi-line container whitelist,
- Constant joins Variable on the one-liner-exempt path (const-group
  members are one-liners by nature, exactly like the module-level
  variables that path already serves).

The Python suite shows no attribution change
(test/solidlsp/python/test_symbol_retrieval.py: 80 passed). Languages
whose containers use the added kinds (e.g. Rust and C structs,
TypeScript interfaces) get the same admission; verified for Go and
Python only.

Regression coverage: new Go fixture containment_sample.go with a
const-iota group, a struct field and an interface method all
referencing a named type; four tests assert containing-symbol and
referencing-symbol attribution, and all four fail against the
pre-change ls.py (verified). Full go-marker suite: 21 passed,
1 skipped.
2026-08-09 16:07:20 +02:00
xor bdc9a2de2d CI: cache npm dependencies for web test fixtures (#1698) 2026-08-09 16:00:55 +02:00
Amir Fathi ec18c48202 Fix: LSP process-group cleanup no longer requires process-table enumeration
An independently-started LSP process is already its own POSIX process group leader
(start_new_session=True), so cleanup can signal that known group directly via os.killpg
instead of walking the tree with psutil.Process.children(recursive=True), which requires
system-wide process-table enumeration that can be denied even for processes we started
and own (#1818).
2026-08-09 12:13:14 +00:00
Dominik Jain e663ccb584 Add news item for v1.7.0 release 2026-08-09 13:54:14 +02:00