A plain truncate-and-write (open(path,"w")) is not atomic: a concurrent writer
(a second Serena process updating the auto-managed registered-projects list) or an
interrupted write can leave the file half-overwritten -- a shorter value over a longer
one leaves a stale tail, corrupting the YAML so every later load fails. This is what
wedged native benchmark runs (serena MCP crashed at startup with a ruamel ScannerError
-> 0 tools registered -> agent silently degraded to Bash).
Write to a temp file in the same dir, then os.replace onto the target (atomic;
last-writer-wins, never a corrupt interleave). Retry os.replace on Windows
PermissionError (WinError 5/32 sharing violation under contention). Adds
test/serena/util/test_yaml.py covering the shorter-over-longer corruption signature
plus a concurrent-writers stress.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Render the system prompt without activating a project: `project` is now an
optional positional (default None -> project-independent prompt). Drop the
--log-level option / logging.configure call so CLI logging stays off and only
the prompt reaches stdout, and remove two stray debug print()s
(default_modes/base_modes) that leaked onto stdout. IDE autostart is already
disabled here via with_headless_mode_overrides() (it nulls
jetbrains_launch_command). Also drop an accidental unused sqlalchemy import.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* Default is None (behaviour unchanged)
* Override is applied for Claude Code, which does not unpack structured
output, causing the LLM to see unnecessary escapings in returned tool
results #1042
Register the LATEX language (.tex/.bib/.sty/.cls) backed by texlab,
downloaded as a sha256-verified single-binary from GitHub Releases
(v5.25.1) across macOS/Linux/Windows. Document symbols expose the
sectioning hierarchy; definitions/references cover labels and citations.
Includes a smoke-test fixture repo and basic document-symbol tests.
Co-authored-by: KoscheiiB <KoscheiiB@users.noreply.github.com>
A registered project whose root directory was deleted (e.g. a removed git
worktree) would raise FileNotFoundError from RegisteredProject.matches_root_path
(via Path.samefile). Because get_registered_project iterates matches_root_path
over every registered project, one dangling entry aborted activation of all
other, valid projects until an MCP server restart.
matches_root_path now treats a non-existent directory as a non-match instead of
letting the filesystem error propagate.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>