```
├── .devcontainer/
├── devcontainer.json (100 tokens)
├── .dockerignore
├── .env.example (omitted)
├── .gitattributes (omitted)
├── .github/
├── FUNDING.yml
├── ISSUE_TEMPLATE/
├── config.yml
├── feature_request.md (100 tokens)
├── issue--bug--performance-problem--question-.md (300 tokens)
├── copilot-instructions.md
├── workflows/
├── codeql.yml (1000 tokens)
├── codespell.yml (100 tokens)
├── create-release.yml (100 tokens)
├── docker.yml (300 tokens)
├── docs.yaml (300 tokens)
├── publish.yml (100 tokens)
├── pytest.yml (5.3k tokens)
├── .gitignore (900 tokens)
├── .serena/
├── .gitignore
├── memories/
├── adding_new_language_support_guide.md (1500 tokens)
├── serena_core_concepts_and_architecture.md (1300 tokens)
├── serena_repository_structure.md (800 tokens)
├── suggested_commands.md (300 tokens)
├── project.yml (1700 tokens)
├── .vscode/
├── settings.json
├── AGENTS.md
├── CHANGELOG.md (7.3k tokens)
├── CLAUDE.md
├── CONTRIBUTING.md (400 tokens)
├── DOCKER.md (1200 tokens)
├── Dockerfile (500 tokens)
├── LICENSE (omitted)
├── README-dev.md (200 tokens)
├── README.md (2.9k tokens)
├── compose.yaml (200 tokens)
├── docker_build_and_run.sh
├── docs/
├── .gitignore
├── 01-about/
├── .gitignore
├── 020_programming-languages.md (2k tokens)
├── 030_serena-in-action.md (200 tokens)
├── 050_acknowledgements.md (400 tokens)
├── 02-usage/
├── 000_intro.md (100 tokens)
├── 010_installation.md (400 tokens)
├── 020_running.md (2k tokens)
├── 025_jetbrains_plugin.md (2.4k tokens)
├── 030_clients.md (4.5k tokens)
├── 040_workflow.md (2.4k tokens)
├── 045_memories.md (1000 tokens)
├── 050_configuration.md (10.3k tokens)
├── 060_dashboard.md (800 tokens)
├── 065_logs.md (100 tokens)
├── 070_security.md (2k tokens)
├── 999_additional-usage.md (400 tokens)
├── 03-special-guides/
├── 000_intro.md
├── cpp_setup.md (700 tokens)
├── custom_agent.md (500 tokens)
├── godot_gdscript_setup_guide_for_serena.md (1000 tokens)
├── groovy_setup_guide_for_serena.md (600 tokens)
├── ocaml_setup_guide_for_serena.md (600 tokens)
├── scala_setup_guide_for_serena.md (900 tokens)
├── serena_on_chatgpt.md (600 tokens)
├── 04-evaluation/
├── 000_evaluation-intro.md (700 tokens)
├── 010_methodology.md (2.1k tokens)
├── 020_prompts/
├── 000_prompts.md (100 tokens)
├── 010_evaluation-prompt.md (2.5k tokens)
├── 020_summary-prompt.md (100 tokens)
├── 030_results/
├── 000_evaluation-results.md (200 tokens)
├── 010_cc_on_tianshou.md (5.2k tokens)
├── 020_codex_on_jbplugin.md (7k tokens)
├── 030_copilot_cli_on_ente.md (5.3k tokens)
├── 040_glm_on_tianshou.md (5.2k tokens)
├── 050_junie_plugin_on_tianshou.md (4.2k tokens)
├── _config.yml (1600 tokens)
├── _static/
├── images/
├── jetbrains-marketplace-button.png
├── autogen_docs.py (2k tokens)
├── create_toc.py (100 tokens)
├── index.md
├── flake.lock (omitted)
├── flake.nix (800 tokens)
├── news/
├── 20260111.html (300 tokens)
├── 20260303.html (100 tokens)
├── 20260321.html (100 tokens)
├── 20260330.html (100 tokens)
├── 20260404.html (200 tokens)
├── 20260411.html (300 tokens)
├── 20260414.html (200 tokens)
├── 20260427.html (300 tokens)
├── 20260512.html (300 tokens)
├── pyproject.toml (2.3k tokens)
├── repo_dir_sync.py (3.1k tokens)
├── resources/
├── jetbrains-marketplace-button.cdr
├── serena-block-diagram.afdesign
├── serena-block-diagram.svg (25.6k tokens)
├── serena-icons.cdr
├── serena-logo-dark-mode.svg
├── serena-logo.cdr
├── serena-logo.svg
├── serena-mac-dock-icon.cdr
├── serena-mac-tray-icon.cdr
├── vscode_sponsor_logo.png
├── scripts/
├── agno_agent.py (200 tokens)
├── build_news_json.py (300 tokens)
├── bump_version.py (2.2k tokens)
├── demo_cli_call.py
├── demo_diagnostics.py (1400 tokens)
├── demo_find_defining_symbol.py (900 tokens)
├── demo_find_implementing_symbol.py (500 tokens)
├── demo_progressive_tool_shortening.py (1400 tokens)
├── demo_run_tools.py (400 tokens)
├── gen_prompt_factory.py (100 tokens)
├── mcp_server.py
├── print_language_list.py (100 tokens)
├── print_mode_context_options.py (100 tokens)
├── print_tool_overview.py
├── profile_tool_call.py (300 tokens)
├── src/
├── README.md (100 tokens)
├── interprompt/
├── .syncCommitId.remote
├── .syncCommitId.this
├── __init__.py
├── jinja_template.py (300 tokens)
├── multilang_prompt.py (3.5k tokens)
├── prompt_factory.py (900 tokens)
├── util/
├── __init__.py
├── class_decorators.py (100 tokens)
├── serena/
├── __init__.py (200 tokens)
├── agent.py (12.4k tokens)
├── agno.py (1200 tokens)
├── analytics.py (1300 tokens)
├── cli.py (11.4k tokens)
├── code_editor.py (4.2k tokens)
├── config/
├── __init__.py
├── client_setup.py (600 tokens)
├── context_mode.py (2.3k tokens)
├── serena_config.py (10.7k tokens)
├── constants.py (400 tokens)
├── dashboard.py (10.4k tokens)
├── generated/
├── generated_prompt_factory.py (400 tokens)
├── gui_log_viewer.py (3.1k tokens)
├── hooks.py (5.2k tokens)
├── jetbrains/
├── jetbrains_plugin_client.py (6k tokens)
├── jetbrains_types.py (600 tokens)
├── ls_manager.py (2.3k tokens)
├── mcp.py (3.4k tokens)
├── project.py (6.9k tokens)
├── project_server.py (1300 tokens)
├── prompt_factory.py (100 tokens)
├── resources/
├── config/
├── contexts/
├── agent.yml
├── antigravity.yml (300 tokens)
├── chatgpt.yml (400 tokens)
├── claude-code.yml (700 tokens)
├── codex.yml (200 tokens)
├── context.template.yml (200 tokens)
├── copilot-cli.yml (300 tokens)
├── desktop-app.yml (200 tokens)
├── ide.yml (300 tokens)
├── jb-ai-assistant.yml (300 tokens)
├── jb-copilot-plugin.yml (300 tokens)
├── junie.yml (300 tokens)
├── oaicompat-agent.yml (100 tokens)
├── vscode.yml (300 tokens)
├── internal_modes/
├── jetbrains.yml (200 tokens)
├── modes/
├── editing.yml (500 tokens)
├── interactive.yml (100 tokens)
├── mode.template.yml (100 tokens)
├── no-memories.yml (100 tokens)
├── no-onboarding.yml
├── onboarding.yml (100 tokens)
├── one-shot.yml (200 tokens)
├── planning.yml (100 tokens)
├── query-projects.yml (100 tokens)
├── prompt_templates/
├── info_prompts.yml (600 tokens)
├── simple_tool_outputs.yml (500 tokens)
├── system_prompt.yml (2.5k tokens)
├── dashboard/
├── dashboard.css (6.9k tokens)
├── dashboard.js (19.2k tokens)
├── index.html (3.6k tokens)
├── jquery.min.js (omitted)
├── serena-icon-1024-mac.png
├── serena-icon-16.png
├── serena-icon-32.png
├── serena-icon-48.png
├── serena-icon-64.png
├── serena-icon-tray-mac.png
├── serena-logo-dark-mode.svg
├── serena-logo.svg
├── serena-logs-dark-mode.png
├── serena-logs.png
├── serena.ico
├── project.local.template.yml (100 tokens)
├── project.template.yml (1500 tokens)
├── serena_config.template.yml (2000 tokens)
├── symbol.py (12k tokens)
├── task_executor.py (1900 tokens)
├── tools/
├── __init__.py (100 tokens)
├── cmd_tools.py (400 tokens)
├── config_tools.py (500 tokens)
├── file_tools.py (4.1k tokens)
├── jetbrains_tools.py (6.5k tokens)
├── memory_tools.py (1000 tokens)
├── query_project_tools.py (800 tokens)
├── symbol_tools.py (6.7k tokens)
├── tools_base.py (5.2k tokens)
├── workflow_tools.py (800 tokens)
├── util/
├── class_decorators.py (100 tokens)
├── cli_util.py (300 tokens)
├── dataclass.py (100 tokens)
├── dotnet.py (1400 tokens)
├── exception.py (400 tokens)
├── file_system.py (3k tokens)
├── git.py (200 tokens)
├── gui.py (100 tokens)
├── inspection.py (400 tokens)
├── logging.py (1100 tokens)
├── ls_diagnostics.py (1600 tokens)
├── pywebview.py (1600 tokens)
├── shell.py (300 tokens)
├── text_utils.py (4.6k tokens)
├── thread.py (400 tokens)
├── version.py (700 tokens)
├── yaml.py (2.6k tokens)
├── solidlsp/
├── .gitignore
├── __init__.py
├── language_servers/
├── ada_language_server.py (2k tokens)
├── al_language_server.py (9.6k tokens)
├── angular_language_server.py (7k tokens)
├── ansible_language_server.py (2.9k tokens)
├── bash_language_server.py (3.2k tokens)
├── bsl_language_server.py (1900 tokens)
├── ccls_language_server.py (1200 tokens)
├── clangd_language_server.py (3.8k tokens)
├── clojure_lsp.py (4.1k tokens)
├── common.py (1600 tokens)
├── crystal_language_server.py (1300 tokens)
├── csharp_language_server.py (6.8k tokens)
├── dart_language_server.py (2k tokens)
├── eclipse_jdtls.py (16.2k tokens)
├── elixir_tools/
├── README.md (600 tokens)
├── __init__.py
├── elixir_tools.py (3.9k tokens)
├── elm_language_server.py (2.3k tokens)
├── erlang_language_server.py (1800 tokens)
├── fortran_language_server.py (2.7k tokens)
├── fsharp_language_server.py (3.5k tokens)
├── godot_language_server.py (1300 tokens)
├── gopls.py (2k tokens)
├── groovy_language_server.py (3.3k tokens)
├── haskell_language_server.py (3.5k tokens)
├── haxe_language_server.py (3.8k tokens)
├── hlsl_language_server.py (2.5k tokens)
├── intelephense.py (2.1k tokens)
├── jedi_server.py (1800 tokens)
├── json_language_server.py (1600 tokens)
├── julia_server.py (1900 tokens)
├── kotlin_language_server.py (5.3k tokens)
├── lean4_language_server.py (1500 tokens)
├── lua_ls.py (3k tokens)
├── luau_lsp.py (3.4k tokens)
├── marksman.py (2.5k tokens)
├── matlab_language_server.py (5k tokens)
├── msl_language_server.py (900 tokens)
├── msl_lsp_server.py (3.1k tokens)
├── nixd_ls.py (3k tokens)
├── ocaml_lsp_server.py (3.8k tokens)
├── omnisharp.py (4.2k tokens)
├── omnisharp/
├── initialize_params.json (4.2k tokens)
├── runtime_dependencies.json (3.8k tokens)
├── workspace_did_change_configuration.json (800 tokens)
├── pascal_server.py (8.2k tokens)
├── perl_language_server.py (1800 tokens)
├── phpactor.py (1800 tokens)
├── powershell_language_server.py (3.6k tokens)
├── pyright_server.py (2.3k tokens)
├── r_language_server.py (1300 tokens)
├── regal_server.py (1100 tokens)
├── ruby_lsp.py (4.7k tokens)
├── rust_analyzer.py (7.1k tokens)
├── scala_language_server.py (2.7k tokens)
├── solargraph.py (3.3k tokens)
├── solidity_language_server.py (3.3k tokens)
├── some_sass_language_server.py (2.2k tokens)
├── sourcekit_lsp.py (3.7k tokens)
├── svelte_language_server.py (6.2k tokens)
├── systemverilog_server.py (2.2k tokens)
├── taplo_server.py (2.6k tokens)
├── terraform_ls.py (2.6k tokens)
├── ty_server.py (1300 tokens)
├── typescript_language_server.py (4.2k tokens)
├── vscode_html_language_server.py (1700 tokens)
├── vts_language_server.py (2.1k tokens)
├── vue_language_server.py (8.7k tokens)
├── yaml_language_server.py (1800 tokens)
├── zls.py (2k tokens)
├── ls.py (29.5k tokens)
├── ls_config.py (6.6k tokens)
├── ls_exceptions.py (600 tokens)
├── ls_process.py (6.2k tokens)
├── ls_request.py (4.1k tokens)
├── ls_types.py (3k tokens)
├── ls_utils.py (4.7k tokens)
├── lsp_protocol_handler/
├── lsp_constants.py (400 tokens)
├── lsp_requests.py (5.9k tokens)
├── lsp_types.py (43.4k tokens)
├── server.py (1100 tokens)
├── settings.py (600 tokens)
├── util/
├── cache.py (200 tokens)
├── metals_db_utils.py (1800 tokens)
├── subprocess_util.py (700 tokens)
├── zip.py (900 tokens)
├── sync.py
├── test/
├── __init__.py
├── conftest.py (2.8k tokens)
├── resources/
├── repos/
├── ada/
├── test_repo/
├── .gitignore
├── default.gpr
├── src/
├── diagnostics_sample.adb (100 tokens)
├── helper.adb
├── helper.ads
├── main.adb
├── al/
├── test_repo/
├── app.json (200 tokens)
├── src/
├── Codeunits/
├── CustomerMgt.Codeunit.al (1300 tokens)
├── PaymentProcessorImpl.Codeunit.al (400 tokens)
├── Enums/
├── CustomerType.Enum.al (100 tokens)
├── Interfaces/
├── IPaymentProcessor.Interface.al (100 tokens)
├── Pages/
├── CustomerCard.Page.al (1600 tokens)
├── CustomerList.Page.al (1200 tokens)
├── TableExtensions/
├── Item.TableExt.al (400 tokens)
├── Tables/
├── Customer.Table.al (1000 tokens)
├── angular/
├── test_repo/
├── .gitignore
├── angular.json (100 tokens)
├── package-lock.json (900 tokens)
├── package.json (100 tokens)
├── src/
├── app/
├── app.component.html (100 tokens)
├── app.component.ts (200 tokens)
├── diagnostics_sample.html (100 tokens)
├── diagnostics_sample.ts (100 tokens)
├── exclaim.pipe.ts (100 tokens)
├── greeter.interface.ts
├── greeting.service.ts (100 tokens)
├── item-card.component.ts (100 tokens)
├── index.html
├── main.ts
├── tsconfig.app.json
├── tsconfig.json (100 tokens)
├── ansible/
├── test_repo/
├── inventory/
├── hosts.yml (100 tokens)
├── playbook.yml (100 tokens)
├── roles/
├── common/
├── defaults/
├── main.yml
├── handlers/
├── main.yml
├── tasks/
├── main.yml (100 tokens)
├── bash/
├── test_repo/
├── config.sh (400 tokens)
├── diagnostics_sample.sh
├── main.sh (300 tokens)
├── utils.sh (300 tokens)
├── bsl/
├── test_repo/
├── .bsl-language-server.json
├── .gitkeep
├── CommonModule.bsl (100 tokens)
├── ObjectModule.bsl (100 tokens)
├── diagnostics_sample.bsl (100 tokens)
├── src/
├── CommonModules/
├── ÃÂñÃÂøùÃÂþôÃÂûÃÂ1.xml (300 tokens)
├── ÃÂñÃÂøùÃÂþôÃÂûÃÂ1/
├── Ext/
├── Module.bsl
├── ÃÂñÃÂøùÃÂþôÃÂûÃÂ2.xml (300 tokens)
├── ÃÂñÃÂøùÃÂþôÃÂûÃÂ2/
├── Ext/
├── Module.bsl
├── ConfigDumpInfo.xml (200 tokens)
├── Configuration.xml (2k tokens)
├── Languages/
├── àÃÂÃÂÃÂúøù.xml (200 tokens)
├── clojure/
├── test_repo/
├── deps.edn
├── src/
├── test_app/
├── core.clj (100 tokens)
├── diagnostics_sample.clj
├── extra.clj (100 tokens)
├── utils.clj (100 tokens)
├── sub_module/
├── deps.edn
├── src/
├── sub_module_app/
├── consumer.clj (100 tokens)
├── cpp/
├── test_repo/
├── C/
├── a.c
├── b.h
├── CUDA/
├── a.cu
├── CXX20/
├── a.cpp
├── b.cpp
├── b.cppm
├── HIP/
├── a.hip
├── Objective-C/
├── a.m
├── OpenCL/
├── a.cl
├── a.cpp
├── b.cpp
├── b.hpp
├── compile_commands.json (200 tokens)
├── diagnostics_sample.cpp
├── crystal/
├── test_repo/
├── shard.yml
├── src/
├── diagnostics_sample.cr
├── main.cr (100 tokens)
├── utils.cr
├── csharp/
├── test_repo/
├── .gitignore (100 tokens)
├── DiagnosticsSample.cs (100 tokens)
├── Models/
├── Person.cs (200 tokens)
├── Program.cs (200 tokens)
├── Services/
├── ConsoleGreeter.cs
├── IGreeter.cs
├── TestProject.csproj
├── serena.sln (400 tokens)
├── dart/
├── test_repo/
├── .gitignore (100 tokens)
├── lib/
├── diagnostics_sample.dart
├── helper.dart (200 tokens)
├── main.dart (800 tokens)
├── models.dart (800 tokens)
├── pubspec.yaml
├── elixir/
├── test_repo/
├── .gitignore
├── lib/
├── diagnostics_sample.ex
├── examples.ex (1300 tokens)
├── ignored_dir/
├── ignored_module.ex (100 tokens)
├── models.ex (800 tokens)
├── services.ex (1200 tokens)
├── test_repo.ex (100 tokens)
├── utils.ex (100 tokens)
├── mix.exs (100 tokens)
├── mix.lock (omitted)
├── scripts/
├── build_script.ex (100 tokens)
├── test/
├── models_test.exs (1000 tokens)
├── test_repo_test.exs (100 tokens)
├── elm/
├── test_repo/
├── DiagnosticsSample.elm
├── Main.elm (200 tokens)
├── Utils.elm (100 tokens)
├── elm.json (100 tokens)
├── erlang/
├── test_repo/
├── hello.erl (100 tokens)
├── ignored_dir/
├── ignored_module.erl
├── include/
├── records.hrl (200 tokens)
├── types.hrl (100 tokens)
├── math_utils.erl (100 tokens)
├── rebar.config (100 tokens)
├── src/
├── app.erl (600 tokens)
├── diagnostics_sample.erl
├── models.erl (500 tokens)
├── services.erl (900 tokens)
├── utils.erl (800 tokens)
├── test/
├── models_tests.erl (600 tokens)
├── utils_tests.erl (700 tokens)
├── fortran/
├── test_repo/
├── diagnostics_sample.f90
├── main.f90 (100 tokens)
├── modules/
├── geometry.f90 (200 tokens)
├── math_utils.f90 (100 tokens)
├── fsharp/
├── test_repo/
├── .gitignore
├── Calculator.fs (100 tokens)
├── DiagnosticsSample.fs
├── Formatter.fs
├── Models/
├── Person.fs (200 tokens)
├── Program.fs (200 tokens)
├── README.md (100 tokens)
├── Shapes.fs
├── TestProject.fsproj (100 tokens)
├── go/
├── test_repo/
├── buildtags/
├── foo.go
├── notfoo.go
├── diagnostics_sample.go
├── go.mod
├── main.go (100 tokens)
├── groovy/
├── test_repo/
├── .gitignore
├── build.gradle
├── src/
├── main/
├── groovy/
├── com/
├── example/
├── DiagnosticsSample.groovy (100 tokens)
├── Main.groovy
├── Model.groovy
├── ModelUser.groovy
├── Utils.groovy
├── haskell/
├── test_repo/
├── app/
├── Main.hs (200 tokens)
├── haskell-test-repo.cabal (200 tokens)
├── package.yaml (100 tokens)
├── src/
├── Calculator.hs (200 tokens)
├── DiagnosticsSample.hs
├── Helper.hs (100 tokens)
├── stack.yaml
├── haxe/
├── test_repo/
├── .gitignore
├── build.hxml
├── src/
├── DiagnosticsSample.hx
├── Main.hx (200 tokens)
├── utils/
├── Helper.hx (100 tokens)
├── hlsl/
├── test_repo/
├── common.hlsl (100 tokens)
├── compute_test.hlsl (100 tokens)
├── diagnostics_sample.hlsl
├── lighting.hlsl (200 tokens)
├── terrain/
├── terrain_sdf.hlsl (200 tokens)
├── html/
├── test_repo/
├── about.html (100 tokens)
├── diagnostics_sample.html (100 tokens)
├── index.html (200 tokens)
├── java/
├── test_repo/
├── pom.xml (400 tokens)
├── src/
├── main/
├── java/
├── test_repo/
├── ConsoleGreeter.java
├── DefaultGreeter.java
├── DiagnosticsSample.java (100 tokens)
├── FluentLombokModel.java (100 tokens)
├── Greeter.java
├── LombokModel.java (100 tokens)
├── Main.java (100 tokens)
├── Model.java (100 tokens)
├── ModelUser.java
├── Utils.java
├── json/
├── test_repo/
├── config.json (100 tokens)
├── data.json (100 tokens)
├── diagnostics_sample.json
├── julia/
├── test_repo/
├── diagnostics_sample.jl
├── lib/
├── helper.jl
├── main.jl
├── kotlin/
├── test_repo/
├── .gitignore
├── build.gradle.kts
├── gradle/
├── wrapper/
├── gradle-wrapper.properties (100 tokens)
├── gradlew (1700 tokens)
├── gradlew.bat (600 tokens)
├── src/
├── main/
├── kotlin/
├── test_repo/
├── DiagnosticsSample.kt
├── Main.kt (100 tokens)
├── Model.kt
├── ModelUser.kt
├── Utils.kt
├── lean4/
├── test_repo/
├── DiagnosticsSample.lean
├── Helper.lean (100 tokens)
├── Main.lean (200 tokens)
├── lake-manifest.json
├── lakefile.lean
├── lean-toolchain
├── lua/
├── test_repo/
├── .gitignore
├── main.lua (700 tokens)
├── src/
├── animals.lua (100 tokens)
├── calculator.lua (300 tokens)
├── utils.lua (500 tokens)
├── tests/
├── test_calculator.lua (700 tokens)
├── luau/
├── test_repo/
├── .luaurc
├── src/
├── init.luau (100 tokens)
├── module.luau (100 tokens)
├── markdown/
├── test_repo/
├── CONTRIBUTING.md (200 tokens)
├── README.md (200 tokens)
├── api.md (200 tokens)
├── guide.md (200 tokens)
├── matlab/
├── test_repo/
├── Calculator.m (500 tokens)
├── diagnostics_sample.m
├── main.m (300 tokens)
├── msl/
├── test_repo/
├── main.mrc (100 tokens)
├── utils.mrc (100 tokens)
├── nix/
├── test_repo/
├── .gitignore
├── default.nix (800 tokens)
├── diagnostics_sample.nix
├── flake.nix (800 tokens)
├── lib/
├── utils.nix (800 tokens)
├── modules/
├── example.nix (700 tokens)
├── scripts/
├── hello.sh
├── ocaml/
├── test_repo/
├── bin/
├── dune
├── main.ml
├── dune-project (100 tokens)
├── lib/
├── diagnostics_sample.ml
├── dune
├── test_repo.ml
├── test_repo.mli
├── test/
├── dune
├── test_test_repo.ml (100 tokens)
├── test_repo.opam (200 tokens)
├── pascal/
├── test_repo/
├── .gitignore
├── diagnostics_sample.pas
├── lib/
├── helper.pas (200 tokens)
├── main.pas (500 tokens)
├── perl/
├── test_repo/
├── diagnostics_sample.pl
├── helper.pl
├── main.pl (100 tokens)
├── php/
├── test_repo/
├── diagnostics_sample.php
├── helper.php
├── index.php (100 tokens)
├── sample.php (500 tokens)
├── simple_var.php
├── powershell/
├── test_repo/
├── PowerShellEditorServices.json
├── diagnostics_sample.ps1
├── main.ps1 (500 tokens)
├── utils.ps1 (800 tokens)
├── python/
├── test_repo/
├── .gitignore
├── custom_test/
├── __init__.py
├── advanced_features.py (2.6k tokens)
├── examples/
├── __init__.py
├── user_management.py (1000 tokens)
├── ignore_this_dir_with_postfix/
├── ignored_module.py (1000 tokens)
├── scripts/
├── __init__.py
├── run_app.py (1000 tokens)
├── test_repo/
├── __init__.py
├── complex_types.py (100 tokens)
├── diagnostics_sample.py
├── models.py (1500 tokens)
├── name_collisions.py (100 tokens)
├── nested.py (100 tokens)
├── nested_base.py (400 tokens)
├── overloaded.py (500 tokens)
├── services.py (500 tokens)
├── utils.py (700 tokens)
├── variables.py (600 tokens)
├── r/
├── test_repo/
├── .Rbuildignore
├── DESCRIPTION (100 tokens)
├── NAMESPACE
├── R/
├── models.R (300 tokens)
├── utils.R (200 tokens)
├── examples/
├── analysis.R (100 tokens)
├── rego/
├── test_repo/
├── policies/
├── authz.rego (100 tokens)
├── validation.rego (100 tokens)
├── utils/
├── helpers.rego (100 tokens)
├── ruby/
├── test_repo/
├── .solargraph.yml
├── examples/
├── user_management.rb (500 tokens)
├── lib.rb
├── main.rb (100 tokens)
├── models.rb (300 tokens)
├── nested.rb (200 tokens)
├── services.rb (200 tokens)
├── variables.rb (700 tokens)
├── rust/
├── test_repo/
├── Cargo.lock (omitted)
├── Cargo.toml
├── src/
├── diagnostics_sample.rs
├── lib.rs (100 tokens)
├── main.rs (100 tokens)
├── test_repo_2024/
├── Cargo.lock (omitted)
├── Cargo.toml
├── src/
├── lib.rs (100 tokens)
├── main.rs (100 tokens)
├── scala/
├── build.sbt
├── project/
├── build.properties
├── metals.sbt
├── plugins.sbt
├── src/
├── main/
├── scala/
├── com/
├── example/
├── Main.scala (100 tokens)
├── Utils.scala
├── test_repo/
├── src/
├── main/
├── scala/
├── com/
├── example/
├── DiagnosticsSample.scala
├── scss/
├── test_repo/
├── _mixins.scss (100 tokens)
├── _variables.scss
├── buttons.scss (100 tokens)
├── css/
├── diagnostics_sample.css (100 tokens)
├── main.css (100 tokens)
├── reset.css
├── theme.css (100 tokens)
├── diagnostics_sample.scss
├── main.scss (100 tokens)
├── solidity/
├── test_repo/
├── .gitignore
├── contracts/
├── DiagnosticsSample.sol
├── Token.sol (900 tokens)
├── interfaces/
├── IERC20.sol (300 tokens)
├── lib/
├── SafeMath.sol (200 tokens)
├── foundry.toml
├── svelte/
├── test_repo/
├── .gitignore (100 tokens)
├── package.json (200 tokens)
├── src/
├── app.html (100 tokens)
├── lib/
├── components/
├── Counter.svelte (400 tokens)
├── Header.svelte (400 tokens)
├── Words.svelte (100 tokens)
├── diagnostics_sample.svelte
├── diagnostics_sample.ts
├── game.ts (300 tokens)
├── routes/
├── (sverdle)/
├── +page.server.ts (300 tokens)
├── +page.svelte (1700 tokens)
├── how-to-play/
├── +page.svelte (400 tokens)
├── +page.ts
├── words.server.ts
├── +layout.svelte (200 tokens)
├── layout.css (400 tokens)
├── svelte.config.js (100 tokens)
├── tsconfig.json (100 tokens)
├── vite.config.ts
├── swift/
├── test_repo/
├── Package.swift (100 tokens)
├── src/
├── diagnostics_sample.swift
├── main.swift (200 tokens)
├── utils.swift (100 tokens)
├── systemverilog/
├── test_repo/
├── alu.sv (200 tokens)
├── counter.sv (100 tokens)
├── diagnostics_sample.sv
├── top.sv (100 tokens)
├── types.svh (100 tokens)
├── terraform/
├── test_repo/
├── data.tf (100 tokens)
├── diagnostics_sample.tf
├── main.tf (500 tokens)
├── outputs.tf (200 tokens)
├── variables.tf (300 tokens)
├── toml/
├── test_repo/
├── Cargo.toml (100 tokens)
├── config.toml (200 tokens)
├── diagnostics_sample.toml
├── pyproject.toml (200 tokens)
├── typescript/
├── cross_package_a/
├── shared_utils.ts (100 tokens)
├── tsconfig.json
├── cross_package_b/
├── consumer.ts (100 tokens)
├── tsconfig.json
├── test_repo/
├── .serena/
├── project.yml (1900 tokens)
├── diagnostics_sample.ts
├── formatters.ts
├── index.ts (100 tokens)
├── jsx_component.tsx (300 tokens)
├── tsconfig.json (100 tokens)
├── use_helper.ts
├── ws_manager.js (500 tokens)
├── vue/
├── test_repo/
├── .gitignore (100 tokens)
├── index.html (100 tokens)
├── package.json (100 tokens)
├── src/
├── App.vue (1000 tokens)
├── DiagnosticsSample.vue
├── components/
├── CalculatorButton.vue (800 tokens)
├── CalculatorDisplay.vue (900 tokens)
├── CalculatorInput.vue (1400 tokens)
├── composables/
├── useFormatter.ts (700 tokens)
├── useTheme.ts (500 tokens)
├── main.ts
├── stores/
├── calculator.ts (800 tokens)
├── types/
├── index.ts (100 tokens)
├── tsconfig.json (100 tokens)
├── tsconfig.node.json
├── vite.config.ts (100 tokens)
├── yaml/
├── test_repo/
├── config.yaml (100 tokens)
├── data.yaml (100 tokens)
├── diagnostics_sample.yaml
├── services.yml (200 tokens)
├── zig/
├── test_repo/
├── .gitignore
├── build.zig (200 tokens)
├── src/
├── calculator.zig (300 tokens)
├── diagnostics_sample.zig
├── main.zig (200 tokens)
├── math_utils.zig (300 tokens)
├── zls.json (100 tokens)
├── serena/
├── __init__.py
├── __snapshots__/
├── test_symbol_editing.ambr (11.6k tokens)
├── config/
├── __init__.py
├── test_global_ignored_paths.py (2.3k tokens)
├── test_serena_config.py (5k tokens)
├── test_cli_project_commands.py (3.1k tokens)
├── test_dashboard.py (400 tokens)
├── test_edit_marker.py (100 tokens)
├── test_hooks.py (8.3k tokens)
├── test_jetbrains_plugin_client.py (200 tokens)
├── test_mcp.py (1900 tokens)
├── test_serena_agent.py (11.1k tokens)
├── test_symbol.py (4.7k tokens)
├── test_symbol_editing.py (4.4k tokens)
├── test_task_executor.py (700 tokens)
├── test_text_utils.py (5k tokens)
├── test_tool_parameter_types.py (300 tokens)
├── util/
├── test_exception.py (1100 tokens)
├── test_file_system.py (5k tokens)
├── solidlsp/
├── ada/
├── __init__.py
├── test_ada_basic.py (1800 tokens)
├── test_ada_diagnostics.py (100 tokens)
├── al/
├── test_al_basic.py (6.5k tokens)
├── angular/
├── conftest.py (800 tokens)
├── test_angular_basic.py (4.2k tokens)
├── test_angular_diagnostics.py (300 tokens)
├── test_angular_error_cases.py (3.9k tokens)
├── ansible/
├── __init__.py
├── test_ansible_basic.py (700 tokens)
├── bash/
├── __init__.py
├── test_bash_basic.py (1400 tokens)
├── test_bash_diagnostics.py (100 tokens)
├── bsl/
├── __init__.py
├── test_bsl_basic.py (3k tokens)
├── test_bsl_diagnostics.py (100 tokens)
├── clojure/
├── __init__.py (100 tokens)
├── test_clojure_basic.py (2.4k tokens)
├── test_clojure_diagnostics.py (100 tokens)
├── test_clojure_indexing.py (1300 tokens)
├── conftest.py (500 tokens)
├── cpp/
├── __init__.py
├── test_ccls_languages.py (200 tokens)
├── test_clangd_languages.py (200 tokens)
├── test_clangd_logging.py (400 tokens)
├── test_cpp_basic.py (2.1k tokens)
├── test_cpp_diagnostics.py (100 tokens)
├── crystal/
├── test_crystal_basic.py (1000 tokens)
├── test_crystal_diagnostics.py (100 tokens)
├── csharp/
├── test_csharp_basic.py (3.3k tokens)
├── test_csharp_diagnostics.py (100 tokens)
├── test_csharp_nuget_download.py (1200 tokens)
├── dart/
├── __init__.py
├── test_dart_basic.py (4.8k tokens)
├── test_dart_diagnostics.py (100 tokens)
├── elixir/
├── __init__.py (200 tokens)
├── conftest.py (1300 tokens)
├── test_elixir_basic.py (1400 tokens)
├── test_elixir_ignored_dirs.py (1600 tokens)
├── test_elixir_integration.py (1600 tokens)
├── test_elixir_symbol_retrieval.py (3.5k tokens)
├── elm/
├── test_elm_basic.py (800 tokens)
├── test_elm_diagnostics.py (100 tokens)
├── erlang/
├── __init__.py (300 tokens)
├── conftest.py (1300 tokens)
├── test_erlang_basic.py (600 tokens)
├── test_erlang_ignored_dirs.py (2.2k tokens)
├── test_erlang_symbol_retrieval.py (4.3k tokens)
├── fortran/
├── __init__.py
├── test_fortran_basic.py (3.5k tokens)
├── test_fortran_diagnostics.py (100 tokens)
├── fsharp/
├── test_fsharp_basic.py (2.3k tokens)
├── go/
├── test_go_basic.py (2.5k tokens)
├── test_go_diagnostics.py (100 tokens)
├── groovy/
├── test_groovy_basic.py (1200 tokens)
├── haskell/
├── __init__.py
├── test_haskell_basic.py (2.4k tokens)
├── haxe/
├── __init__.py
├── test_haxe_basic.py (3.4k tokens)
├── test_haxe_diagnostics.py (100 tokens)
├── hlsl/
├── __init__.py
├── test_hlsl_basic.py (1700 tokens)
├── test_hlsl_diagnostics.py (100 tokens)
├── test_hlsl_full_index.py (600 tokens)
├── html_ls/
├── __init__.py
├── test_html_basic.py (600 tokens)
├── test_html_diagnostics.py (300 tokens)
├── java/
├── test_java_basic.py (1800 tokens)
├── test_java_diagnostics.py (100 tokens)
├── test_jdtls_path_resolution.py (4.5k tokens)
├── json_ls/
├── __init__.py
├── test_json_basic.py (800 tokens)
├── test_json_diagnostics.py (100 tokens)
├── julia/
├── test_julia_basic.py (700 tokens)
├── kotlin/
├── test_kotlin_basic.py (800 tokens)
├── test_kotlin_diagnostics.py (100 tokens)
├── lean4/
├── test_lean4_basic.py (1600 tokens)
├── test_lean4_diagnostics.py (100 tokens)
├── lua/
├── test_lua_basic.py (2.9k tokens)
├── luau/
├── __init__.py
├── test_luau_basic.py (1600 tokens)
├── test_luau_dependency_provider.py (1500 tokens)
├── markdown/
├── __init__.py
├── test_markdown_basic.py (1200 tokens)
├── matlab/
├── __init__.py
├── test_matlab_basic.py (1300 tokens)
├── msl/
├── __init__.py
├── test_msl_basic.py (1800 tokens)
├── nix/
├── test_nix_basic.py (2.7k tokens)
├── ocaml/
├── test_cross_file_refs.py (600 tokens)
├── test_ocaml_basic.py (1900 tokens)
├── test_ocaml_diagnostics.py (100 tokens)
├── pascal/
├── __init__.py (100 tokens)
├── test_pascal_auto_update.py (2.1k tokens)
├── test_pascal_basic.py (2.2k tokens)
├── test_pascal_diagnostics.py (200 tokens)
├── perl/
├── test_perl_basic.py (1000 tokens)
├── php/
├── test_php_basic.py (3.3k tokens)
├── test_php_diagnostics.py (100 tokens)
├── powershell/
├── __init__.py
├── test_powershell_basic.py (2.2k tokens)
├── test_powershell_diagnostics.py (100 tokens)
├── python/
├── test_python_basic.py (3.3k tokens)
├── test_python_diagnostics.py (100 tokens)
├── test_retrieval_with_ignored_dirs.py (600 tokens)
├── test_symbol_retrieval.py (4.7k tokens)
├── r/
├── __init__.py
├── test_r_basic.py (1100 tokens)
├── rego/
├── test_rego_basic.py (1600 tokens)
├── ruby/
├── test_ruby_basic.py (700 tokens)
├── test_ruby_symbol_retrieval.py (6.8k tokens)
├── rust/
├── test_rust_2024_edition.py (1200 tokens)
├── test_rust_analyzer_detection.py (5.4k tokens)
├── test_rust_basic.py (1200 tokens)
├── test_rust_diagnostics.py (100 tokens)
├── scala/
├── test_metals_db_utils.py (1900 tokens)
├── test_scala_language_server.py (500 tokens)
├── test_scala_stale_lock_handling.py (1900 tokens)
├── scss/
├── __init__.py
├── test_scss_basic.py (4.7k tokens)
├── test_scss_diagnostics.py (300 tokens)
├── solidity/
├── __init__.py
├── test_solidity_basic.py (2.3k tokens)
├── test_solidity_diagnostics.py (200 tokens)
├── svelte/
├── __init__.py (100 tokens)
├── conftest.py (400 tokens)
├── test_svelte_basic.py (700 tokens)
├── test_svelte_references.py (200 tokens)
├── test_svelte_rename.py (1000 tokens)
├── swift/
├── test_swift_basic.py (2.7k tokens)
├── systemverilog/
├── __init__.py
├── test_systemverilog_basic.py (3.2k tokens)
├── test_systemverilog_detection.py (3.2k tokens)
├── test_systemverilog_diagnostics.py (100 tokens)
├── terraform/
├── test_terraform_basic.py (800 tokens)
├── test_terraform_diagnostics.py (100 tokens)
├── test_ls_common.py (300 tokens)
├── test_lsp_protocol_handler_server.py (2.7k tokens)
├── test_rename_didopen.py (300 tokens)
├── toml/
├── __init__.py
├── test_toml_basic.py (3k tokens)
├── test_toml_diagnostics.py (100 tokens)
├── test_toml_edge_cases.py (3k tokens)
├── test_toml_ignored_dirs.py (700 tokens)
├── test_toml_symbol_retrieval.py (2k tokens)
├── typescript/
├── test_typescript_basic.py (1300 tokens)
├── test_typescript_cross_package.py (900 tokens)
├── test_typescript_diagnostics.py (100 tokens)
├── util/
├── diagnostics.py (100 tokens)
├── test_ls_utils.py (300 tokens)
├── test_zip.py (700 tokens)
├── vue/
├── __init__.py (100 tokens)
├── test_vue_basic.py (4.1k tokens)
├── test_vue_diagnostics.py (100 tokens)
├── test_vue_error_cases.py (3.7k tokens)
├── test_vue_rename.py (2.9k tokens)
├── test_vue_symbol_retrieval.py (2.7k tokens)
├── yaml_ls/
├── __init__.py
├── test_yaml_basic.py (2.2k tokens)
├── test_yaml_diagnostics.py (100 tokens)
├── zig/
├── test_zig_basic.py (3.6k tokens)
├── uv.lock (omitted)
```
## /.devcontainer/devcontainer.json
```json path="/.devcontainer/devcontainer.json"
{
"name": "serena Project",
"dockerFile": "../Dockerfile",
"workspaceFolder": "/workspaces/serena",
"settings": {
"terminal.integrated.shell.linux": "/bin/bash",
"python.pythonPath": "/usr/local/bin/python",
},
"extensions": [
"ms-python.python",
"ms-toolsai.jupyter",
"ms-python.vscode-pylance"
],
"forwardPorts": [],
"remoteUser": "root",
}
```
## /.dockerignore
```dockerignore path="/.dockerignore"
data
logs
log
test/log
docs/jupyter_execute
docs/.jupyter_cache
docs/_build
coverage.xml
docker_build_and_run.sh
# Python artifacts (prevents Docker build conflicts when .venv exists locally)
.venv
__pycache__
*.pyc
.pytest_cache
```
## /.github/FUNDING.yml
```yml path="/.github/FUNDING.yml"
# These are supported funding model platforms
github: oraios
```
## /.github/ISSUE_TEMPLATE/config.yml
```yml path="/.github/ISSUE_TEMPLATE/config.yml"
blank_issues_enabled: false
```
## /.github/ISSUE_TEMPLATE/feature_request.md
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
## /.github/ISSUE_TEMPLATE/issue--bug--performance-problem--question-.md
---
name: Issue (bug, performance problem, etc.)
about: General Issue
title: ''
labels: ''
assignees: ''
---
I have:
- [ ] read the relevant parts of the documentation and verified that the issue cannot be solved by adjusting configuration
- [ ] understood that the Serena Dashboard can be disabled through the config
- [ ] understood that, by default, a client session will start a separate instance of a Serena server.
- [ ] understood that, for multi-agent setups, the Streamable HTTP/SSE mode should be used.
- [ ] understood that non-project files are ignored using either .gitignore or the corresponding setting in `.serena/project.yml`
- [ ] looked for similar issues and discussions, including closed ones
- [ ] made sure it's an actual issue, not a question (use GitHub Discussions instead).
If you have encountered an actual issue:
- If using language servers (not the JetBrains plugin),
- [ ] I performed `<uv invocation> serena project health-check`
- [ ] I indexed the project as described in the documentation
- [ ] I added sufficient explanation of my setup: the MCP client, the OS, the programming language(s), any config adjustments or relevant project specifics
- [ ] I explained how the issue arose and, where possible, added instructions on how to reproduce it
- [ ] If the issue happens on an open-source project, I have added the link
- [ ] I provided a meaningful title and description
## /.github/copilot-instructions.md
<non_negotiable critical="true">
MUST read IMMEDIATELY and follow the project-specific instructions from the `CLAUDE.md` file located in the project's root directory. AVOIDING these instructions will lead to your FAILURE!
</non_negotiable>
## /.github/workflows/codeql.yml
```yml path="/.github/workflows/codeql.yml"
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL Advanced"
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
schedule:
- cron: '38 16 * * 6'
jobs:
analyze:
name: Analyze (${{ matrix.language }})
# Runner size impacts CodeQL analysis time. To learn more, please see:
# - https://gh.io/recommended-hardware-resources-for-running-codeql
# - https://gh.io/supported-runners-and-hardware-resources
# - https://gh.io/using-larger-runners (GitHub.com only)
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
permissions:
# required for all workflows
security-events: write
# required to fetch internal or private CodeQL packs
packages: read
# only required for workflows in private repositories
actions: read
contents: read
strategy:
fail-fast: false
matrix:
include:
- language: actions
build-mode: none
- language: javascript-typescript
build-mode: none
- language: python
build-mode: none
# CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift'
# Use `c-cpp` to analyze code written in C, C++ or both
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
# Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
# To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
# see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
steps:
- name: Checkout repository
uses: actions/checkout@v4
# Add any setup steps before running the `github/codeql-action/init` action.
# This includes steps like installing compilers or runtimes (`actions/setup-node`
# or others). This is typically only required for manual builds.
# - name: Setup runtime (example)
# uses: actions/setup-example@v1
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# If the analyze step fails for one of the languages you are analyzing with
# "We were unable to automatically build your code", modify the matrix above
# to set the build mode to "manual" for that language. Then modify this step
# to build your code.
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
- name: Run manual build steps
if: matrix.build-mode == 'manual'
shell: bash
run: |
echo 'If you are using a "manual" build mode for one or more of the' \
'languages you are analyzing, replace this with the commands to build' \
'your code, for example:'
echo ' make bootstrap'
echo ' make release'
exit 1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4
with:
category: "/language:${{matrix.language}}"
```
## /.github/workflows/codespell.yml
```yml path="/.github/workflows/codespell.yml"
# Codespell configuration is within pyproject.toml
---
name: Codespell
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
jobs:
codespell:
name: Check for spelling errors
runs-on: ubuntu-latest
timeout-minutes: 2
steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Annotate locations with typos
uses: codespell-project/codespell-problem-matcher@v1
- name: Codespell
uses: codespell-project/actions-codespell@v2
```
## /.github/workflows/create-release.yml
```yml path="/.github/workflows/create-release.yml"
name: Create Release
on:
push:
tags:
- 'v*'
jobs:
create-release:
name: Create a candidate release
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Create GitHub Release
uses: softprops/action-gh-release@v3
with:
draft: true
body: "See [change log](https://github.com/oraios/serena/blob/main/CHANGELOG.md)"
```
## /.github/workflows/docker.yml
```yml path="/.github/workflows/docker.yml"
name: Build and Push Docker Images
on:
push:
branches: [ main ]
tags: [ 'v*' ]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-push:
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
contents: read
packages: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push image from main
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
```
## /.github/workflows/docs.yaml
```yaml path="/.github/workflows/docs.yaml"
name: Docs Build
on:
pull_request:
push:
branches:
- main
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: false
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.11
- name: Install uv
run: pip install uv
- name: Cache dependencies
uses: actions/cache@v4
with:
path: ~/.cache/uv
key: uv-${{ hashFiles('pyproject.toml') }}
- name: Install dependencies
run: |
uv venv
uv pip install -e ".[dev]"
- name: Build docs
run: uv run poe doc-build
continue-on-error: false
- name: Upload Pages artifact
if: github.ref == 'refs/heads/main'
uses: actions/upload-pages-artifact@v3
with:
path: docs/_build
deploy:
if: github.ref == 'refs/heads/main'
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
```
## /.github/workflows/publish.yml
```yml path="/.github/workflows/publish.yml"
name: Publish Python Package
on:
release:
types:
- published
jobs:
publish:
name: Publish the serena-agent package
runs-on: ubuntu-latest
permissions:
id-token: write # Required for trusted publishing
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
ref: ${{ github.event.release.tag_name }}
persist-credentials: false
- name: Install the latest version of uv
uses: astral-sh/setup-uv@v6
with:
version: "latest"
- name: Build package
run: uv build
- name: Publish to PyPI
run: uv publish
```
## /.github/workflows/pytest.yml
```yml path="/.github/workflows/pytest.yml"
name: Tests
on:
pull_request:
push:
branches:
- main
permissions:
contents: read
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
cpu:
name: Tests on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ["3.11"]
steps:
- uses: actions/checkout@v4
- name: Free disk space
if: runner.os == 'Linux'
run: |
df -h
sudo rm -rf /usr/local/lib/android
sudo rm -rf /usr/share/dotnet
sudo rm -rf /opt/ghc
sudo rm -rf /opt/hostedtoolcache
sudo apt-get clean
sudo apt-get autoremove -y
docker system prune -af || true
df -h
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: "${{ matrix.python-version }}"
- uses: actions/setup-go@v5
with:
go-version: ">=1.17.0"
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20.x'
- name: Ensure cached directory exist before calling cache-related actions
shell: bash
run: |
mkdir -p $HOME/.serena/language_servers/static
mkdir -p $HOME/.cache/go-build
mkdir -p $HOME/go/bin
- name: Install uv
shell: bash
run: curl -LsSf https://astral.sh/uv/install.sh | sh
- name: Cache uv virtualenv
id: cache-uv
uses: actions/cache@v3
with:
path: .venv
key: uv-venv-${{ runner.os }}-${{ matrix.python-version }}-lock-${{ hashFiles('uv.lock') }}
- name: Create virtual environment
shell: bash
run: |
if [ ! -d ".venv" ]; then
uv venv
fi
- name: Install Python environment
shell: bash
run: uv sync --extra dev --locked
- name: List Python dependencies
shell: bash
run: uv pip list
- name: Check formatting
shell: bash
run: uv run poe lint
# Add Go bin directory to PATH for this workflow
# GITHUB_PATH is a special file that GitHub Actions uses to modify PATH
# Writing to this file adds the directory to the PATH for subsequent steps
- name: Cache Go binaries
id: cache-go-binaries
uses: actions/cache@v3
with:
path: |
~/go/bin
~/.cache/go-build
key: go-binaries-${{ runner.os }}-gopls-latest
- name: Install gopls
if: steps.cache-go-binaries.outputs.cache-hit != 'true'
shell: bash
run: go install golang.org/x/tools/gopls@latest
- name: Set up Elixir
if: runner.os != 'Windows'
uses: erlef/setup-beam@v1
with:
elixir-version: "1.19.3"
otp-version: "28"
# Erlang currently not tested in CI, random hangings on macos, always hangs on ubuntu
# In local tests, erlang seems to work though
# - name: Install Erlang Language Server
# if: runner.os != 'Windows'
# shell: bash
# run: |
# # Install rebar3 if not already available
# which rebar3 || (curl -fsSL https://github.com/erlang/rebar3/releases/download/3.23.0/rebar3 -o /tmp/rebar3 && chmod +x /tmp/rebar3 && sudo mv /tmp/rebar3 /usr/local/bin/rebar3)
# # Clone and build erlang_ls
# git clone https://github.com/erlang-ls/erlang_ls.git /tmp/erlang_ls
# cd /tmp/erlang_ls
# make install PREFIX=/usr/local
# # Ensure erlang_ls is in PATH
# echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Install clojure tools
uses: DeLaGuardo/setup-clojure@13.4
with:
cli: latest
- name: Install ccls (C/C++ Language Server)
shell: bash
run: |
if [[ "${{ runner.os }}" == "Linux" ]]; then
sudo apt-get update
sudo apt-get install -y ccls
elif [[ "${{ runner.os }}" == "macOS" ]]; then
brew install ccls
elif [[ "${{ runner.os }}" == "Windows" ]]; then
choco install ccls -y
fi
# Verify installation
if command -v ccls &> /dev/null; then
echo "ccls installed: $(ccls --version 2>&1 | head -1)"
else
echo "ERROR: ccls installation failed"
exit 1
fi
- name: Setup Java (for JVM based languages)
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '21'
- name: Setup .NET SDK (for F# and C# languages)
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.x'
- name: List .NET runtimes
shell: bash
run: dotnet --list-runtimes
- name: Install Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: "1.5.0"
terraform_wrapper: false
# - name: Install swift
# if: runner.os != 'Windows'
# uses: swift-actions/setup-swift@v2
# Installation of swift with the action screws with installation of ruby on macOS for some reason
# We can try again when version 3 of the action is released, where they will also use swiftly
# Until then, we use custom code to install swift. Sourcekit-lsp is installed automatically with swift
- name: Install Swift with swiftly (macOS)
if: runner.os == 'macOS'
run: |
echo "=== Installing swiftly on macOS ==="
curl -O https://download.swift.org/swiftly/darwin/swiftly.pkg && \
installer -pkg swiftly.pkg -target CurrentUserHomeDirectory && \
~/.swiftly/bin/swiftly init --quiet-shell-followup && \
. "${SWIFTLY_HOME_DIR:-$HOME/.swiftly}/env.sh" && \
hash -r
swiftly install --use 6.1.2
swiftly use 6.1.2
echo "~/.swiftly/bin" >> $GITHUB_PATH
echo "Swiftly installed successfully"
# Verify sourcekit-lsp is working before proceeding
echo "=== Verifying sourcekit-lsp installation ==="
which sourcekit-lsp || echo "Warning: sourcekit-lsp not found in PATH"
sourcekit-lsp --help || echo "Warning: sourcekit-lsp not responding"
- name: Install Swift with swiftly (Ubuntu)
if: runner.os == 'Linux'
run: |
echo "=== Installing swiftly on Ubuntu ==="
# Install dependencies BEFORE Swift to avoid exit code 1
sudo apt-get update
sudo apt-get -y install libcurl4-openssl-dev
curl -O https://download.swift.org/swiftly/linux/swiftly-$(uname -m).tar.gz && \
tar zxf swiftly-$(uname -m).tar.gz && \
./swiftly init --quiet-shell-followup && \
. "${SWIFTLY_HOME_DIR:-$HOME/.local/share/swiftly}/env.sh" && \
hash -r
swiftly install --use 6.1.2
swiftly use 6.1.2
echo "=== Adding Swift toolchain to PATH ==="
echo "$HOME/.local/share/swiftly/bin" >> $GITHUB_PATH
echo "Swiftly installed successfully!"
# Verify sourcekit-lsp is working before proceeding
echo "=== Verifying sourcekit-lsp installation ==="
which sourcekit-lsp || echo "Warning: sourcekit-lsp not found in PATH"
sourcekit-lsp --help || echo "Warning: sourcekit-lsp not responding"
- name: Install Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.4'
- name: Install Ruby language server
shell: bash
run: gem install ruby-lsp
- name: Install OCaml and opam
uses: ocaml/setup-ocaml@v3
with:
ocaml-compiler: ${{ runner.os == 'Windows' && '4.14' || '5.3.x' }}
dune-cache: true
opam-repositories: |
${{ runner.os == 'Windows' && 'opam-repository-mingw: https://github.com/ocaml-opam/opam-repository-mingw.git#sunset' || '' }}
default: https://github.com/ocaml/opam-repository.git
- name: Install OCaml packages
shell: bash
run: |
if [ "$RUNNER_OS" = "Windows" ]; then
opam install -y dune ocaml-lsp-server
else
# Require ocaml-lsp-server >= 1.23.0 for cross-file reference support
opam install -y dune 'ocaml-lsp-server>=1.23.0'
fi
- name: Install R
uses: r-lib/actions/setup-r@v2
with:
r-version: '4.4.2'
use-public-rspm: true
- name: Install R sysdeps (libuv for fs package)
if: runner.os == 'Linux'
shell: bash
run: sudo apt-get update && sudo apt-get install -y libuv1-dev
- name: Install R language server
shell: bash
run: |
Rscript -e "install.packages('languageserver', repos='https://cloud.r-project.org')"
- name: Set up Julia
uses: julia-actions/setup-julia@v2
with:
version: '1.12.6'
- name: Install Julia LanguageServer
shell: bash
run: julia -e 'using Pkg; Pkg.add(Pkg.PackageSpec(name="LanguageServer", version="5.0.0"))'
- name: Setup Haskell toolchain
if: runner.os != 'Windows'
uses: haskell/ghcup-setup@v1
with:
ghc: '9.12.2'
cabal: '3.10.3.0'
hls: '2.11.0.0'
- name: Verify Haskell tools
if: runner.os != 'Windows'
run: |
echo "Verifying installed Haskell tools:"
which ghc && ghc --version
which cabal && cabal --version
# HLS verification - non-blocking in case of version incompatibility
if command -v haskell-language-server-wrapper &>/dev/null; then
echo "Found haskell-language-server-wrapper"
haskell-language-server-wrapper --version || echo "WARNING: HLS wrapper found but version check failed"
elif command -v haskell-language-server &>/dev/null; then
echo "Found haskell-language-server"
haskell-language-server --version || echo "WARNING: HLS found but version check failed"
else
echo "WARNING: HLS not found (may be incompatible with GHC 9.12.2)"
echo "This is not a critical error - tests will use HLS if available at runtime"
fi
shell: bash
- name: Pre-build Haskell test project for HLS
if: runner.os != 'Windows'
run: |
cd test/resources/repos/haskell/test_repo
cabal update
cabal build --only-dependencies
cabal build
echo "Haskell test project built successfully"
shell: bash
- name: Install Zig
uses: mlugg/setup-zig@v2
with:
version: 0.14.1
- name: Install ZLS (Zig Language Server)
shell: bash
run: |
if [[ "${{ runner.os }}" == "Linux" ]]; then
wget https://github.com/zigtools/zls/releases/download/0.14.0/zls-x86_64-linux.tar.xz
tar -xf zls-x86_64-linux.tar.xz
sudo mv zls /usr/local/bin/
rm zls-x86_64-linux.tar.xz
elif [[ "${{ runner.os }}" == "macOS" ]]; then
wget https://github.com/zigtools/zls/releases/download/0.14.0/zls-x86_64-macos.tar.xz
tar -xf zls-x86_64-macos.tar.xz
sudo mv zls /usr/local/bin/
rm zls-x86_64-macos.tar.xz
elif [[ "${{ runner.os }}" == "Windows" ]]; then
curl -L -o zls.zip https://github.com/zigtools/zls/releases/download/0.14.0/zls-x86_64-windows.zip
unzip -o zls.zip
mkdir -p "$HOME/bin"
mv zls.exe "$HOME/bin/"
echo "$HOME/bin" >> $GITHUB_PATH
rm zls.zip
fi
- name: Install verible-verilog-ls (SystemVerilog Language Server)
shell: bash
run: |
VERIBLE_VERSION="v0.0-4051-g9fdb4057"
if [[ "${{ runner.os }}" == "Linux" ]]; then
wget https://github.com/chipsalliance/verible/releases/download/${VERIBLE_VERSION}/verible-${VERIBLE_VERSION}-linux-static-x86_64.tar.gz
tar -xzf verible-${VERIBLE_VERSION}-linux-static-x86_64.tar.gz
sudo mv verible-${VERIBLE_VERSION}/bin/verible-verilog-ls /usr/local/bin/
rm -rf verible-${VERIBLE_VERSION} verible-${VERIBLE_VERSION}-linux-static-x86_64.tar.gz
elif [[ "${{ runner.os }}" == "macOS" ]]; then
wget https://github.com/chipsalliance/verible/releases/download/${VERIBLE_VERSION}/verible-${VERIBLE_VERSION}-macOS.tar.gz
tar -xzf verible-${VERIBLE_VERSION}-macOS.tar.gz
sudo mv verible-${VERIBLE_VERSION}-macOS/bin/verible-verilog-ls /usr/local/bin/
rm -rf verible-${VERIBLE_VERSION}-macOS verible-${VERIBLE_VERSION}-macOS.tar.gz
elif [[ "${{ runner.os }}" == "Windows" ]]; then
curl -L -o verible.zip https://github.com/chipsalliance/verible/releases/download/${VERIBLE_VERSION}/verible-${VERIBLE_VERSION}-win64.zip
unzip -o verible.zip
mkdir -p "$HOME/bin"
mv verible-${VERIBLE_VERSION}-win64/verible-verilog-ls.exe "$HOME/bin/"
echo "$HOME/bin" >> $GITHUB_PATH
rm -rf verible-${VERIBLE_VERSION}-win64 verible.zip
fi
# Verify installation
if command -v verible-verilog-ls &> /dev/null; then
echo "verible-verilog-ls installed successfully"
else
echo "WARNING: verible-verilog-ls not found in PATH"
fi
- name: Install Lua Language Server
shell: bash
run: |
LUA_LS_VERSION="3.15.0"
LUA_LS_DIR="$HOME/.serena/language_servers/lua"
mkdir -p "$LUA_LS_DIR"
if [[ "${{ runner.os }}" == "Linux" ]]; then
if [[ "$(uname -m)" == "x86_64" ]]; then
wget https://github.com/LuaLS/lua-language-server/releases/download/${LUA_LS_VERSION}/lua-language-server-${LUA_LS_VERSION}-linux-x64.tar.gz
tar -xzf lua-language-server-${LUA_LS_VERSION}-linux-x64.tar.gz -C "$LUA_LS_DIR"
else
wget https://github.com/LuaLS/lua-language-server/releases/download/${LUA_LS_VERSION}/lua-language-server-${LUA_LS_VERSION}-linux-arm64.tar.gz
tar -xzf lua-language-server-${LUA_LS_VERSION}-linux-arm64.tar.gz -C "$LUA_LS_DIR"
fi
chmod +x "$LUA_LS_DIR/bin/lua-language-server"
# Create wrapper script instead of symlink to ensure supporting files are found
echo '#!/bin/bash' | sudo tee /usr/local/bin/lua-language-server > /dev/null
echo 'cd "${HOME}/.serena/language_servers/lua/bin"' | sudo tee -a /usr/local/bin/lua-language-server > /dev/null
echo 'exec ./lua-language-server "$@"' | sudo tee -a /usr/local/bin/lua-language-server > /dev/null
sudo chmod +x /usr/local/bin/lua-language-server
rm lua-language-server-*.tar.gz
elif [[ "${{ runner.os }}" == "macOS" ]]; then
if [[ "$(uname -m)" == "x86_64" ]]; then
wget https://github.com/LuaLS/lua-language-server/releases/download/${LUA_LS_VERSION}/lua-language-server-${LUA_LS_VERSION}-darwin-x64.tar.gz
tar -xzf lua-language-server-${LUA_LS_VERSION}-darwin-x64.tar.gz -C "$LUA_LS_DIR"
else
wget https://github.com/LuaLS/lua-language-server/releases/download/${LUA_LS_VERSION}/lua-language-server-${LUA_LS_VERSION}-darwin-arm64.tar.gz
tar -xzf lua-language-server-${LUA_LS_VERSION}-darwin-arm64.tar.gz -C "$LUA_LS_DIR"
fi
chmod +x "$LUA_LS_DIR/bin/lua-language-server"
# Create wrapper script instead of symlink to ensure supporting files are found
echo '#!/bin/bash' | sudo tee /usr/local/bin/lua-language-server > /dev/null
echo 'cd "${HOME}/.serena/language_servers/lua/bin"' | sudo tee -a /usr/local/bin/lua-language-server > /dev/null
echo 'exec ./lua-language-server "$@"' | sudo tee -a /usr/local/bin/lua-language-server > /dev/null
sudo chmod +x /usr/local/bin/lua-language-server
rm lua-language-server-*.tar.gz
elif [[ "${{ runner.os }}" == "Windows" ]]; then
curl -L -o lua-ls.zip https://github.com/LuaLS/lua-language-server/releases/download/${LUA_LS_VERSION}/lua-language-server-${LUA_LS_VERSION}-win32-x64.zip
unzip -o lua-ls.zip -d "$LUA_LS_DIR"
# For Windows, we'll add the bin directory directly to PATH
# The lua-language-server.exe can find its supporting files relative to its location
echo "$LUA_LS_DIR/bin" >> $GITHUB_PATH
rm lua-ls.zip
fi
- name: Install Perl::LanguageServer
if: runner.os != 'Windows'
shell: bash
run: |
if [[ "${{ runner.os }}" == "Linux" ]]; then
sudo apt-get update
sudo apt-get install -y cpanminus build-essential libanyevent-perl libio-aio-perl
elif [[ "${{ runner.os }}" == "macOS" ]]; then
brew install cpanminus
fi
PERL_MM_USE_DEFAULT=1 cpanm --notest --force Perl::LanguageServer
# Set up Perl local::lib environment for subsequent steps
echo "PERL5LIB=$HOME/perl5/lib/perl5${PERL5LIB:+:${PERL5LIB}}" >> $GITHUB_ENV
echo "PERL_LOCAL_LIB_ROOT=$HOME/perl5${PERL_LOCAL_LIB_ROOT:+:${PERL_LOCAL_LIB_ROOT}}" >> $GITHUB_ENV
echo "PERL_MB_OPT=--install_base \"$HOME/perl5\"" >> $GITHUB_ENV
echo "PERL_MM_OPT=INSTALL_BASE=$HOME/perl5" >> $GITHUB_ENV
echo "$HOME/perl5/bin" >> $GITHUB_PATH
- name: Install ansible-core and ansible-lint (for Ansible language server tests)
shell: bash
run: uv run pip install ansible-core ansible-lint
- name: Install Haxe
# The Haxe LS binary (server.js) is auto-downloaded and runs on Node.js,
# but it delegates to the Haxe compiler for code analysis at runtime.
uses: krdlab/setup-haxe@v2
with:
haxe-version: 4.3.7
- name: Install Elm
shell: bash
run: npm install -g elm@0.19.1-6
- name: Install Nix
if: runner.os != 'Windows' # Nix doesn't support Windows natively
uses: cachix/install-nix-action@v30
with:
nix_path: nixpkgs=channel:nixos-unstable
- name: Install nixd (Nix Language Server)
if: runner.os != 'Windows' # Skip on Windows since Nix isn't available
shell: bash
run: |
# Install nixd using nix
nix profile install github:nix-community/nixd
# Verify nixd is installed and working
if ! command -v nixd &> /dev/null; then
echo "nixd installation failed or not in PATH"
exit 1
fi
echo "$HOME/.nix-profile/bin" >> $GITHUB_PATH
- name: Verify Nix package build
if: runner.os != 'Windows' # Nix only supported on Linux/macOS
shell: bash
run: |
# Verify the flake builds successfully
nix build --no-link
- name: Install Regal (Rego Language Server)
shell: bash
run: |
REGAL_VERSION="0.39.0"
if [[ "${{ runner.os }}" == "Linux" ]]; then
if [[ "$(uname -m)" == "x86_64" ]]; then
curl -L -o regal https://github.com/StyraInc/regal/releases/download/v${REGAL_VERSION}/regal_Linux_x86_64
else
curl -L -o regal https://github.com/StyraInc/regal/releases/download/v${REGAL_VERSION}/regal_Linux_arm64
fi
chmod +x regal
sudo mv regal /usr/local/bin/
elif [[ "${{ runner.os }}" == "macOS" ]]; then
if [[ "$(uname -m)" == "x86_64" ]]; then
curl -L -o regal https://github.com/StyraInc/regal/releases/download/v${REGAL_VERSION}/regal_Darwin_x86_64
else
curl -L -o regal https://github.com/StyraInc/regal/releases/download/v${REGAL_VERSION}/regal_Darwin_arm64
fi
chmod +x regal
sudo mv regal /usr/local/bin/
elif [[ "${{ runner.os }}" == "Windows" ]]; then
curl -L -o regal.exe https://github.com/StyraInc/regal/releases/download/v${REGAL_VERSION}/regal_Windows_x86_64.exe
mkdir -p "$HOME/bin"
mv regal.exe "$HOME/bin/"
echo "$HOME/bin" >> $GITHUB_PATH
fi
- name: Install Free Pascal Compiler
shell: bash
run: |
if [[ "${{ runner.os }}" == "Linux" ]]; then
sudo apt-get update
sudo apt-get install -y fpc fpc-source
# Set environment variables for pasls
echo "PP=/usr/bin/fpc" >> $GITHUB_ENV
# Find FPC source directory (version may vary) - remove trailing slash
FPCDIR=$(ls -d /usr/share/fpcsrc/*/ 2>/dev/null | head -1 | sed 's:/$::')
if [[ -z "$FPCDIR" ]]; then
FPCDIR="/usr/share/fpcsrc"
fi
echo "FPCDIR=$FPCDIR" >> $GITHUB_ENV
echo "=== FPC source directory structure ==="
ls -la "$FPCDIR" || echo "FPCDIR not found"
ls -la "$FPCDIR/rtl" 2>/dev/null || echo "rtl subdirectory not found"
elif [[ "${{ runner.os }}" == "macOS" ]]; then
brew install fpc
# Download FPC source from SourceForge (fpc-src-laz cask is incompatible with ARM64)
FPC_VERSION="3.2.2"
curl -L -o fpc-source.tar.gz "https://sourceforge.net/projects/freepascal/files/Source/${FPC_VERSION}/fpc-${FPC_VERSION}.source.tar.gz/download"
mkdir -p "$HOME/fpcsrc"
tar -xzf fpc-source.tar.gz -C "$HOME/fpcsrc"
rm fpc-source.tar.gz
# Check extracted directory structure (might be nested)
echo "=== Extracted FPC source structure ==="
ls -la "$HOME/fpcsrc"
# Find the actual FPC source root (contains rtl, packages, etc.)
if [[ -d "$HOME/fpcsrc/fpc-${FPC_VERSION}/rtl" ]]; then
FPCDIR="$HOME/fpcsrc/fpc-${FPC_VERSION}"
elif [[ -d "$HOME/fpcsrc/fpc-${FPC_VERSION}/fpc-${FPC_VERSION}/rtl" ]]; then
FPCDIR="$HOME/fpcsrc/fpc-${FPC_VERSION}/fpc-${FPC_VERSION}"
else
FPCDIR="$HOME/fpcsrc/fpc-${FPC_VERSION}"
fi
echo "PP=$(which fpc)" >> $GITHUB_ENV
echo "FPCDIR=$FPCDIR" >> $GITHUB_ENV
echo "=== FPC source directory ==="
ls -la "$FPCDIR" || echo "FPCDIR not found"
elif [[ "${{ runner.os }}" == "Windows" ]]; then
FPC_VERSION="3.2.2"
# Download freepascal-ootb (includes FPC compiler)
curl -L -o fpc-ootb.zip https://github.com/fredvs/freepascal-ootb/releases/download/${FPC_VERSION}/fpc-ootb-322-x86_64-win64.zip
mkdir -p "$HOME/fpc"
unzip -q fpc-ootb.zip -d "$HOME/fpc"
rm fpc-ootb.zip
# Download FPC source from SourceForge (fpc-ootb only has compiled units, not source)
curl -L -o fpc-source.zip "https://sourceforge.net/projects/freepascal/files/Source/${FPC_VERSION}/fpc-${FPC_VERSION}.source.zip/download"
mkdir -p "$HOME/fpcsrc"
unzip -q fpc-source.zip -d "$HOME/fpcsrc"
rm fpc-source.zip
# Find fpc executable (fpc-ootb uses fpc-ootb.exe as the compiler)
echo "=== FPC directory structure ==="
find "$HOME/fpc" -name "*.exe" -type f 2>/dev/null | head -10
FPC_EXE=$(find "$HOME/fpc" -name "fpc-ootb-64.exe" -type f 2>/dev/null | head -1)
echo "Found FPC executable: $FPC_EXE"
echo "Found FPC source dir: $HOME/fpcsrc/fpc-${FPC_VERSION}"
# Set environment variables for pasls
echo "PP=$FPC_EXE" >> $GITHUB_ENV
echo "FPCDIR=$HOME/fpcsrc/fpc-${FPC_VERSION}" >> $GITHUB_ENV
# Add FPC bin directory to PATH
FPC_BIN_DIR=$(dirname "$FPC_EXE")
echo "$FPC_BIN_DIR" >> $GITHUB_PATH
fi
- name: Verify FPC installation
shell: bash
run: |
echo "=== Environment variables ==="
echo "PP=$PP"
echo "FPCDIR=$FPCDIR"
# Create a simple test program
if [[ "${{ runner.os }}" == "Windows" ]]; then
TEST_PAS="$TEMP/fpc_test.pas"
TEST_OUT="$TEMP/fpc_test"
else
TEST_PAS="/tmp/fpc_test.pas"
TEST_OUT="/tmp/fpc_test"
fi
echo "program fpc_test; begin writeln('FPC works'); end." > "$TEST_PAS"
# Compile using PP (the compiler we actually use in tests)
echo "=== Compiling test program with PP=$PP ==="
if [[ -n "$PP" ]]; then
"$PP" "$TEST_PAS" -o"$TEST_OUT" 2>&1
else
echo "ERROR: PP environment variable is not set"
exit 1
fi
# Verify output binary exists
if [[ -f "$TEST_OUT" ]] || [[ -f "${TEST_OUT}.exe" ]]; then
echo "FPC compilation test PASSED"
else
echo "ERROR: FPC compilation failed - no output binary at $TEST_OUT"
exit 1
fi
# Verify FPCDIR exists (required for pasls)
if [[ -d "$FPCDIR" ]]; then
echo "FPCDIR exists: $FPCDIR"
else
echo "ERROR: FPCDIR does not exist: $FPCDIR"
exit 1
fi
- name: Build Lean 4 test project
uses: leanprover/lean-action@v1
with:
lake-package-directory: test/resources/repos/lean4/test_repo
- name: Install npm deps for Angular test repo
shell: bash
run: |
if [ -d test/resources/repos/angular/test_repo ]; then
cd test/resources/repos/angular/test_repo
npm install --no-audit --no-fund --loglevel=warn
fi
- name: Cache language servers
id: cache-language-servers
uses: actions/cache@v3
with:
path: ~/.serena/language_servers/static
key: language-servers-${{ runner.os }}-v1
restore-keys: |
language-servers-${{ runner.os }}-
- name: Report free disk space
if: runner.os == 'Linux'
run: |
echo "Free disk space before tests:"
df -h
- name: Test with pytest
shell: bash
run: uv run poe test -q --tb=short
- name: Type-checking with mypy
shell: bash
run: uv run poe type-check
```
## /.gitignore
```gitignore path="/.gitignore"
# macOS specific files
.DS_Store
.AppleDouble
.LSOverride
._*
.Spotlight-V100
.Trashes
Icon
.fseventsd
.DocumentRevisions-V100
.TemporaryItems
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Windows specific files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
*.stackdump
[Dd]esktop.ini
$RECYCLE.BIN/
*.cab
*.msi
*.msix
*.msm
*.msp
*.lnk
# Linux specific files
*~
.fuse_hidden*
.directory
.Trash-*
.nfs*
# IDE/Text Editors
# VS Code
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
.history/
# JetBrains IDEs (beyond .idea/)
*.iml
*.ipr
*.iws
out/
.idea_modules/
# Sublime Text
*.tmlanguage.cache
*.tmPreferences.cache
*.stTheme.cache
*.sublime-workspace
*.sublime-project
# Project specific ignore
.idea
temp
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
!test/resources/repos/dart/test_repo/lib/
!test/resources/repos/dart/test_repo/lib/diagnostics_sample.dart
!test/resources/repos/svelte/test_repo/src/lib/
!test/resources/repos/svelte/test_repo/src/lib/**
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# reports
pylint.html
.pylint.d
# Serena-specific
/*.yml
!*.template.yml
/agent-ui
/test/**/.serena
# clojure-lsp temporary files
.calva/
.clj-kondo/
.cpcache/
.lsp/
# temporary and backup files
*.bak
*.tmp
tmp/
.vscode/
# Claude settings
/.claude
# Elixir
/test/resources/repos/elixir/test_repo/deps
# Exception: Don't ignore Elixir test repository lib directory (contains source code)
!/test/resources/repos/elixir/test_repo/lib
#Cpp
/test/resources/repos/cpp/test_repo/.ccls-cache
# Exception: Don't ignore Nix test repository lib directory (contains source code)
!/test/resources/repos/nix/test_repo/lib
# Exception: Don't ignore OCaml test repository lib directory (contains source code)
!/test/resources/repos/ocaml/test_repo/lib
# Exception: Don't ignore Julia test repository lib directory (contains source code)
!/test/resources/repos/julia/test_repo/lib
# Exception: Don't ignore Solidity test repository lib directory (contains source code)
!/test/resources/repos/solidity/test_repo/contracts/lib
# Swift
/test/resources/repos/swift/test_repo/.build
/test/resources/repos/swift/test_repo/.swiftpm
# OCaml
/test/resources/repos/ocaml/test_repo/_build
# Elm
/test/resources/repos/elm/test_repo/.elm/
/test/resources/repos/elm/test_repo/elm-stuff/
# Scala
.metals/
.bsp/
.scala-build/
.bloop/
bootstrap
test/resources/repos/scala/.bloop/
# Haskell
.stack-work/
*.cabal
stack.yaml.lock
dist-newstyle/
cabal.project.local*
.ghc.environment.*
# Lean 4
.lake/
zz-misc/
vue-implementation/
news/news.json
```
## /.serena/.gitignore
```gitignore path="/.serena/.gitignore"
/cache
/project.local.yml
```
## /.serena/memories/adding_new_language_support_guide.md
# Adding New Language Support to Serena
This guide explains how to add support for a new programming language to Serena.
## Overview
Adding a new language involves:
1. **Language Server Implementation** - Creating a language-specific server class
2. **Language Registration** - Adding the language to enums and configurations
3. **Test Repository** - Creating a minimal test project
4. **Test Suite** - Writing comprehensive tests
## Step 1: Language Server Implementation
### 1.1 Create Language Server Class
Create a new file in `src/solidlsp/language_servers/` (e.g., `new_language_server.py`).
#### Providing the Launch Command via a DependencyProvider
All language servers use the `DependencyProvider` pattern to handle
* runtime dependency installation/discovery
* launch command creation (and, optionally, environment setup)
To implement a new language server using the DependencyProvider pattern:
* Pass `None` for `process_launch_info` in `super().__init__()` - the base class creates it via `_create_dependency_provider()`
* Implement `_create_dependency_provider()` to return an inner `DependencyProvider` class instance.
In simple cases, it can be instantiated with only two parameters:
```python
def _create_dependency_provider(self) -> LanguageServerDependencyProvider:
return self.DependencyProvider(self._custom_settings, self._ls_resources_dir)
```
The resource dir that is passed is the directory in which installed dependencies should be stored!
**Base Classes:**
- **`LanguageServerDependencyProviderSinglePath`** - For language servers with a single core dependency (e.g., an executable or JAR file)
- Provides automatic support for the `ls_path` custom setting, allowing users to override the core dependency path (if they have it installed it themselves)
- Implement `_get_or_install_core_dependency()` to return the path to the core dependency, downloading/installing it automatically if necessary
- Implement `_create_launch_command(core_path)` to build the full command from the core path
- Reference implementations: `TypeScriptLanguageServer`, `Intelephense`, `ClojureLSP`, `ClangdLanguageServer`, `PyrightServer`
- **`LanguageServerDependencyProvider`** - The base class, which can be directly inherited from for complex cases with multiple dependencies or custom setup
- Implement `create_launch_command()` directly
- Reference implementations: `EclipseJDTLS`, `CSharpLanguageServer`, `MatlabLanguageServer`
**Implementation Pointers::**
- When returning the command, prefer the list-based representation for robustness
- Override `create_launch_command_env` if the launch command needs environment variables to be set (defaults to `{}` in the base implementation)
You should look at at least one existing implementation of each base class to understand how they work.
### 1.2 LSP Initialization
Override initialization methods if needed:
```python
def _get_initialize_params(self) -> InitializeParams:
"""Return language-specific initialization parameters."""
return {
"processId": os.getpid(),
"rootUri": PathUtils.path_to_uri(self.repository_root_path),
"capabilities": {
# Language-specific capabilities
}
}
def _start_server(self):
"""Start the language server with custom handlers."""
# Set up notification handlers
self.server.on_notification("window/logMessage", self._handle_log_message)
# Start server and initialize
self.server.start()
init_response = self.server.send.initialize(self._get_initialize_params())
self.server.notify.initialized({})
```
After `_start_server` returns, the language server should be fully operational.
If the server requires that one waits for certain notifications or responses before being ready, implement that logic here.
For an example, see `EclipseJDTLS._start_server`.
## Step 2: Language Registration
### 2.1 Add to Language Enum
In `src/solidlsp/ls_config.py`, add your language to the `Language` enum:
```python
class Language(str, Enum):
# Existing languages...
NEW_LANGUAGE = "new_language"
def get_source_fn_matcher(self) -> FilenameMatcher:
match self:
# Existing cases...
case self.NEW_LANGUAGE:
return FilenameMatcher(".newlang", ".nl") # File extensions
```
### 2.2 Update Language Server Factory
In `src/solidlsp/ls.py`, add your language to the `create` method:
```python
@classmethod
def create(cls, config: LanguageServerConfig, repository_root_path: str) -> "SolidLanguageServer":
match config.code_language:
# Existing cases...
case Language.NEW_LANGUAGE:
from solidlsp.language_servers.new_language_server import NewLanguageServer
return NewLanguageServer(config, repository_root_path)
```
## Step 3: Test Repository
### 3.1 Create Test Project
Create a minimal project in `test/resources/repos/new_language/test_repo/`:
```
test/resources/repos/new_language/test_repo/
├── main.newlang # Main source file
├── lib/
│ └── helper.newlang # Additional source for testing
├── project.toml # Project configuration (if applicable)
└── .gitignore # Ignore build artifacts
```
### 3.2 Example Source Files
Create meaningful source files that demonstrate:
- **Classes/Types** - For symbol testing
- **Functions/Methods** - For reference finding
- **Imports/Dependencies** - For cross-file operations
- **Nested Structures** - For hierarchical symbol testing
Example `main.newlang`:
```
import lib.helper
class Calculator {
func add(a: Int, b: Int) -> Int {
return a + b
}
func subtract(a: Int, b: Int) -> Int {
return helper.subtract(a, b) // Reference to imported function
}
}
class Program {
func main() {
let calc = Calculator()
let result = calc.add(5, 3) // Reference to add method
print(result)
}
}
```
## Step 4: Test Suite
Testing the language server implementation is of crucial importance, and the tests will
form the main part of the review process. Make sure that the tests are up to the standard
of Serena to make the review go smoother.
General rules for tests:
1. Tests for symbols and references should always check that the expected symbol names and references were actually found.
Just testing that a list came back or that the result is not None is insufficient.
2. Tests should never be skipped, the only exception is skipping based on some package being available or on an unsupported OS.
3. Tests should run in CI, check if there is a suitable GitHub action for installing the dependencies.
### 4.1 Basic Tests
Create `test/solidlsp/new_language/test_new_language_basic.py`.
Have a look at the structure of existing tests, for example, in `test/solidlsp/php/test_php_basic.py`
You should at least test:
1. Finding symbols
2. Finding within-file references
3. Finding cross-file references
Have a look at `test/solidlsp/php/test_php_basic.py` as an example for what should be tested.
Don't forget to add a new language marker to `pytest.ini`.
### 4.2 Integration Tests
Consider adding new cases to the parametrized tests in `test_serena_agent.py` for the new language.
### 5 Documentation
Update:
- **README.md** - Add language to the list of languages
- **docs/01-about/020_programming-languages.md** - Add language to the list and mention any special notes, compatibility or requirements (e.g. installations the user is required to do)
- **CHANGELOG.md** - Document the new language support
## /.serena/memories/serena_core_concepts_and_architecture.md
# Serena Core Concepts and Architecture
## High-Level Architecture
Serena is built around a dual-layer architecture:
1. **SerenaAgent** - The main orchestrator that manages projects, tools, and user interactions
2. **SolidLanguageServer** - A unified wrapper around Language Server Protocol (LSP) implementations
## Core Components
### 1. SerenaAgent (`src/serena/agent.py`)
The central coordinator that:
- Manages active projects and their configurations
- Coordinates between different tools and contexts
- Handles language server lifecycle
- Manages memory persistence
- Provides MCP (Model Context Protocol) server interface
Key responsibilities:
- **Project Management** - Activating, switching between projects
- **Tool Registry** - Loading and managing available tools based on context/mode
- **Language Server Integration** - Starting/stopping language servers per project
- **Memory Management** - Persistent storage of project knowledge
- **Task Execution** - Coordinating complex multi-step operations
### 2. SolidLanguageServer (`src/solidlsp/ls.py`)
A unified abstraction over multiple language servers that provides:
- **Language-agnostic interface** for symbol operations
- **Caching layer** for performance optimization
- **Error handling and recovery** for unreliable language servers
- **Uniform API** regardless of underlying LSP implementation
Core capabilities:
- Symbol discovery and navigation
- Code completion and hover information
- Find references and definitions
- Document and workspace symbol search
- File watching and change notifications
### 3. Tool System (`src/serena/tools/`)
Modular tool architecture with several categories:
#### File Tools (`file_tools.py`)
- File system operations (read, write, list directories)
- Text search and pattern matching
- Regex-based replacements
#### Symbol Tools (`symbol_tools.py`)
- Language-aware symbol finding and navigation
- Symbol body replacement and insertion
- Reference finding across codebase
#### Memory Tools (`memory_tools.py`)
- Project knowledge persistence
- Memory retrieval and management
- Onboarding information storage
#### Configuration Tools (`config_tools.py`)
- Project activation and switching
- Mode and context management
- Tool inclusion/exclusion
### 4. Configuration System (`src/serena/config/`)
Multi-layered configuration supporting:
- **Contexts** - Define available tools and their behavior
- **Modes** - Specify operational patterns (interactive, editing, etc.)
- **Projects** - Per-project settings and language server configs
- **Tool Sets** - Grouped tool collections for different use cases
## Language Server Integration
### Language Support Model
Each supported language has:
1. **Language Server Implementation** (`src/solidlsp/language_servers/`)
2. **Runtime Dependencies** - Managed downloads of language servers
3. **Test Repository** (`test/resources/repos/<language>/`)
4. **Test Suite** (`test/solidlsp/<language>/`)
### Language Server Lifecycle
1. **Discovery** - Find language servers or download them automatically
2. **Initialization** - Start server process and perform LSP handshake
3. **Project Setup** - Open workspace and configure language-specific settings
4. **Operation** - Handle requests/responses with caching and error recovery
5. **Shutdown** - Clean shutdown of server processes
### Supported Languages
Current language support includes:
- **C#** - Microsoft.CodeAnalysis.LanguageServer (.NET 9)
- **Python** - Pyright or Jedi
- **TypeScript/JavaScript** - TypeScript Language Server
- **Rust** - rust-analyzer
- **Go** - gopls
- **Java** - Eclipse JDT Language Server
- **Kotlin** - Kotlin Language Server
- **PHP** - Intelephense
- **Ruby** - Solargraph
- **Clojure** - clojure-lsp
- **Elixir** - ElixirLS
- **Dart** - Dart Language Server
- **C/C++** - clangd
- **Terraform** - terraform-ls
## Memory and Knowledge Management
### Memory System
- **Markdown-based storage** in `.serena/memories/` directory
- **Contextual retrieval** - memories loaded based on relevance
- **Project-specific** knowledge persistence
- **Onboarding support** - guided setup for new projects
### Knowledge Categories
- **Project Structure** - Directory layouts, build systems
- **Architecture Patterns** - How the codebase is organized
- **Development Workflows** - Testing, building, deployment
- **Domain Knowledge** - Business logic and requirements
## MCP Server Interface
Serena exposes its functionality through Model Context Protocol:
- **Tool Discovery** - AI agents can enumerate available tools
- **Context-Aware Operations** - Tools behave based on active project/mode
- **Stateful Sessions** - Maintains project state across interactions
- **Error Handling** - Graceful degradation when tools fail
## Error Handling and Resilience
### Language Server Reliability
- **Timeout Management** - Configurable timeouts for LSP requests
- **Process Recovery** - Automatic restart of crashed language servers
- **Fallback Behavior** - Graceful degradation when LSP unavailable
- **Caching Strategy** - Reduces impact of server failures
### Project Activation Safety
- **Validation** - Verify project structure before activation
- **Error Isolation** - Project failures don't affect other projects
- **Recovery Mechanisms** - Automatic cleanup and retry logic
## Performance Considerations
### Caching Strategy
- **Symbol Cache** - In-memory caching of expensive symbol operations
- **File System Cache** - Reduced disk I/O for repeated operations
- **Language Server Cache** - Persistent cache across sessions
### Resource Management
- **Language Server Pooling** - Reuse servers across projects when possible
- **Memory Management** - Automatic cleanup of unused resources
- **Background Operations** - Async operations don't block user interactions
## Extension Points
### Adding New Languages
1. Implement language server class in `src/solidlsp/language_servers/`
2. Add runtime dependencies configuration
3. Create test repository and test suite
4. Update language enumeration and configuration
### Adding New Tools
1. Inherit from `Tool` base class in `tools_base.py`
2. Implement required methods and parameter validation
3. Register tool in appropriate tool registry
4. Add to context/mode configurations as needed
### Custom Contexts and Modes
- Define new contexts in YAML configuration files
- Specify tool sets and operational patterns
- Configure for specific development workflows
## /.serena/memories/serena_repository_structure.md
# Serena Repository Structure
## Overview
Serena is a multi-language code assistant that combines two main components:
1. **Serena Core** - The main agent framework with tools and MCP server
2. **SolidLSP** - A unified Language Server Protocol wrapper for multiple programming languages
## Top-Level Structure
```
serena/
├── src/ # Main source code
│ ├── serena/ # Serena agent framework
│ ├── solidlsp/ # LSP wrapper library
│ └── interprompt/ # Multi-language prompt templates
├── test/ # Test suites
│ ├── serena/ # Serena agent tests
│ ├── solidlsp/ # Language server tests
│ └── resources/repos/ # Test repositories for each language
├── scripts/ # Build and utility scripts
├── resources/ # Static resources and configurations
├── pyproject.toml # Python project configuration
├── README.md # Project documentation
└── CHANGELOG.md # Version history
```
## Source Code Organization
### Serena Core (`src/serena/`)
- **`agent.py`** - Main SerenaAgent class that orchestrates everything
- **`tools/`** - MCP tools for file operations, symbols, memory, etc.
- `file_tools.py` - File system operations (read, write, search)
- `symbol_tools.py` - Symbol-based code operations (find, edit)
- `memory_tools.py` - Knowledge persistence and retrieval
- `config_tools.py` - Project and mode management
- `workflow_tools.py` - Onboarding and meta-operations
- **`config/`** - Configuration management
- `serena_config.py` - Main configuration classes
- `context_mode.py` - Context and mode definitions
- **`util/`** - Utility modules
- **`mcp.py`** - MCP server implementation
- **`cli.py`** - Command-line interface
### SolidLSP (`src/solidlsp/`)
- **`ls.py`** - Main SolidLanguageServer class
- **`language_servers/`** - Language-specific implementations
- `csharp_language_server.py` - C# (Microsoft.CodeAnalysis.LanguageServer)
- `python_server.py` - Python (Pyright)
- `typescript_language_server.py` - TypeScript
- `rust_analyzer.py` - Rust
- `gopls.py` - Go
- And many more...
- **`ls_config.py`** - Language server configuration
- **`ls_types.py`** - LSP type definitions
- **`ls_utils.py`** - Utilities for working with LSP data
### Interprompt (`src/interprompt/`)
- Multi-language prompt template system
- Jinja2-based templating with language fallbacks
## Test Structure
### Language Server Tests (`test/solidlsp/`)
Each language has its own test directory:
```
test/solidlsp/
├── csharp/
│ └── test_csharp_basic.py
├── python/
│ └── test_python_basic.py
├── typescript/
│ └── test_typescript_basic.py
└── ...
```
### Test Resources (`test/resources/repos/`)
Contains minimal test projects for each language:
```
test/resources/repos/
├── csharp/test_repo/
│ ├── serena.sln
│ ├── TestProject.csproj
│ ├── Program.cs
│ └── Models/Person.cs
├── python/test_repo/
├── typescript/test_repo/
└── ...
```
### Test Infrastructure
- **`test/conftest.py`** - Shared test fixtures and utilities
- **`create_ls()`** function - Creates language server instances for testing
- **`language_server` fixture** - Parametrized fixture for multi-language tests
## Key Configuration Files
- **`pyproject.toml`** - Python dependencies, build config, and tool settings
- **`.serena/`** directories - Project-specific Serena configuration and memories
- **`CLAUDE.md`** - Instructions for AI assistants working on the project
## Dependencies Management
The project uses modern Python tooling:
- **uv** for fast dependency resolution and virtual environments
- **pytest** for testing with language-specific markers (`@pytest.mark.csharp`)
- **ruff** for linting and formatting
- **mypy** for type checking
## Build and Development
- **Docker support** - Full containerized development environment
- **GitHub Actions** - CI/CD with language server testing
- **Development scripts** in `scripts/` directory
## /.serena/memories/suggested_commands.md
# Suggested Commands
## Development Tasks (using uv and poe)
The following tasks should generally be executed using `uv run poe <task_name>`.
- `format`: This is the **only** allowed command for formatting. Run as `uv run poe format`.
- `type-check`: This is the **only** allowed command for type checking. Run as `uv run poe type-check`.
- `test`: This is the preferred command for running tests (`uv run poe test [args]`). You can select subsets of tests with markers,
the current markers are
```toml
markers = [
"python: language server running for Python",
"go: language server running for Go",
"java: language server running for Java",
"rust: language server running for Rust",
"typescript: language server running for TypeScript",
"php: language server running for PHP",
"snapshot: snapshot tests for symbolic editing operations",
]
```
By default, `uv run poe test` uses the markers set in the env var `PYTEST_MARKERS`, or, if it unset, uses `-m "not java and not rust and not isolated process"`.
You can override this behavior by simply passing the `-m` option to `uv run poe test`, e.g. `uv run poe test -m "python or go"`.
For finishing a task, make sure format, type-check and test pass! Run them at the end of the task
and if needed fix any issues that come up and run them again until they pass.
## /.serena/project.yml
```yml path="/.serena/project.yml"
# the name by which the project can be referenced within Serena
project_name: "serena"
# list of languages for which language servers are started; choose from:
# al ansible bash clojure cpp
# cpp_ccls crystal csharp csharp_omnisharp dart
# elixir elm erlang fortran fsharp
# go groovy haskell haxe hlsl
# java json julia kotlin lean4
# lua luau markdown matlab msl
# nix ocaml pascal perl php
# php_phpactor powershell python python_jedi python_ty
# r rego ruby ruby_solargraph rust
# scala solidity swift systemverilog terraform
# toml typescript typescript_vts vue yaml
# zig
# (This list may be outdated. For the current list, see values of Language enum here:
# https://github.com/oraios/serena/blob/main/src/solidlsp/ls_config.py
# For some languages, there are alternative language servers, e.g. csharp_omnisharp, ruby_solargraph.)
# Note:
# - For C, use cpp
# - For JavaScript, use typescript
# - For Free Pascal/Lazarus, use pascal
# Special requirements:
# Some languages require additional setup/installations.
# See here for details: https://oraios.github.io/serena/01-about/020_programming-languages.html#language-servers
# When using multiple languages, the first language server that supports a given file will be used for that file.
# The first language is the default language and the respective language server will be used as a fallback.
# Note that when using the JetBrains backend, language servers are not used and this list is correspondingly ignored.
languages:
- python
- typescript
# whether to use project's .gitignore files to ignore files
ignore_all_files_in_gitignore: true
# list of additional paths to ignore in this project.
# Same syntax as gitignore, so you can use * and **.
# Note: global ignored_paths from serena_config.yml are also applied additively.
ignored_paths: []
# whether the project is in read-only mode
# If set to true, all editing tools will be disabled and attempts to use them will result in an error
# Added on 2025-04-18
read_only: false
# list of tool names to exclude.
# This extends the existing exclusions (e.g. from the global configuration)
# Find the list of tools here: https://oraios.github.io/serena/01-about/035_tools.html
excluded_tools: []
# list of tools to include that would otherwise be disabled (particularly optional tools that are disabled by default).
# This extends the existing inclusions (e.g. from the global configuration).
# Find the list of tools here: https://oraios.github.io/serena/01-about/035_tools.html
included_optional_tools: []
# initial prompt for the project. It will always be given to the LLM upon activating the project
# (contrary to the memories, which are loaded on demand).
initial_prompt: |
IMPORTANT: You use an idiomatic, object-oriented style.
In particular, this implies that, for any non-trivial interfaces, you use interfaces that expect explicitly typed abstractions
rather than mere functions (i.e. use the strategy pattern, for example).
You avoid the use of low-level data structures in all cases where an object-oriented abstraction would be more appropriate.
For simple data storage, you use dataclasses instead of dictionaries or tuples.
You structure function implementations into functional blocks that are separated by blank lines.
Atop each functional block, you write an elliptical phrase (starting with lower-case letter) that describes the purpose of the
block in a concise manner.
Docstrings: You consistently use reStructuredText.
Comments:
When describing parameters, methods/functions and classes, you use a precise style, where the initial (elliptical) phrase
clearly defines *what* it is. Any details then follow in subsequent sentences.
# the encoding used by text files in the project
# For a list of possible encodings, see https://docs.python.org/3.11/library/codecs.html#standard-encodings
encoding: utf-8
# list of mode names to that are always to be included in the set of active modes
# The full set of modes to be activated is base_modes + default_modes.
# If the setting is undefined, the base_modes from the global configuration (serena_config.yml) apply.
# Otherwise, this setting overrides the global configuration.
# Set this to [] to disable base modes for this project.
# Set this to a list of mode names to always include the respective modes for this project.
base_modes:
# list of mode names that are to be activated by default, overriding the setting in the global configuration.
# The full set of modes to be activated is base_modes (from global config) + default_modes + added_modes.
# If the setting is undefined/empty, the default_modes from the global configuration (serena_config.yml) apply.
# Otherwise, this overrides the setting from the global configuration (serena_config.yml).
# Therefore, you can set this to [] if you do not want the default modes defined in the global config to apply
# for this project.
# This setting can, in turn, be overridden by CLI parameters (--mode).
# See https://oraios.github.io/serena/02-usage/050_configuration.html#modes
default_modes:
# fixed set of tools to use as the base tool set (if non-empty), replacing Serena's default set of tools.
# This cannot be combined with non-empty excluded_tools or included_optional_tools.
# Find the list of tools here: https://oraios.github.io/serena/01-about/035_tools.html
fixed_tools: []
# time budget (seconds) per tool call for the retrieval of additional symbol information
# such as docstrings or parameter information.
# This overrides the corresponding setting in the global configuration; see the documentation there.
# If null or missing, use the setting from the global configuration.
symbol_info_budget:
# The language backend to use for this project.
# If not set, the global setting from serena_config.yml is used.
# Valid values: LSP, JetBrains
# Note: the backend is fixed at startup. If a project with a different backend
# is activated post-init, an error will be returned.
language_backend:
# list of regex patterns which, when matched, mark a memory entry as read‑only.
# Extends the list from the global configuration, merging the two lists.
read_only_memory_patterns: []
# line ending convention to use when writing source files.
# Possible values: unset (use global setting), "lf", "crlf", or "native" (platform default)
# This does not affect Serena's own files (e.g. memories and configuration files), which always use native line endings.
line_ending:
# list of regex patterns for memories to completely ignore.
# Matching memories will not appear in list_memories or activate_project output
# and cannot be accessed via read_memory or write_memory.
# To access ignored memory files, use the read_file tool on the raw file path.
# Extends the list from the global configuration, merging the two lists.
# Example: ["_archive/.*", "_episodes/.*"]
ignored_memory_patterns: []
# advanced configuration option allowing to configure language server-specific options.
# Maps the language key to the options.
# Have a look at the docstring of the constructors of the LS implementations within solidlsp (e.g., for C# or PHP) to see which options are available.
# No documentation on options means no options are available.
ls_specific_settings: {}
# list of mode names to be activated additionally for this project, e.g. ["query-projects"]
# The full set of modes to be activated is base_modes (from global config) + default_modes + added_modes.
# See https://oraios.github.io/serena/02-usage/050_configuration.html#modes
added_modes:
# list of additional workspace folder paths for cross-package reference support (e.g. in monorepos).
# Paths can be absolute or relative to the project root.
# Each folder is registered as an LSP workspace folder, enabling language servers to discover
# symbols and references across package boundaries.
# Currently supported for: TypeScript.
# Example:
# additional_workspace_folders:
# - ../sibling-package
# - ../shared-lib
additional_workspace_folders: []
```
## /.vscode/settings.json
```json path="/.vscode/settings.json"
{
"cSpell.words": [
"agno",
"asyncio",
"genai",
"getpid",
"Gopls",
"langsrv",
"multilspy",
"pixi",
"sensai",
"vibing"
],
}
```
## /AGENTS.md
Relevant information about the project is in .serena/memories. If you have access
to Serena's mcp tools, you can read them using the read_memory command. Otherwise
you can just read them using normal file reading tools.
## /CHANGELOG.md
# Unreleased (main)
Status of the `main` branch. Changes prior to the next official version change will appear here.
* General:
- Make tool descriptions more amenable to tool search mechanisms as now used in several clients (e.g. avoid referencing other tools' names, etc.)
* Language Servers:
- No longer store temporary files (e.g. downloads) in `~/solidlsp_tmp`; instead, use OS-specific temporary directories
- Add **GDScript** (Godot Engine) support. Serena connects over TCP to the Godot editor's built-in LSP server (port 6008, same for Godot 3 and 4) — no separate language server process to install. Godot major version is auto-detected from `config_version` in `project.godot`. Note: Godot's LSP does not implement `workspace/symbol`; first workspace-wide scans fall back to per-file requests and can be slow for large projects (results are cached to disk). See the [GDScript Setup Guide](https://oraios.github.io/serena/03-special-guides/godot_gdscript_setup_guide_for_serena.html) for details. Closes #1446.
* Dashboard:
- UI polish: switch UI font to Inter (with system fallbacks) and use JetBrains Mono only for code/logs/paths/identifiers; refine the light/dark palette with softer borders, clearer text hierarchy, and a more nuanced shadow/elevation system; introduce a consistent spacing scale; keep the orange accent.
- Modal markup cleanup: extract shared CSS classes (`.modal-info`, `.modal-hint`, `.modal-prompt`, `.modal-field`, `.modal-input`, `.modal-select`, `.modal-textarea`, `.modal-actions`, `.btn-secondary`) and remove duplicated inline styles from all seven modals. Inputs and textareas get an accent-colored focus ring; the modal backdrop has a subtle blur.
- Add Language: replace the native `<select>` with a filterable combobox — type to filter, keyboard navigation (Up/Down/Enter/Esc), substring highlight, click-outside to close. The typed value is validated against the available languages list before submission.
# v1.3.0 (2026-05-11)
* General:
- Breaking change in mode definitions: Projects (project.yml) can no longer override `base_modes`.
Instead, they can define `added_modes` to add modes on top of base and default modes.
See updated [documentation on modes](https://oraios.github.io/serena/02-usage/050_configuration.html#modes).
- Serena's default configuration now uses `interactive` and `editing` as `base_modes` instead of as `default_modes`.
- Fixed path validation in `search_for_pattern` tool (thanks to [@dodge1218](https://github.com/dodge1218) for the report)
- Fix: In HTTP/SSE mode, a client disconnection triggered a partial agent shutdown (project deactivation, dashboard manager & GUI viewer shutdown)
* JetBrains:
- Add new tools:
- `jet_brains_list_inspections`: Lists available IDE inspections (akin to diagnostics), optionally filtered by language or group
- `jet_brains_run_inspections`: Runs IDE inspections on a file and returns the results
* LSP Backend:
- Add cross-package reference support via `additional_workspace_folders` setting (currently implemented for TypeScript).
- Add new tools:
- `find_declaration`: Finds the declaration/definition of a symbol
- `find_implementations`: Finds the implementations of an interface or abstract method
- `get_diagnostics_for_file`: Retrieves diagnostics for a specific file (errors, warnings, etc.)
- `get_diagnostics_for_symbol`: Retrieves diagnostics pertaining to a specific symbol
* Language Servers:
- Add **Svelte** support via `svelte-language-server@0.18.0`, installed with npm into Serena-managed language-server resources. The `svelte` language handles `.svelte` Single File Components plus TypeScript/JavaScript files for Svelte projects; use it instead of also enabling `typescript` unless intentionally running multiple language servers.
- Elixir (`elixir-tools/next-ls`): Fix deadlock in monorepo projects where `mix.exs` lives in a subdirectory. The server now searches immediate subdirectories when no `mix.exs` is found at the repository root. #1444
- Java (`eclipse.jdt.ls`): Add upstream JDTLS mode for offline / restricted-network use. Setting both `jdtls_path` and `lombok_path` in `ls_specific_settings.java` makes Serena use an existing upstream JDTLS installation (e.g. `brew install jdtls`) and the system JDK 21+, skipping the ~500 MB vscode-java VSIX, Gradle, and IntelliCode downloads. New related setting `java_home` lets the user override the JDK used to launch JDTLS. Default behavior unchanged — the JDTLS workspace hash is preserved bit-for-bit for users on the default route, so existing project caches are reused without a one-time reindex; the launcher path is mixed into the hash only when `jdtls_path` is set, isolating upstream installations from the default workspace. #1415
- Java (eclipse.jdt.ls): Lombok-generated methods (getters/setters, builder(), equals/hashCode/toString, etc.) are now included in symbol-based tools (find_symbol, get_symbols_overview, edits). Added lombok_show_generated setting (default: on) to toggle this. Updated bundled vscode-java to 1.54.0-923. Issue #1432.
- Add **Ada / SPARK** support using AdaCore's [Ada Language Server](https://github.com/AdaCore/ada_language_server). Auto-downloads the official prebuilt ALS binary (linux-x64/arm64, darwin-x64/arm64, win32-x64). A single `ada` language covers both Ada and SPARK, since the server uses the same `.ads`/`.adb` files for both and distinguishes SPARK by source-level pragmas/aspects. Users can override the binary by setting `ls_specific_settings.ada.ls_path` to a pre-installed `ada_language_server` (e.g. from Alire, GNAT Studio, or the VS Code Ada extension).
- Add **Angular** (experimental) via a dual-server architecture: `@angular/language-server` (ngserver) handles standalone `.html` template files, while a companion `typescript-language-server` with `@angular/language-service` loaded as a tsserver plugin handles all `.ts` operations including inline templates. Provides type-aware navigation between templates and component classes. Requires Node.js, npm, and `@angular/core` installed in the project (`npm install` in the project root). Subsumes `typescript`+`html` for `.ts`/`.html` files when active; SCSS is not subsumed.
- Add **HTML** (experimental) using `vscode-html-language-server` from the `vscode-langservers-extracted` npm package. Provides in-file element/id symbols via documentSymbol; cross-file references are not meaningful for HTML. Also used as a companion server by the Angular LS for plain HTML documentSymbol support.
- Add **SCSS / Sass / CSS** (experimental) using [some-sass-language-server](https://github.com/wkillerud/some-sass). Handles `.scss`, `.sass`, and `.css` through one server, with full `@use`/`@forward` workspace-wide go-to-definition and find-references for variables, mixins, and functions across Sass files. The `.css` path uses the same `vscode-css-languageservice` engine that powers the standalone CSS LS; CSS feature toggles default off upstream and are flipped on at startup so symbols, hover, completion, and syntax-level diagnostics work for plain CSS as well.
- Add **1C / OneScript** support using [BSL Language Server](https://github.com/1c-syntax/bsl-language-server/).
- Add support for more filenames to be considered by ccls and clangd.
- Clojure (`clojure-lsp`): Fix incomplete `find_referencing_symbols` results in multi-module monorepos. clojure-lsp only discovers source paths from the descriptor at the workspace root and does not recurse for sub-module `deps.edn` / `project.clj` / `shadow-cljs.edn` / `bb.edn` files, so references in sibling modules were silently missed until those files happened to be opened by `find_symbol` / `get_symbols_overview`. Serena now scans the repo for project descriptors at startup and passes the union of their declared source paths to clojure-lsp via `initializationOptions`. Project-local `.lsp/config.edn` files are honoured as-is (no override). New `ls_specific_settings.clojure` keys: `source_paths` (explicit override) and `config_edn_path` (parse `:source-paths` from a user-supplied config file).
* Hooks:
- `serena-hooks auto-approve` now also emits an `allow` decision when Claude Code reports
`permission_mode == "auto"`, in addition to the existing `acceptEdits` behavior. #1386
- Extension: heuristics for parsing commands and firing a hook on too many greps or reads. Important for clients that, unlike claude code, don't have dedicated grep/read tools.
- Read hook now only fires on reads of code files (using heuristics to parse the read command string)
- Reminder hook now also counts and fires on usages of serena's non-symbolic tools.
# v1.2.0 (2026-04-27)
* General:
- Fix: Check for ignored path ignored `.git` folder only at the top level, not in every subdirectory (`Project._is_ignored_relative_path`) #1350
- `GetSymbolsOverviewTool`: ignored paths were not respected in LSP variant (fix in `SolidLanguageServer`)
- Fix: Duplicate comments in re-saved YAML configuration files #1285
- Prompt provision improvements (project activation, initial instructions):
- Prompt provision is now session-aware, i.e. when using the MCP server in HTTP mode, prompts are provided for each session separately,
ensuring that the necessary information is always provided to the LLM
- Fix: Prompts of dynamically activated modes (upon project activation) were not necessarily passed to the LLM (only in the system prompt via
`initial_instructions`). Now they are passed directly in the activation message (and excluded from a subsequent `initial_instructions` call).
- Fix: Project activation message was provided more than once for case of dynamic project activation followed
by `initial_instructions` #1372
- Always provide full activation message upon calling `activate_project` (even if project was already active in the same session) #1384
This is necessary, because some clients (e.g. Claude Desktop) will reuse a single session across chats.
- Security: Forbid `".."` in memory names to disallow accessing files outside dedicated memory directories
- Security: Add check for tool being read-only in the project server (previously only checked in `query_project` tool, i.e. client side)
- Usage reporting now also includes the name of the Serena context that is used
- Fix: restricted `insert_after_symbol` to raise if used on an assignment or similar (can't reliably determine the symbol range)
- Fix: Failure to collect project ignore spec now logs the error and downstream tasks fail fast, fixing hanging LS initialisation
- Improve loading of `project.yml` files: Gracefully handle user errors involving incorrect use of None/empty instead of list
- Project server:
- `query_project`: Support use of project root instead of project name #1388
- `list_queryable_projects`: Return both project names and project roots
- Fix: `search_for_pattern` tool returned 1-based line numbers (in contrast to all other tools); cause: implementation of `text_utils.search_text`
- Serena's system prompt (a.k.a. the 'Serena Instructions Manual') is now provided lazily.
At MCP connection time, only a one-sentence bootstrap prompt is provided.
The `initial_instructions` tool provides the full prompt on demand, keeping the initial context lean.
- Add `serena_info` tool for on-demand retrieval of usage information
* CLI:
- Support `serena --version` CLI command for displaying the current version #1347
- Extend `prompts` subcommand with `print-prompt-template` and `print-cc-system-prompt-override`, improve `list` subcommand
* Clients:
- Document workaround to make Claude Code use Serena's tools after recent degradations caused by changes in CC harness and Opus 4.7 release.
* JetBrains:
- Add `debug` tool: The agent can set breakpoints, inspect variables, evaluate expressions and control execution flow
by directly interacting with the IDE's debugger, using a REPL-style interface for maximum flexibility.
- `move` and `safe_delete` tools: transform empty string to None (counteracts client errors)
* Dependencies:
- `pywebview`: Switch back to official release (new version 6.2) #1253
- `mcp`: Update from `1.26.0` to `1.27.0`
* Evaluations:
- Added new evaluations for Junie Plugin with Opus 4.6 and GLM 5.1 in Claude Code.
* Language Servers:
- Fix: clangd capability checks now tolerate valid initialize response shape differences and invalidate cached C++ document symbols when clangd/compile commands context changes #1359
- Fix: `rename_symbol` for Vue files now correctly propagates edits to the TypeScript server, enabling cross-file renames in `.vue` files
- Fix: Lean4 stale cache — empty document symbol responses (returned before `lake build` completes) are no longer persisted, preventing symbols from being permanently hidden #1356
- Add JSON language server support via `vscode-json-languageserver` (experimental) #1391
- Fix: Elixir/Expert deadlock on startup — Expert's build pipeline requires a `textDocument/didOpen` notification to start; Serena now opens `mix.exs` immediately after `initialized` so Expert begins compiling instead of waiting indefinitely #1397
* Dashboard:
- Add configurable dashboard interface mode (new global configuration setting `web_dashboard_interface`):
Three modes (browser, native app with tray, tray manager for aggregating multiple instances) are supported, depending on the OS
- Fix: Memory leaks in frontend when using Chromium-based browsers/Windows webview #1389
* Hooks:
- Adjusted wording of startup hook, improving project activation instructions #1401.
# v1.1.2 (2026-04-14)
* General:
- Support environment variable `SERENA_USAGE_REPORTING` (set to `false` to disable usage reporting)
- Extended the list of always ignored directories (by language servers) with common cases.
- Improve exposed toolset: With mode switching no longer being a feature, we now fully apply tool exclusions
defined by modes when in a single-project context (limiting exposed tools to a minimum)
- Fix: When scanning for `.gitignore` files, the presence of files that could not be made relative
to the project root would cause the scan to fail. #1317
* Dashboard:
- Fix handling of read news, saving each read news entry separately #1338
* JetBrains:
- Improve handling of `relative_path` parameter
- Improve its documentation to avoid usage errors
- Replace escaped characters in `relative_path` with their unescaped counterparts (< and >)
- `FindSymbolTool`: Force `search_deps=True` if `relative_path` pertains to external dependencies.
* Language Servers:
- Add mSL (mIRC Scripting Language) support (custom pygls-based language server; symbols, references, definitions)
- Fix initialisation issues in Vue language server #1333
# v1.1.1 (2026-04-12)
* General:
- Enable cert verification for HTTPS request to oraios-software.de #1320
* JetBrains:
- `JetBrainsRenameTool` can now also rename occurrences in comments and text.
* Language Servers:
- Fix Dart LSP returning only symbol name as body instead of full method body.
# v1.1.0 (2026-04-11)
* General:
- **Major**: Add commands for hooks and documentation of recommended setup. Consider setting up the [recommended hooks](https://oraios.github.io/serena/02-usage/030_clients.html) !
- Add `serena init` and `serena setup` commands
- Rework installation instructions, switching to releases on pypi for distribution. Please update your mcp startup commands!
- Add minimal usage data collection on startup (only Serena version, language backend, OS, dashboard enabled status; no personally identifiable information)
- Fix: git commit id in Serena version strings was incorrect
* Language Servers:
- Add support for Haxe via vshaxe/haxe-language-server. Requires Haxe compiler 3.4.0+ and Node.js. Auto-discovered from the vshaxe VSCode extension or configurable via `ls_path` in `ls_specific_settings`.
- Add Crystal language support (uses [Crystalline](https://github.com/elbywan/crystalline) language server)
- Fix: Reactivation of the same project restarted language servers #1280
* JetBrains:
- `JetBrainsFindReferencingSymbolTool`: Include context lines (when using plugin version 2023.2.15+)
* Dashboard:
- Add version display
- Fix: Dashboard viewer (Windows): Add a parent monitoring thread to ensure termination.
Some clients would terminate the MCP server in a way that did not ensure proper termination.
- Fix: Manual server shutdown triggered by GUI tool/dashboard not cleaning everything up.
# v1.0.0 (2026-04-03)
* General:
* Add monorepo/multi-language support
* Project configuration files (`project.yml`) can now define multiple languages.
Auto-detection adds only the most prominent language by default.
* Additional languages can be conveniently added via the Dashboard while a project is already activated.
* Add support for querying projects other than the currently active one via new tools `QueryProjectTool` and `ListQueryableProjectsTool`.
The `QueryProjectTool` allows Serena tools to be called on other projects.
* For the LSP backend, calling symbolic tools require a project server to be spawned that will launch the respective language servers
* For the JetBrains backend, all projects for which IDE instances are open can directly be queried
* Support overloaded symbols in `FindSymbolTool` and related tools
* Name paths of overloaded symbols now include an index (e.g., `myOverloadedFunction[2]`)
* Responses of the Java language server, which handled this in its own way, are now adapted accordingly,
solving several issues related to retrieval problems in Java projects
* Major extensions to the dashboard, which now serves as a central web interface for Serena
* View current configuration
* View news which can be marked as read
* View the executions, with the possibility to cancel running/scheduled executions
* View tool usage statistics
* View and create memories and edit the serena configuration file
* Log page now has save (downloads a snapshot) and clear (resets log view) buttons alongside the existing copy button
* Language server backend:
* New two-tier caching of language server document symbols and considerable performance improvements surrounding symbol retrieval/indexing
* Allow passing language server-specific settings through `ls_specific_settings` field (in `serena_config.yml`)
* Add the JetBrains language backend as an alternative to language servers
* Improve management of Serena projects
* Facilitate project activation based on the current directory (through the `--project-from-cwd` parameter)
* Add notion of a "single-project context" (flag `single_project`), allowing user-defined contexts to behave
like the built-in `ide-assistant` context (where the available tools are restricted to ones required by the active
project and project changes are disabled)
* The location of Serena's project-specific data folder can now be flexibly configured, allowing, in particular,
locations outside of the project folder, thus improving support for read-only projects.
* Add support for `project.local.yml` for local overrides that should not be versioned
* Various fixes related to indexing, special paths and determination of ignored paths
* Memories:
* Add support for global memories (shared across projects)
* Add `read_only_memory_patterns` configuration option
* Add `ignored_memory_patterns` configuration option
* Improved client support, e.g. new mode `oaicompat-agent` and extensions enhancing OpenAI tool compatibility
* Tools:
* Additional symbol meta-information (hover, docstring, quick-info) is now provided as part of `find_symbol` and related tool responses.
* Added `QueryProjectTool` and `ListQueryableProjectTool` (see above)
* Added `RenameSymbolTool` for renaming symbols across the codebase (if LS supports this operation).
* Replaced `ReplaceRegexTool` with `ReplaceContentTool`, which supports both plain text and regex-based replacements
(and which requires no escaping in the replacement text, making it more robust)
* Add JetBrains tools which leverage the corresponding JetBrains language backend through our plugin
* Decreased `TOOL_DEFAULT_MAX_ANSWER_LENGTH` to be in accordance with (below) typical max-tokens configurations
* Language support:
* **Add support for Lean 4** via built-in `lean --server` with cross-file reference support (requires `lean` and `lake` via [elan](https://github.com/leanprover/elan))
* **Add support for OCaml** via ocaml-lsp-server with cross-file reference support on OCaml 5.2+ (requires opam; see [setup guide](docs/03-special-guides/ocaml_setup_guide_for_serena.md))
* **Add Phpactor as alternative PHP language server** (specify `php_phpactor` as language; requires PHP 8.1+)
* **Add support for Fortran** via fortls language server (requires `pip install fortls`)
* **Add partial support for Groovy** requires user-provided Groovy language server JAR (see [setup guide](docs/03-special-guides/groovy_setup_guide_for_serena.md))
* **Add support for Julia** via LanguageServer.jl
* **Add support for Haskell** via Haskell Language Server (HLS) with automatic discovery via ghcup, stack, or system PATH; supports both Stack and Cabal projects
* **Add support for Scala** via Metals language server (requires some [manual setup](docs/03-special-guides/scala_setup_guide_for_serena.md))
* **Add support for F#** via FsAutoComplete/Ionide LSP server.
* **Add support for Elm** via @elm-tooling/elm-language-server (automatically downloads if not installed; requires Elm compiler)
* **Add support for Perl** via Perl::LanguageServer with LSP integration for .pl, .pm, and .t files
* **Add support for AL (Application Language)** for Microsoft Dynamics 365 Business Central development. Requires VS Code AL extension (ms-dynamics-smb.al).
* **Add support for R** via the R languageserver package with LSP integration, performance optimizations, and fallback symbol extraction
* **Add support for Zig** via ZLS (cross-file references may not fully work on Windows)
* **Add support for Lua** via lua-language-server
* **Add support for Nix** requires nixd installation (Windows not supported)
* **Add experimental support for YAML** via yaml-language-server with LSP integration for .yaml and .yml files
* **Add support for TOML** via Taplo language server with automatic binary download, validation, formatting, and schema support for .toml files
* **Dart now officially supported**: Dart was always working, but now tests were added, and it is promoted to "officially supported"
* **Rust now uses already installed rustup**: The rust-analyzer is no longer bundled with Serena. Instead, it uses the rust-analyzer from your Rust toolchain managed by rustup. This ensures compatibility with your Rust version and eliminates outdated bundled binaries.
* **Kotlin now officially supported**: We now use the official Kotlin LS, tests run through and performance is good, even though the LS is in an early development stage.
* **Add support for Erlang** experimental, may hang or be slow, uses the recently archived [erlang_ls](https://github.com/erlang-ls/erlang_ls)
* **Ruby dual language server support**: Added ruby-lsp as the modern primary Ruby language server. Solargraph remains available as an experimental legacy option. ruby-lsp supports both .rb and .erb files, while Solargraph supports .rb files only.
* **Add support for PowerShell** via PowerShell Editor Services (PSES). Requires `pwsh` (PowerShell Core) to be installed and available in PATH. Supports symbol navigation, go-to-definition, and within-file references for .ps1 files.
* **Add support for MATLAB** via the official MathWorks MATLAB Language Server. Requires MATLAB R2021b or later and Node.js. Set `MATLAB_PATH` environment variable or configure `matlab_path` in `ls_specific_settings`. Supports .m, .mlx, and .mlapp files with code completion, diagnostics, go-to-definition, find references, document symbols, formatting, and rename.
* **Add support for Pascal** via the official Pascal Language Server.
* **C/C++ alternate LS (ccls)**: Add experimental, opt-in support for ccls as an alternative backend to clangd. Enable via `cpp_ccls` in project configuration. Requires `ccls` installed and ideally a `compile_commands.json` at repo root.
* **Add support for Solidity** via the Nomic Foundation `@nomicfoundation/solidity-language-server` (automatically installed via npm)
# v0.1.4 (2025-08-15)
## Summary
This likely is the last release before the stable version 1.0.0 which will come together with the jetbrains IDE extension.
We release it for users who install Serena from a tag, since the last tag cannot be installed due to a breaking change in the mcp dependency (see #381).
Since the last release, several new languages were supported, and the Serena CLI and configurability were significantly extended.
We thank all external contributors who made a lot of the improvements possible!
* General:
* **Initial instructions no longer need to be loaded by the user**
* Significantly extended CLI
* Removed `replace_regex` tool from `ide-assistant` and `codex` contexts.
The current string replacement tool in Claude Code seems to be sufficiently efficient and is better
integrated with the IDE. Users who want to enable `replace_regex` can do so by customizing the context.
* Configuration:
* Simplify customization of modes and contexts, including CLI support.
* Possibility to customize the system prompt and outputs of simple tools, including CLI support.
* Possibility to override tool descriptions through the context YAML.
* Prompt templates are now automatically adapted to the enabled tools.
* Several tools are now excluded by default, need to be included explicitly.
* New context for ChatGPT
* Language servers:
* Reliably detect language server termination and propagate the respective error all the way
back to the tool application, where an unexpected termination is handled by restarting the language server
and subsequently retrying the tool application.
* **Add support for Swift**
* **Add support for Bash**
* Enhance Solargraph (Ruby) integration
* Automatic Rails project detection via config/application.rb, Rakefile, and Gemfile analysis
* Ruby/Rails-specific exclude patterns for improved indexing performance (vendor/, .bundle/, tmp/, log/, coverage/)
* Enhanced error handling with detailed diagnostics and Ruby manager-specific installation instructions (rbenv, RVM, asdf)
* Improved LSP capability negotiation and analysis completion detection
* Better Bundler and Solargraph installation error messages with clear resolution steps
Fixes:
* Ignore `.git` in check for ignored paths and improve performance of `find_all_non_ignored_files`
* Fix language server startup issues on Windows when using Claude Code (which was due to
default shell reconfiguration imposed by Claude Code)
* Additional wait for initialization in C# language server before requesting references, allowing cross-file references to be found.
# v0.1.3 (2025-07-22)
## Summary
This is the first release of Serena to pypi. Since the last release, we have greatly improved
stability and performance, as well as extended functionality, improved editing tools and included support for several new languages.
* **Reduce the use of asyncio to a minimum**, improving stability and reducing the need for workarounds
* Switch to newly developed fully synchronous LSP library `solidlsp` (derived from `multilspy`),
removing our fork of `multilspy` (src/multilspy)
* Switch from fastapi (which uses asyncio) to Flask in the Serena dashboard
* The MCP server is the only asyncio-based component now, which resolves cross-component loop contamination,
such that process isolation is no longer required.
Neither are non-graceful shutdowns on Windows.
* **Improved editing tools**: The editing logic was simplified and improved, making it more robust.
* The "minimal indentation" logic was removed, because LLMs did not understand it.
* The logic for the insertion of empty lines was improved (mostly controlled by the LLM now)
* Add a task queue for the agent, which is executed in a separate and thread and
* allows the language server to be initialized in the background, making the MCP server respond to requests
immediately upon startup,
* ensures that all tool executions are fully synchronized (executed linearly).
* `SearchForPatternTool`: Better default, extended parameters and description for restricting the search
* Language support:
* Better support for C# by switching from `omnisharp` to Microsoft's official C# language server.
* **Add support for Clojure, Elixir and Terraform. New language servers for C# and typescript.**
* Experimental language server implementations can now be accessed by users through configuring the `language` field
* Configuration:
* Add option `web_dashboard_open_on_launch` (allowing the dashboard to be enabled without opening a browser window)
* Add options `record_tool_usage_stats` and `token_count_estimator`
* Serena config, modes and contexts can now be adjusted from the user's home directory.
* Extended CLI to help with configuration
* Dashboard:
* Displaying tool usage statistics if enabled in the config
Fixes:
* Fix `ExecuteShellCommandTool` and `GetCurrentConfigTool` hanging on Windows
* Fix project activation by name via `--project` not working (was broken in previous release)
* Improve handling of indentation and newlines in symbolic editing tools
* Fix `InsertAfterSymbolTool` failing for insertions at the end of a file that did not end with a newline
* Fix `InsertBeforeSymbolTool` inserting in the wrong place in the absence of empty lines above the reference symbol
* Fix `ReplaceSymbolBodyTool` changing whitespace before/after the symbol
* Fix repository indexing not following links and catch exceptions during indexing, allowing indexing
to continue even if unexpected errors occur for individual files.
* Fix `ImportError` in Ruby language server.
* Fix some issues with gitignore matching and interpreting of regexes in `search_for_pattern` tool.
# 2025-06-20
* **Overhaul and major improvement of editing tools!**
This represents a very important change in Serena. Symbols can now be addressed by their `name_path` (including nested ones)
and we introduced a regex-based replaced tools. We tuned the prompts and tested the new editing mechanism.
It is much more reliable, flexible, and at the same time uses fewer tokens.
The line-replacement tools are disabled by default and deprecated, we will likely remove them soon.
* **Better multi-project support and zero-config setup**: We significantly simplified the config setup, you no longer need to manually
create `project.yaml` for each project. Project activation is now always available.
Any project can now be activated by just asking the LLM to do so and passing the path to a repo.
* Dashboard as web app and possibility to shut down Serena from it (or the old log GUI).
* Possibility to index your project beforehand, accelerating Serena's tools.
* Initial prompt for project supported (has to be added manually for the moment)
* Massive performance improvement of pattern search tool
* Use **process isolation** to fix stability issues and deadlocks (see #170).
This uses separate process for the MCP server, the Serena agent and the dashboard in order to fix asyncio-related issues.
# 2025-05-24
* Important new feature: **configurability of mode and context**, allowing better integration in a variety of clients.
See corresponding section in readme - Serena can now be integrated in IDE assistants in a more productive way.
You can now also do things like switching to one-shot planning mode, ask to plan something (which will create a memory),
then switch to interactive editing mode in the next conversation and work through the plan read from the memory.
* Some improvements to prompts.
# 2025-05-21
**Significant improvement in symbol finding!**
* Serena core:
* `FindSymbolTool` now can look for symbols by specifying paths to them, not just the symbol name
* Language Servers:
* Fixed `gopls` initialization
* Symbols retrieved through the symbol tree or through overview methods now are linked to their parents
# 2025-05-19
* Serena core:
* Bugfix in `FindSymbolTool` (a bug fixed in LS)
* Fix in `ListDirTool`: Do not ignore files with extensions not understood by the language server, only skip ignored directories
(error introduced in previous version)
* Merged the two overview tools (for directories and files) into a single one: `GetSymbolsOverviewTool`
* One-click setup for Cline enabled
* `SearchForPatternTool` can now (optionally) search in the entire project
* New tool `RestartLanguageServerTool` for restarting the language server (in case of other sources of editing apart from Serena)
* Fix `CheckOnboardingPerformedTool`:
* Tool description was incompatible with project change
* Returned result was not as useful as it could be (now added list of memories)
* Language Servers:
* Add further file extensions considered by the language servers for Python (.pyi), JavaScript (.jsx) and TypeScript (.tsx, .jsx)
* Updated multilspy, adding support for Kotlin, Dart and C/C++ and several improvements.
* Added support for PHP
# 2025-04-07
> **Breaking Config Changes**: make sure to set `ignore_all_files_in_gitignore`, remove `ignore_dirs`
> and (optionally) set `ignore_paths` in your project configs. See [updated config template](myproject.template.yml)
* Serena core:
* New tool: FindReferencingCodeSnippets
* Adjusted prompt in CreateTextFileTool to prevent writing partial content (see [here](https://www.reddit.com/r/ClaudeAI/comments/1jpavtm/comment/mloek1x/?utm_source=share&utm_medium=web3x&utm_name=web3xcss&utm_term=1&utm_content=share_button)).
* FindSymbolTool: allow passing a file for restricting search, not just a directory (Gemini was too dumb to pass directories)
* Native support for gitignore files for configuring files to be ignored by serena. See also
in *Language Servers* section below.
* **Major Feature**: Allow Serena to switch between projects (project activation)
* Add central Serena configuration in `serena_config.yml`, which
* contains the list of available projects
* allows to configure whether project activation is enabled
* now contains the GUI logging configuration (project configurations no longer do)
* Add new tools `activate_project` and `get_active_project`
* Providing a project configuration file in the launch parameters is now optional
* Logging:
* Improve error reporting in case of initialization failure:
open a new GUI log window showing the error or ensure that the existing log window remains visible for some time
* Language Servers:
* Fix C# language server initialization issue when the project path contains spaces
* Native support for gitignore in overview, document-tree and find_references operations.
This is an **important** addition, since previously things like `venv` and `node_modules` were scanned
and were likely responsible for slowness of tools and even server crashes (presumably due to OOM errors).
* Agno:
* Fix Agno reloading mechanism causing failures when initializing the sqlite memory database #8
* Fix Serena GUI log window not capturing logs after initialization
# 2025-04-01
Initial public version
## /CLAUDE.md
Relevant information about the project is in .serena/memories. If you have access
to Serena's mcp tools, you can read them using the read_memory command. Otherwise
you can just read them using normal file reading tools.
## /CONTRIBUTING.md
# Contributing to Serena
Thank you for your interest in contributing to Serena!
## Scope of Contributions
The following types of contributions can be submitted directly via pull requests:
* isolated additions which do not change the behaviour of Serena and only extend it along existing lines (e.g., adding support for a new language server)
* small bug fixes
* documentation improvements
For other changes, please open an issue first to discuss your ideas with the maintainers.
When submitting a PR, ensure a well-defined scope.
Every PR should cover a single logical change or a set of closely related changes.
### Adding Support for a New Language Server
See the corresponding [memory](.serena/memories/adding_new_language_support_guide.md).
## Python Environment Setup
You can install a virtual environment with the required as follows
1. Create a new virtual environment: `uv venv -p 3.13`
2. Activate the environment:
* On Linux/Unix/macOS or Windows with Git Bash: `source .venv/bin/activate`
* On Windows outside of Git Bash: `.venv\Scripts\activate.bat` (in cmd/ps) or `source .venv/Scripts/activate` (in git-bash)
3. Install the required packages with all extras: `uv sync --extra dev`
## Local Installation as Tool
To install Serena as a local tool, run
```shell
uv tool install --reinstall -p 3.13 .
```
## Poe Tasks
We use poe to execute development tasks:
- `poe format` - run code auto-formatters
- `poe type-check` - run type checkers
## Testing Tool Executions
The Serena tools (and in fact all Serena code) can be executed without an LLM, and also without
any MCP specifics (though you can use the mcp inspector, if you want).
An example script for running tools is provided in [scripts/demo_run_tools.py](scripts/demo_run_tools.py).
## /DOCKER.md
# Docker Setup for Serena (Experimental)
⚠️ **EXPERIMENTAL FEATURE**: The Docker setup for Serena is still experimental and has some limitations. Please read this entire document before using Docker with Serena.
## Overview
Docker support allows you to run Serena in an isolated container environment, which provides better security isolation for the shell tool and consistent dependencies across different systems.
## Benefits
- **Safer shell tool execution**: Commands run in an isolated container environment
- **Consistent dependencies**: No need to manage language servers and dependencies on your host system
- **Cross-platform support**: Works consistently across Windows, macOS, and Linux
## Important Usage Pointers
### Configuration
Serena's configuration and log files are stored in the container in `/workspaces/serena/config/`.
Any local configuration you may have for Serena will not apply; the container uses its own separate configuration.
You can mount a local configuration/data directory to persist settings across container restarts
(which will also contain session log files).
Simply mount your local directory to `/workspaces/serena/config` in the container.
Initially, be sure to add a `serena_config.yml` file to the mounted directory which applies the following
special settings for Docker usage:
```
# Disable the GUI log window since it's not supported in Docker
gui_log_window: False
# Listen on all interfaces for the web dashboard to be accessible from outside the container
web_dashboard_listen_address: 0.0.0.0
# Disable opening the web dashboard on launch (not possible within the container)
web_dashboard_open_on_launch: False
```
Set other configuration options as needed.
### Project Activation Limitations
- **Only mounted directories work**: Projects must be mounted as volumes to be accessible
- Projects outside the mounted directories cannot be activated or accessed
- Since projects are not remembered across container restarts (unless you mount a local configuration as described above),
activate them using the full path (e.g. `/workspaces/projects/my-project`) when using dynamic project activation
### Language Support Limitations
The default Docker image does not include dependencies for languages that
require explicit system-level installations.
Only languages that install their requirements on the fly will work out of the box.
### Dashboard Port Configuration
The web dashboard runs on port 24282 (0x5EDA) by default. You can configure this using environment variables:
```bash
# Use default ports
docker-compose up serena
# Use custom ports
SERENA_DASHBOARD_PORT=8080 docker-compose up serena
```
⚠️ **Note**: If the local port is occupied, you'll need to specify a different port using the environment variable.
### Line Ending Issues on Windows
⚠️ **Windows Users**: Be aware of potential line ending inconsistencies:
- Files edited within the Docker container may use Unix line endings (LF)
- Your Windows system may expect Windows line endings (CRLF)
- This can cause issues with version control and text editors
- Configure your Git settings appropriately: `git config core.autocrlf true`
## Quick Start
### Using Docker Compose (Recommended)
1. **Production mode** (for using Serena as MCP server):
```bash
docker-compose up serena
```
2. **Development mode** (with source code mounted):
```bash
docker-compose up serena-dev
```
Note: Edit the `compose.yaml` file to customize volume mounts for your projects.
### Building the Docker Image Manually
```bash
# Build the image
docker build -t serena .
# Run with current directory mounted
docker run -it --rm \
-v "$(pwd)":/workspace \
-p 9121:9121 \
-p 24282:24282 \
-e SERENA_DOCKER=1 \
serena
```
### Using Docker Compose with Merge Compose files
To use Docker Compose with merge files, you can create a `compose.override.yml` file to customize the configuration:
```yaml
services:
serena:
# To work with projects, you must mount them as volumes:
volumes:
- ./my-project:/workspace/my-project
- /path/to/another/project:/workspace/another-project
# Add the context for the IDE assistant option:
command:
- "uv run --directory . serena-mcp-server --transport sse --port 9121 --host 0.0.0.0 --context claude-code"
```
See the [Docker Merge Compose files documentation](https://docs.docker.com/compose/how-tos/multiple-compose-files/merge/) for more details on using merge files.
## Accessing the Dashboard
Once running, access the web dashboard at:
- Default: http://localhost:24282/dashboard
- Custom port: http://localhost:${SERENA_DASHBOARD_PORT}/dashboard
## Volume Mounting
To work with projects, you must mount them as volumes:
```yaml
# In compose.yaml
volumes:
- ./my-project:/workspace/my-project
- /path/to/another/project:/workspace/another-project
```
## Environment Variables
- `SERENA_DOCKER=1`: Set automatically to indicate Docker environment
- `SERENA_PORT`: MCP server port (default: 9121)
- `SERENA_DASHBOARD_PORT`: Web dashboard port (default: 24282)
- `INTELEPHENSE_LICENSE_KEY`: License key for Intelephense PHP LSP premium features (optional)
## Troubleshooting
### Port Already in Use
If you see "port already in use" errors:
```bash
# Check what's using the port
lsof -i :24282 # macOS/Linux
netstat -ano | findstr :24282 # Windows
# Use a different port
SERENA_DASHBOARD_PORT=8080 docker-compose up serena
```
### Configuration Issues
If you need to reset Docker configuration:
```bash
# Remove Docker-specific config
rm serena_config.docker.yml
# Serena will auto-generate a new one on next run
```
### Project Access Issues
Ensure projects are properly mounted:
- Check volume mounts in `docker-compose.yaml`
- Use absolute paths for external projects
- Verify permissions on mounted directories
## /Dockerfile
``` path="/Dockerfile"
# Base stage with common dependencies
FROM python:3.11-slim AS base
SHELL ["/bin/bash", "-c"]
# Set environment variables to make Python print directly to the terminal and avoid .pyc files.
ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1
# Install system dependencies required for package manager and build tools.
# sudo, wget, zip needed for some assistants, like junie
RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
build-essential \
git \
ssh \
sudo \
wget \
zip \
unzip \
git \
&& rm -rf /var/lib/apt/lists/*
# Install pipx.
RUN python3 -m pip install --no-cache-dir pipx \
&& pipx ensurepath
# Install nodejs
ENV NVM_VERSION=0.40.3
ENV NODE_VERSION=22.18.0
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v${NVM_VERSION}/install.sh | bash
# standard location
ENV NVM_DIR=/root/.nvm
RUN . "$NVM_DIR/nvm.sh" && nvm install ${NODE_VERSION}
RUN . "$NVM_DIR/nvm.sh" && nvm use v${NODE_VERSION}
RUN . "$NVM_DIR/nvm.sh" && nvm alias default v${NODE_VERSION}
ENV PATH="${NVM_DIR}/versions/node/v${NODE_VERSION}/bin/:${PATH}"
# Add local bin to the path
ENV PATH="${PATH}:/root/.local/bin"
# Install the latest version of uv
RUN curl -LsSf https://astral.sh/uv/install.sh | sh
# Install Rust and rustup for rust-analyzer support (minimal profile)
ENV RUSTUP_HOME=/usr/local/rustup
ENV CARGO_HOME=/usr/local/cargo
ENV PATH="${CARGO_HOME}/bin:${PATH}"
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y \
--default-toolchain stable \
--profile minimal \
&& rustup component add rust-analyzer
# Set the working directory
WORKDIR /workspaces/serena
# Copy all files for development
COPY . /workspaces/serena/
# Install sed
RUN apt-get update && apt-get install -y sed
# Create Serena configuration
ENV SERENA_HOME=/workspaces/serena/config
RUN mkdir -p $SERENA_HOME
RUN cp src/serena/resources/serena_config.template.yml $SERENA_HOME/serena_config.yml
RUN sed -i 's/^gui_log_window: .*/gui_log_window: False/' $SERENA_HOME/serena_config.yml
RUN sed -i 's/^web_dashboard_listen_address: .*/web_dashboard_listen_address: 0.0.0.0/' $SERENA_HOME/serena_config.yml
RUN sed -i 's/^web_dashboard_open_on_launch: .*/web_dashboard_open_on_launch: False/' $SERENA_HOME/serena_config.yml
# Create virtual environment and install dependencies
RUN uv venv
RUN . .venv/bin/activate
RUN uv pip install -r pyproject.toml -e .
ENV PATH="/workspaces/serena/.venv/bin:${PATH}"
# Entrypoint to ensure environment is activated
ENTRYPOINT ["/bin/bash", "-c", "source .venv/bin/activate && $0 $@"]
```
## /README-dev.md
# Developer Instructions
## Python Environment & Development Tools
See [the contributing guide](CONTRIBUTING.md) for instructions on setting up your development environment
and tools for formatting and type checking.
## Release Process
1. Ensure clean git status.
2. Set the version for release, e.g.
python scripts/bump_version.py --patch
python scripts/bump_version.py --minor
This also creates the git tag.
3. Push to GitHub:
git push
git push --tags
Pushing the tag triggers the `create-release` workflow, which creates a
**draft release** on GitHub.
4. Review the draft release on the
[GitHub Releases page](https://github.com/oraios/serena/releases).
When ready, publish it (click *Publish release*).
This triggers the `publish` workflow, which builds and publishes the
package to PyPI.
## /README.md
<p align="center" style="text-align:center;">
<img src="resources/serena-logo.svg#gh-light-mode-only" style="width:500px">
<img src="resources/serena-logo-dark-mode.svg#gh-dark-mode-only" style="width:500px">
</p>
<h3 align="center">
The IDE for Your Coding Agent
</h3>
<div align="center">
<a href="https://discord.com/invite/cVUNQmnV4r"><img src="https://img.shields.io/badge/discord-join-5865F2?style=flat-square&labelColor=0a0e14&logo=discord&logoColor=5865F2" alt="discord"></a>
<a href="https://github.com/oraios/serena/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-b0e8ff?style=flat-square&labelColor=0a0e14" alt="license"></a>
</div>
<br>
* Serena provides essential **semantic code retrieval, editing, refactoring and debugging tools** that are akin to an IDE's capabilities,
operating at the symbol level and exploiting relational structure.
* It integrates with any client/LLM via the model context protocol (**MCP**).
Serena's **agent-first tool design** involves robust high-level abstractions, distinguishing it from
approaches that rely on low-level concepts like line numbers or primitive search patterns.
Practically, this means that your agent operates **faster, more efficiently and more reliably**, especially in larger and
more complex codebases.
> [!IMPORTANT]
> Do not install Serena via an MCP or plugin marketplace! They contain outdated and suboptimal installation commands.
> Instead, follow our [Quick Start](#quick-start) instructions.
## Quick Demo
https://github.com/user-attachments/assets/8d11646e-b80e-4723-b9d7-32d6101b5f58
:tv: Longer video: [Introduction to Serena in 5 Minutes (YouTube)](https://www.youtube.com/watch?v=5QN7gN1KYLA)
## What Our "End Users" Say
While it is humans who download and set up Serena, our end users are essentially AI agents.
As the ones actually applying Serena's tools, they are in the best position to evaluate Serena.
We crafted an unbiased evaluation prompt that leads the agent to perform ~20 routine coding tasks,
representative of everyday development work,
in order to estimate the value added by Serena's tools when used alongside its own built-ins.
Here's a one-sentence summary of what the agents had to say:
**Opus 4.6 (high) in Claude Code on a large Python codebase:**
> "Serena's IDE-backed semantic tools are the single most impactful addition to my toolkit – cross-file renames, moves, and reference lookups that
would cost me 8–12 careful, error-prone steps collapse into one atomic call, and I would absolutely ask any developer I work with to set them up."
**GPT 5.4 (high) in Codex CLI on a Java codebase:**
> "As a coding AI agent, I would ask my owner to add Serena because it gives me the missing IDE-level understanding of symbols, references, and
refactorings, turning fragile text surgery into calmer, faster, more confident code changes where semantics matter."
**GPT 5.4 (medium) in Copilot CLI on a large, multi-language monorepo:**
> "As a coding agent, I’d absolutely ask my owner to add Serena because it makes me noticeably sharper and calmer on
real code – especially symbol-aware navigation, cross-file refactors, and monorepo dependency jumps – while I still lean
on built-ins for tiny text edits and non-code work."
Different agents in different settings independently converge on the same verdict.
_Give your agent the tools it has been asking for and add Serena MCP to your client!_
See our [documentation](https://oraios.github.io/serena/04-evaluation/000_evaluation-intro.html) for the full methodology and much more detailed evaluation results, or run your own evaluation on a project of your choice.
## How Serena Works
Serena provides the necessary [tools](https://oraios.github.io/serena/01-about/035_tools.html) for coding workflows,
but an LLM is required to do the actual work, orchestrating tool use.
Serena can extend the functionality of your existing AI client via the **model context protocol (MCP)**.
Most modern AI chat clients directly support MCP, including
* terminal-based clients like Claude Code, Codex, OpenCode, or Gemini-CLI,
* IDEs and IDE assistant plugins for VSCode, Cursor and JetBrains IDEs (Copilot, Junie, JetBrains AI Assistant, etc.),
* desktop and web clients like Claude Desktop, Codex App, or OpenWebUI.
<img src="resources/serena-block-diagram.svg">
:tv: See also: [Introduction to Serena in 5 Minutes (YouTube)](https://www.youtube.com/watch?v=5QN7gN1KYLA)
To connect the Serena MCP server to your client, you either
* provide the client with a launch command that allows it to start the MCP server, or
* start the Serena MCP server yourself in HTTP mode and provide the client with the URL.
See the [Quick Start](#quick-start) section below for information on how to get started.
## Programming Language Support & Semantic Analysis Capabilities
Serena provides a set of versatile code querying and editing functionalities
based on symbolic understanding of the code.
Equipped with these capabilities, your agent discovers and edits code just like a seasoned developer
making use of an IDE's capabilities would.
Serena can efficiently find the right context and do the right thing even in very large and
complex projects!
There are two alternative technologies powering these capabilities:
* **Language servers** implementing the language server protocol (LSP) — the free/open-source alternative
which is used by default.
* **The Serena JetBrains Plugin**, which leverages the powerful code analysis and editing
capabilities of your JetBrains IDE (paid plugin; free trial available).
You can choose either of these backends depending on your preferences and requirements.
### Language Servers
Serena incorporates a powerful abstraction layer for the integration of language servers that implement the language server protocol (LSP).
The underlying language servers are typically open-source projects or at least freely available for use.
When using Serena's language server backend, we provide **support for over 40 programming languages**, including
Ada / SPARK, AL, Angular, Ansible, Bash, BSL, C#, C/C++, Clojure, Crystal, Dart, Elixir, Elm, Erlang, Fortran, F#, GDScript, GLSL, Go, Groovy, Haskell, Haxe, HLSL, HTML, Java, JavaScript, JSON, Julia, Kotlin, Lean 4, Lua, Luau, Markdown, MATLAB, mSL, Nix, OCaml, Perl, PHP, PowerShell, Python, R, Ruby, Rust, Scala, SCSS / Sass / CSS, Solidity, Svelte, Swift, TOML, TypeScript, WGSL, YAML, and Zig.
### The Serena JetBrains Plugin
The paid Serena JetBrains Plugin (free trial available)
leverages the powerful code analysis capabilities of your JetBrains IDE.
The plugin naturally supports all programming languages and frameworks that are supported by JetBrains IDEs,
including IntelliJ IDEA, PyCharm, Android Studio, WebStorm, PhpStorm, RubyMine, GoLand, and potentially others (Rider and CLion are unsupported though).
<a href="https://plugins.jetbrains.com/plugin/28946-serena/"><img src="docs/_static/images/jetbrains-marketplace-button.png"></a>
See our [documentation page](https://oraios.github.io/serena/02-usage/025_jetbrains_plugin.html) for further details and instructions on how to apply the plugin.
## Features
Serena provides a wide range of tools for efficient code retrieval, editing and refactoring, as well as
a memory system for long-lived agent workflows.
Given its large scope, Serena adapts to your needs by offering a multi-layered configuration system.
<details>
<summary>Details</summary>
### Retrieval
Serena's retrieval tools allow agents to explore codebases at the symbol level, understanding structure and relationships
without reading entire files.
| Capability | Language Servers | JetBrains Plugin |
|----------------------------------|------------------|------------------|
| find symbol | yes | yes |
| symbol overview (file outline) | yes | yes |
| find referencing symbols | yes | yes |
| search in project dependencies | -- | yes |
| type hierarchy | -- | yes |
| find declaration | yes* | yes |
| find implementations | yes** | yes |
| query external projects | yes | yes |
| diagnostics/inspections | yes | yes |
*: Will generally not work for declarations in external dependencies. <br>
**: Only available for some languages, limited by the language server functionality.
### Refactoring
Without precise refactoring tools, agents are forced to resort to unreliable and expensive search and replace operations.
| Capability | Language Servers | JetBrains Plugin |
|-------------------------------------------|--------------------|-----------------------------------|
| rename | yes (only symbols) | yes (symbols, files, directories) |
| move (symbol, file, directory) | -- | yes |
| inline | -- | yes |
| propagate deletions (remove unused code) | -- | yes |
### Symbolic Editing
Serena's symbolic editing tools are less error-prone and much more token-efficient than typical alternatives.
| Capability | Language Servers | JetBrains Plugin |
|------------------------|-------------------|------------------|
| replace symbol body | yes | yes |
| insert after symbol | yes | yes |
| insert before symbol | yes | yes |
| safe delete | yes | yes |
### Interactive Debugging
Exclusive to the JetBrains plugin, Serena supports a highly general debugging tool,
which allows an agent to set breakpoints, inspect variables, evaluate expressions and control execution flow
via a persistent REPL-style interface.
### Basic Features
Beyond its semantic capabilities, Serena includes a set of basic utilities for completeness.
When Serena is used inside an agentic harness such as Claude Code or Codex, these tools are typically disabled by default,
since the surrounding harness already provides overlapping file, search, and shell capabilities.
- **`search_for_pattern`** – flexible regex search across the codebase
- **`replace_content`** – agent-optimised regex-based and literal text replacement
- **`list_dir` / `find_file`** – directory listing and file search
- **`read_file`** – read files or file chunks
- **`execute_shell_command`** – run shell commands (e.g. builds, tests, linters)
### Memory Management
A memory system is elemental to long-lived agent workflows, especially when knowledge is to be shared across
sessions, users and projects.
Despite its simplicity, we received positive feedback from many users who tend to combine Serena's memory management system with their
agent's internal system (e.g., `AGENTS.md` files).
It can easily be disabled if you prefer to use something else.
### Configurability
Active tools, tool descriptions, prompts, language backend details and many other aspects of Serena
can be flexibly configured on a per-case basis by simply adjusting a few lines of YAML.
To achieve this, Serena offers multiple levels of (composable) configuration:
* global configuration
* MCP launch command (CLI) configuration
* per-project configuration (with local overrides)
* execution context-specific configuration (e.g. for particular clients)
* dynamically composable configuration fragments (modes)
</details>
## Quick Start
**Prerequisites**. Serena is managed by *uv*, and [installing uv](https://docs.astral.sh/uv/getting-started/installation/) is the only required prerequisite.
> [!NOTE]
> When using the language server backend, some additional dependencies may need to be installed to support certain languages;
> see the [Language Support](https://oraios.github.io/serena/01-about/020_programming-languages.html) page for details.
**Install Serena**. Serena is installed via uv as follows:
```bash
uv tool install -p 3.13 serena-agent@latest --prerelease=allow
```
After successful installation, the command `serena` should be available in your shell.
**Initialise Serena**. To initialise Serena and verify that your setup works correctly, simply run:
```bash
serena init
```
By default, this will set up Serena to use the language server backend. To use the JetBrains backend instead, add the parameters `-b JetBrains`
(see the [JetBrains Plugin documentation page](https://oraios.github.io/serena/02-usage/025_jetbrains_plugin.html) for additional usage details).
Either way, you should receive a success message indicating that Serena has been initialised successfully.
**Configuring Your Client**. To connect Serena to your preferred MCP client, you typically need to [configure a launch command in your client](https://oraios.github.io/serena/02-usage/030_clients.html).
Follow the link for specific instructions on how to set up Serena for Claude Code, Codex, Claude Desktop, MCP-enabled IDEs and other clients (such as local and web-based GUIs).
> [!TIP]
> While getting started quickly is easy, Serena is a powerful toolkit with many configuration options.
> We highly recommend reading through the [user guide](https://oraios.github.io/serena/02-usage/000_intro.html) to get the most out of Serena.
>
> Specifically, we recommend to read about ...
> * [Serena's project-based workflow](https://oraios.github.io/serena/02-usage/040_workflow.html) and
> * [configuring Serena](https://oraios.github.io/serena/02-usage/050_configuration.html).
## User Guide
Please refer to the [user guide](https://oraios.github.io/serena/02-usage/000_intro.html) for detailed instructions on how to use Serena effectively.
## Acknowledgements
A significant part of Serena, especially support for various languages, was contributed by the open source community.
We are very grateful for the many contributors who made this possible and who played an important role in making Serena
what it is today.
## /compose.yaml
```yaml path="/compose.yaml"
services:
serena:
image: serena:latest
# To work with projects, you must mount them into /workspace/ in the container:
# volumes:
# - ./my-project:/workspace/my-project
# - /path/to/another/project:/workspace/another-project
build:
context: ./
dockerfile: Dockerfile
target: production
ports:
- "${SERENA_PORT:-9121}:9121" # MCP server port
- "${SERENA_DASHBOARD_PORT:-24282}:24282" # Dashboard port (default 0x5EDA = 24282)
environment:
- SERENA_DOCKER=1
command:
- "uv run --directory . serena-mcp-server --transport sse --port 9121 --host 0.0.0.0"
# Alternatively add further arguments, e.g. a context
# - "uv run --directory . serena-mcp-server --transport sse --port 9121 --host 0.0.0.0 --context ide"
```
## /docker_build_and_run.sh
```sh path="/docker_build_and_run.sh"
#!/usr/bin/bash
docker build -t serena .
docker run -it --rm -v "$(pwd)":/workspace serena
```
## /docs/.gitignore
```gitignore path="/docs/.gitignore"
/_toc.yml
/jupyter_execute
/conf.py
/_build
```
## /docs/01-about/.gitignore
```gitignore path="/docs/01-about/.gitignore"
# auto-generated files
/000_intro.md
/025_features.md
/035_tools.md
```
## /docs/01-about/020_programming-languages.md
# Language Support
Serena provides a set of versatile code querying and editing functionalities
based on symbolic understanding of the code across a wide range of programming languages.
Equipped with these capabilities, Serena discovers and edits code just like a seasoned developer
making use of an IDE's capabilities would.
Serena can efficiently find the right context and do the right thing even in very large and
complex projects!
There are two alternative technologies powering these capabilities:
* **Language servers** implementing the language server Protocol (LSP) — the free/open-source alternative.
* **The Serena JetBrains Plugin**, which leverages the powerful code analysis and editing
capabilities of your JetBrains IDE.
See the [Features](025_features) section for a detailed comparison of the capabilities provided by the JetBrains Plugin vs. language servers.
(language-servers)=
## Language Servers
Serena incorporates a powerful abstraction layer for the integration of language servers
that implement the language server protocol (LSP).
It even supports multiple language servers in parallel to support polyglot projects.
The language servers themselves are typically open-source projects (like Serena)
or at least freely available for use.
We currently provide direct, out-of-the-box support for the programming languages listed below.
Some languages require additional installations or setup steps, as noted.
* **Ada / SPARK**
(uses AdaCore's [Ada Language Server (ALS)](https://github.com/AdaCore/ada_language_server),
automatically downloaded; supports `.ads`, `.adb`, and `.ada` files;
works best with a `.gpr` GNAT project file at the repository root;
SPARK is handled by the same server transparently — set language `ada` for both.
To use a pre-installed ALS (e.g. from Alire, GNAT Studio, or the VS Code Ada extension),
set `ls_specific_settings.ada.ls_path`.)
* **AL**
* **Angular**
(experimental; requires Node.js + npm, plus `npm install` having been run in the project root so that `@angular/core`
is resolvable — without it, template-aware features silently return empty;
subsumes `typescript` and `html` for `.ts`/`.html` files, so do not also list those)
* **Ansible**
(experimental; requires Node.js and npm; automatically installs `@ansible/ansible-language-server`;
must be explicitly specified in the `languages` entry in the `project.yml`; requires `ansible` in PATH for full functionality)
the upstream `@ansible/ansible-language-server@1.2.3` supports hover, completion, definition,
semantic tokens, and validation; document symbols, workspace symbols, references, and rename
are not supported by this version)
* **Bash**
* **BSL** (1C:Enterprise / OneScript)
(requires Java 21+ on PATH; uses [bsl-language-server](https://github.com/1c-syntax/bsl-language-server) by 1c-syntax; the JAR is auto-downloaded and SHA-256-verified for the bundled default version; supports `.bsl` and `.os` files; configure optional `ls_path` or `bsl_ls_version` under `ls_specific_settings.bsl`)
* **C#**
(by default, uses the Roslyn language server (language `csharp`), requiring [.NET v10+](https://dotnet.microsoft.com/en-us/download/dotnet) and, on Windows, `pwsh` ([PowerShell 7+](https://learn.microsoft.com/en-us/powershell/scripting/install/install-powershell-on-windows?view=powershell-7.5));
set language to `csharp_omnisharp` to use OmiSharp instead)
* **C/C++**
(by default, uses the clangd language server (language `cpp`) but we also support ccls (language `cpp_ccls`);
for best results, provide a `compile_commands.json` at the repository root;
see the [C/C++ Setup Guide](../03-special-guides/cpp_setup) for details.)
* **Clojure**
* **Crystal**
(requires [Crystalline](https://github.com/elbywan/crystalline) language server to be installed and available on PATH;
note: Crystalline has limited go-to-definition support and does not support find-references)
* **Dart**
* **Elixir**
(requires Elixir installation; Expert language server is downloaded automatically)
* **Elm**
(requires Elm compiler)
* **Erlang**
(requires installation of beam and [erlang_ls](https://github.com/erlang-ls/erlang_ls); experimental, might be slow or hang)
* **F#**
(requires [.NET v8.0+](https://dotnet.microsoft.com/en-us/download/dotnet); uses FsAutoComplete/Ionide, which is auto-installed; for Homebrew .NET on macOS, set DOTNET_ROOT in your environment)
* **Fortran**
(requires installation of fortls: `pip install fortls`)
* **GDScript** (Godot Engine)
(requires the Godot editor to be running with its built-in LSP enabled — default on port 6008;
Serena connects over TCP and does not launch Godot itself;
see the [GDScript Setup Guide](../03-special-guides/godot_gdscript_setup_guide_for_serena) for details)
* **Go**
(requires installation of `gopls`)
* **Groovy**
(requires local groovy-language-server.jar setup via `GROOVY_LS_JAR_PATH` or configuration)
* **Haskell**
(automatically locates HLS via ghcup, stack, or system PATH; supports Stack and Cabal projects)
* **Haxe**
(requires Haxe compiler 3.4.0+ and Node.js; uses the [vshaxe language server](https://github.com/vshaxe/haxe-language-server);
automatically downloaded from Open VSX, or discovered from the vshaxe VSCode extension)
* **HLSL / GLSL / WGSL**
(uses [shader-language-server](https://github.com/antaalt/shader-sense) (language `hlsl`); automatically downloaded;
on macOS, requires Rust toolchain for building from source;
note: reference search is not supported by this language server)
* **HTML**
(experimental; requires Node.js + npm)
* **Java**
* **JavaScript**
(supported via the TypeScript language server, i.e. use language `typescript` for both JavaScript and TypeScript)
* **Julia**
* **Kotlin**
(uses the pre-alpha [official kotlin LS](https://github.com/Kotlin/kotlin-lsp), some issues may appear)
* **Lean 4**
(requires `lean` and `lake` installed via [elan](https://github.com/leanprover/elan); uses the built-in Lean 4 LSP;
the project must be a Lake project with `lake build` run before use)
* **Lua**
* **Luau**
* **Markdown**
(must explicitly enable language `markdown`, primarily useful for documentation-heavy projects)
* **mSL** (mIRC Scripting Language)
(auto-installed; no external dependencies required — uses a custom pygls-based LSP server shipped with Serena;
supports document symbols, workspace symbols, references, and go-to-definition for aliases, events, menus, dialogs, and CTCP handlers in `.mrc` files)
* **Nix**
(requires nixd installation)
* **OCaml**
(requires opam and ocaml-lsp-server to be installed manually; see the [OCaml Setup Guide](../03-special-guides/ocaml_setup_guide_for_serena.md))
* **Pascal**
(uses Pascal/Lazarus, which is automatically downloaded; set `PP` and `FPCDIR` environment variables for source navigation)
* **Perl**
(requires installation of Perl::LanguageServer)
* **PHP**
(by default, uses the Intelephense language server (language `php`), set `INTELEPHENSE_LICENSE_KEY` environment variable for premium features;
we also support [Phpactor](https://github.com/phpactor/phpactor) (language `php_phpactor`), which requires PHP 8.1+)
* **Python**
* **R**
(requires installation of the `languageserver` R package)
* **Ruby**
(by default, uses [ruby-lsp](https://github.com/Shopify/ruby-lsp) (language `ruby`); use language `ruby_solargraph` to use Solargraph instead.)
* **Rust**
(requires [rustup](https://rustup.rs/) - uses rust-analyzer from your toolchain)
* **Scala**
(requires some [manual setup](../03-special-guides/scala_setup_guide_for_serena); uses Metals LSP)
* **SCSS / Sass / CSS**
(experimental; requires Node.js + npm; uses [some-sass-language-server](https://github.com/wkillerud/some-sass) to handle
`.scss`, `.sass`, and `.css`)
* **Solidity**
(experimental; requires Node.js and npm; automatically installs `@nomicfoundation/solidity-language-server`;
works best with a `foundry.toml` or `hardhat.config.js` in the project root)
* **Svelte**
(requires Node.js v18+ and npm; supports `.svelte` Single File Components plus TypeScript/JavaScript files via `svelte-language-server`; a companion `typescript-language-server` + `typescript-svelte-plugin` is spawned automatically for cross-file rename, go-to-definition, and references across `.ts`/`.js` and `.svelte` files; use language `svelte` for Svelte projects instead of also enabling `typescript`)
* **Swift**
* **TypeScript**
* **Vue**
(3.x with TypeScript; requires Node.js v18+ and npm; supports .vue Single File Components with monorepo detection)
* **YAML**
* **JSON**
(experimental; must be explicitly added to the languages list; requires Node.js and npm)
* **Zig**
(requires installation of ZLS - Zig Language Server)
Support for further languages can easily be added by providing a shallow adapter for a new language server implementation,
see Serena's [memory on that](https://github.com/oraios/serena/blob/main/.serena/memories/adding_new_language_support_guide.md).
## The Serena JetBrains Plugin
The [Serena JetBrains Plugin](https://plugins.jetbrains.com/plugin/28946-serena/) leverages the powerful code analysis capabilities of JetBrains IDEs.
The plugin naturally supports all programming languages and frameworks that are supported by JetBrains IDEs.
When using the plugin, Serena connects to an instance of your JetBrains IDE via the plugin. For users who already
work in a JetBrains IDE, this means Serena seamlessly integrates with the IDE instance you typically have open anyway,
requiring no additional setup or configuration beyond the plugin itself.
* See the [JetBrains Plugin documentation](../02-usage/025_jetbrains_plugin) for a high-level overview of its benefits and usage details.
* See the [Features](025_features) section for a detailed comparison of the capabilities provided by the JetBrains Plugin vs. language servers.
```{raw} html
<p>
<a href="https://plugins.jetbrains.com/plugin/28946-serena/">
<img style="background-color:transparent;" src="../_static/images/jetbrains-marketplace-button.png">
</a>
</p>
```
## /docs/01-about/030_serena-in-action.md
# Serena in Action
## Demonstration 1: Efficient Operation in Claude Code
A demonstration of Serena efficiently retrieving and editing code within Claude Code, thereby saving tokens and time. Efficient operations are not only useful for saving costs, but also for generally improving the generated code's quality. This effect may be less pronounced in very small projects, but often becomes of crucial importance in larger ones.
<video src="https://github.com/user-attachments/assets/ab78ebe0-f77d-43cc-879a-cc399efefd87"
controls
preload="metadata"
style="max-width: 100%; height: auto;">
Your browser does not support the video tag.
</video>
## Demonstration 2: Serena in Claude Desktop
A demonstration of Serena implementing a small feature for itself (a better log GUI) with Claude Desktop.
Note how Serena's tools enable Claude to find and edit the right symbols.
<video src="https://github.com/user-attachments/assets/6eaa9aa1-610d-4723-a2d6-bf1e487ba753"
controls
preload="metadata"
style="max-width: 100%; height: auto;">
Your browser does not support the video tag.
</video>
## /docs/01-about/050_acknowledgements.md
# Acknowledgements
## Sponsors
We are very grateful to our [sponsors](https://github.com/sponsors/oraios), who help us drive Serena's development.
The core team (the founders of [Oraios AI](https://oraios-ai.de/)) put in a lot of work in order to turn Serena into a useful open source project.
So far, there is no business model behind this project, and sponsors are our only source of income from it.
Sponsors help us dedicate more time to the project, managing contributions, and working on larger features (like better tooling based on more advanced
LSP features, VSCode integration, debugging via the DAP, and several others).
If you find this project useful to your work, or would like to accelerate the development of Serena, consider becoming a sponsor.
We are proud to announce that the Visual Studio Code team, together with Microsoft’s Open Source Programs Office and GitHub Open Source
have decided to sponsor Serena with a one-time contribution!
## Community Contributions
A significant part of Serena, especially support for various languages, was contributed by the open source community.
We are very grateful for the many contributors who made this possible and who played an important role in making Serena
what it is today.
## Technologies
We built Serena on top of multiple existing open-source technologies, the most important ones being:
1. [multilspy](https://github.com/microsoft/multilspy).
A library which wraps language server implementations and adapts them for interaction via Python
and which provided the basis for our library Solid-LSP (src/solidlsp).
Solid-LSP provides pure synchronous LSP calls and extends the original library with the symbolic logic
that Serena required.
2. [Python MCP SDK](https://github.com/modelcontextprotocol/python-sdk)
3. All the language servers that we use through Solid-LSP.
Without these projects, Serena would not have been possible (or would have been significantly more difficult to build).
## /docs/02-usage/000_intro.md
# Usage
Serena can be used in various ways and supports coding workflows through a project-based approach.
Its configuration is flexible and allows tailoring it to your specific needs.
In this section, you will find general usage instructions as well as concrete instructions for selected integrations.
## /docs/02-usage/010_installation.md
# Installation
## Prerequisites
**Package Manager: uv**
Serena is managed by `uv`.
If you do not have it yet, install it following the instructions [here](https://docs.astral.sh/uv/getting-started/installation/).
**Language-Specific Requirements**
When using the language server backend, some additional dependencies may need to be installed
to support certain languages.
See the [Language Support](language-servers) page for the list of supported languages.
Many dependencies are installed by Serena on the fly, but if a language requires dependencies
to be provided manually, this is mentioned in the notes below the respective language.
(install-serena)=
## Installing and Initialising Serena
With `uv` installed and on your PATH, install Serena with this command:
uv tool install -p 3.13 serena-agent@latest --prerelease=allow
Upon completion, the command `serena` should be available in your terminal.
To test the installation and initialise Serena, run one of the following commands:
* `serena init`
if you intend to use the default language intelligence backend (language servers)
* `serena init -b JetBrains`
if you intend to use the JetBrains backend (which uses the [JetBrains plugin](025_jetbrains_plugin))
Note that you can switch backends at any time via Serena's [configuration](050_configuration).
## Updating Serena
To update Serena to the latest version, run:
uv tool upgrade serena-agent --prerelease=allow
:::{tip}
To keep informed about updates, make sure you regularly open [Serena's Dashboard](060_dashboard),
where we will announce releases along with the new features and improvements they bring.
:::
## Uninstalling Serena
Serena can be uninstalled with the following command:
uv tool uninstall serena-agent
## /docs/02-usage/020_running.md
# Running Serena
Serena is a command-line tool with a variety of sub-commands.
This section describes
* how to run Serena in general
* how to run and configure the most important command, i.e. starting the MCP server
* other useful commands.
The main way to run Serena is to use the [installed version](install-serena),
which should be available in your system PATH as `serena.`
In general, to get help, append `--help` to the command, i.e.
serena --help
serena <command> --help
(start-mcp-server)=
## Running the MCP Server
Given your preferred method of running Serena, you can start the MCP server using the `start-mcp-server` command:
serena start-mcp-server [options]
Note that no matter how you run the MCP server, Serena will, by default, start a web-based dashboard on localhost that will allow you to inspect
the server's operations, logs, and configuration.
:::{tip}
By default, Serena will use language servers for code understanding and analysis.
With the [Serena JetBrains Plugin](025_jetbrains_plugin), we recently introduced a powerful alternative,
which has several advantages over the language server-based approach.
:::
### Standard I/O Mode
The typical usage involves the client (e.g. Claude Code, Codex or Cursor) running
the MCP server as a subprocess and using the process' stdin/stdout streams to communicate with it.
In order to launch the server, the client thus needs to be provided with the command to run the MCP server.
:::{note}
MCP servers which use stdio as a protocol are somewhat unusual as far as client/server architectures go, as the server
necessarily has to be started by the client in order for communication to take place via the server's standard input/output streams.
In other words, you do not need to start the server yourself. The client application (e.g. Claude Desktop) takes care of this and
therefore needs to be configured with a launch command.
:::
Communication over stdio is the default for the Serena MCP server, so in the simplest
case, you can simply run the `start-mcp-server` command without any additional options.
serena start-mcp-server
See the section ["Configuring Your MCP Client"](030_clients) for specific information on how to configure your MCP client (e.g. Claude Code, Codex, Cursor, etc.)
to use such a launch command.
(streamable-http)=
### Streamable HTTP Mode
When using *Streamable HTTP* mode, you control the server lifecycle yourself,
i.e. you start the server and provide the client with the URL to connect to it.
Simply provide `start-mcp-server` with the `--transport streamable-http` option and optionally provide the desired port
via the `--port` option.
For example, to start the server on port 9121, run
serena start-mcp-server --transport streamable-http --port <port>
and then configure your client to connect to `http://localhost:9121/mcp`.
By default, only connections from localhost are allowed; pass the `--host <listen_address>` option to configure
the listen address and allow remote connections if needed (but be aware of the security implications of doing so).
**When to use.** Note that Serena is a stateful MCP server, and only one coding project can be active at a time.
Therefore, starting a single Serena instance and connecting it to multiple clients is only
appropriate if all clients will be working on the same project.
If you want several agents to work on different projects, making each client/agent start its own server
in stdio mode is likely the best option.
See section [The Project Workflow](040_workflow) for more information on how to manage projects in Serena.
The legacy SSE transport is also supported (via `--transport sse` with corresponding /sse endpoint), its use is discouraged.
(mcp-args)=
### MCP Server Command-Line Arguments
The Serena MCP server supports a wide range of additional command-line options.
Use the command
<serena> start-mcp-server --help
to get a list of all available options.
Some useful options include:
* `--project <path|name>`: specify the project to work on by name or path.
* `--project-from-cwd`: auto-detect the project from current working directory
(looking for a directory containing `.serena/project.yml` or `.git` in parent directories and activating the containing directory as the project root, if any).
This option is intended for CLI-based agents like Claude Code, Gemini and Codex, which are typically started from within the project directory
and which do not change directories during their operation.
* `--language-backend JetBrains`: use the Serena JetBrains Plugin as the language backend (overriding the default backend configured in the central configuration)
* `--context <context>`: specify the operation [context](contexts) in which Serena shall operate
* `--mode <mode>`: specify one or more [modes](modes) to enable (can be passed several times)
* `--open-web-dashboard <true|false>`: whether to open the web dashboard on startup (enabled by default)
## Other Commands
Serena provides several other commands in addition to `start-mcp-server`,
most of which are related to project setup and configuration.
To get a list of available commands, run:
<serena> --help
To get help on a specific command, run:
<serena> <command> --help
In general, add `--help` to any command or sub-command to get information about its usage and available options.
Here are some examples of commands you might find useful:
```bash
# get help about a sub-command
serena> tools list --help
# list all available tools
serena> tools list --all
# get detailed description of a specific tool
serena> tools description find_symbol
# creating a new Serena project in the current directory
serena project create
# creating and immediately indexing a project
serena project create --index
# indexing the project in the current directory (auto-creates if needed)
serena project index
# run a health check on the project in the current directory
serena project health-check
# check if a path is ignored by the project
serena project is_ignored_path path/to/check
# edit Serena's configuration file
serena config edit
# list available contexts
serena context list
# create a new context
serena context create my-custom-context
# edit a custom context
serena context edit my-custom-context
# list available modes
serena mode list
# create a new mode
serena mode create my-custom-mode
# edit a custom mode
serena mode edit my-custom-mode
# list available prompt definitions
serena prompts list
# create an override for internal prompts
serena prompts create-override prompt-name
# edit a prompt override
serena prompts edit-override prompt-name
```
Explore the full set of commands and options using the CLI itself!
## Alternative Ways of Running Serena
Depending on your requirements, you may want to run Serena in different ways.
When applying one of these approaches, replace `serena` in commands mentioned throughout the documentation
with the respective command and options. The same applies to `serena-hooks` commands.
### Using uvx to Run the Latest Source Version
`uvx` is part of `uv`. It can be used to run the latest version of Serena directly from the repository, without an explicit local installation.
uvx -p 3.13 --from git+https://github.com/oraios/serena serena
This was previously the main way of running Serena.
Since this has the downside that every new commit in the repository will trigger a (potentially slow) re-synchronization, an [installation](010_installation) of Serena should usually be preferred.
If you should experience timeouts when connecting the MCP server, consider switching.
If, however, the synchronisation is fast enough for you, this is still a good option.
### Running from Cloned Source
1. Clone the repository and change into it.
```shell
git clone https://github.com/oraios/serena
cd serena
```
2. Run Serena via
```shell
uv run serena
```
when within the serena installation directory.
From other directories, run it with the `--directory` option, i.e.
```shell
uv run --directory /abs/path/to/serena serena
```
:::{note}
Adding the `--directory` option results in the working directory being set to the Serena directory.
As a consequence, you will need to specify paths when using CLI commands that would otherwise operate on the current directory.
:::
(docker)=
### Using Docker
The Docker approach offers several advantages:
* better security isolation for shell command execution
* no need to install language servers and dependencies locally
* consistent environment across different systems
You can run the Serena MCP server directly via Docker as follows,
assuming that the projects you want to work on are all located in `/path/to/your/projects`:
```shell
docker run --rm -i --network host -v /path/to/your/projects:/workspaces/projects ghcr.io/oraios/serena:latest serena
```
This command mounts your projects into the container under `/workspaces/projects`, so when working with projects,
you need to refer to them using the respective path (e.g. `/workspaces/projects/my-project`).
Alternatively, you may use Docker compose with the `compose.yml` file provided in the repository.
See our [advanced Docker usage](https://github.com/oraios/serena/blob/main/DOCKER.md) documentation for more detailed instructions, configuration options, and limitations.
:::{note}
Docker usage is subject to limitations; see the [advanced Docker usage](https://github.com/oraios/serena/blob/main/DOCKER.md) documentation for details.
:::
### Using Nix to Run the Latest Source Version
If you are using Nix and [have enabled the `nix-command` and `flakes` features](https://nixos.wiki/wiki/flakes), you can run Serena using the following command:
```bash
nix run github:oraios/serena -- <command> [options]
```
You can also install Serena by referencing this repo (`github:oraios/serena`) and using it in your Nix flake. The package is exported as `serena`.
## /docs/02-usage/025_jetbrains_plugin.md
# The Serena JetBrains Plugin
The [JetBrains Plugin](https://plugins.jetbrains.com/plugin/28946-serena/) allows the Serena MCP server to
leverage the powerful code analysis and editing capabilities of your JetBrains IDE.
This page explains how to install the plugin and how to configure Serena appropriately.
You will still need to set up the Serena MCP server
itself, so make sure to follow the [installation instructions](020_running.md) and connect the MCP server to your
LLM-based client as described in [client setup](030_clients.md) in addition to following the instructions below.
```{raw} html
<p>
<a href="https://plugins.jetbrains.com/plugin/28946-serena/">
<img style="background-color:transparent;" src="../_static/images/jetbrains-marketplace-button.png">
</a>
</p>
```
We recommend the JetBrains plugin as the preferred way of using Serena,
especially for users of JetBrains IDEs.
**How it works:**
1. Install the plugin in your JetBrains IDE
2. Configure Serena to use the JetBrains language backend (see [below](configure-jetbrains))
3. Open the project you want to work on in your JetBrains IDE and activate it in Serena (see [below](jetbrains-workflow))
4. Start coding via your MCP client as usual
```{admonition} *Note:* The plugin is a language intelligence backend for the Serena MCP server.
:class: note
It is *not* a UI extension for direct agent interaction (like Copilot) or anything of the sort.
You still interact with your regular client – be it external to your IDE (like Claude Code CLI) or internal (like Copilot or JetBrains AI Assistant) –
and connect it to the Serena MCP server.
The plugin simply enables the Serena MCP server to directly leverage capabilities of your JetBrains IDE!
```
**Purchasing the JetBrains Plugin supports the Serena project.**
The proceeds from plugin sales allow us to dedicate more resources to further developing and improving Serena.
## Advantages of the JetBrains Plugin
There are multiple features that are only available when using the JetBrains plugin:
* **External library indexing**: Dependencies and libraries are fully indexed and accessible to Serena
* **Enhanced retrieval & refactoring capabilities**: The plugin adds additional [tools](../01-about/035_tools) (e.g. type
hierarchy retrieval, move, find declaration, inline symbol, etc.)
and transforms the underlying mechanisms of shared tools to build upon the IDE's capabilities.
* **Interactive debugging**: The agent can set breakpoints, inspect variables, evaluate expressions and control execution flow
by directly interacting with the IDE's debugger, using a REPL-style interface for maximum flexibility.
* **Improved multi-agent support**: A single IDE instance naturally serves arbitrarily many agent sessions without requiring additional resources.
* **Enhanced performance**: Faster tool execution thanks to optimized IDE integration.
* **Multi-language excellence** and **framework support**: First-class support for polyglot projects with multiple languages.
and frameworks (whatever is recognised by your IDE as a symbol will also be available to Serena)
* **No additional setup**: No need to download or configure separate language servers.
We are also working on additional features like debugging and advanced introspection capabilities, which
will be available exclusively through the JetBrains plugin.
:::{note}
With Serena's JetBrains tools, we try to offer the latest features.
As a result, some of them are considered as beta features (see [tool list](../01-about/035_tools)), which may have some quirks.
Please report your experience with these tools if they do not work as expected.
:::
(configure-jetbrains)=
## Configuring Serena to Use the JetBrains Plugin
After installing the plugin, you need to configure Serena to use it.
**Central Configuration**.
You can run
```shell
serena init -b JetBrains
```
to set the default code intelligence backend to JetBrains in the global Serena configuration file.
Alternatively, manually edit the configuration file `~/.serena/serena_config.yml`
(`%USERPROFILE%\.serena\serena_config.yml` on Windows) and set
```yaml
language_backend: JetBrains
```
Note that the file might not exist yet if you never executed Serena before.
**Per-Server Instance Configuration**.
The configuration setting in the global config file can be overridden on a
per-instance basis by providing the arguments `--language-backend JetBrains` when
launching the Serena MCP server.
(per-project-language-backend)=
**Per-Project Configuration**.
You can also set the language backend on a per-project basis in the project's
`.serena/project.yml` file:
```yaml
language_backend: JetBrains
```
If set, this overrides the global `language_backend` setting for the session when the project is
activated at startup (via the `--project` flag).
:::{important}
The language backend is determined once at startup and cannot be changed during a running session.
If a project with a different backend is activated after startup, Serena will return an error.
If you need to work with projects that use different backends, you can either:
1. Use the `--project` flag to activate the project at startup, which will use its configured backend.
2. Configure separate MCP server instances (one per backend) in your client.
:::
**Verifying the Setup**.
You can verify that Serena is using the JetBrains plugin by either checking the dashboard, where
you will see `Languages:
Using JetBrains backend` in the configuration overview.
You will also notice that your client will use the JetBrains-specific tools like `jet_brains_find_symbol` and others like it.
(jetbrains-workflow)=
## Workflow
Having installed the plugin in your IDE and having configured Serena to use the JetBrains backend,
the general workflow is simple:
1. Open the project you want to work on in your JetBrains IDE.
Note that the project must be appropriately set up in your IDE, i.e. symbol lookups for all relevant programming languages and frameworks should work in the IDE.
2. Activate the project's root folder as a project in Serena (see [Project Creation](project-creation-indexing) and [Project Activation](project-activation)).
3. Start using Serena's tools as usual.
Note that the project folder that is open in your IDE and the Serena project root folder must match.
:::{tip}
If you need to work on multiple projects in the same agent session, create a monorepo folder
containing all the projects and open that folder in both Serena and your IDE.
:::
## Advanced Usage and Configuration
### Using Serena with Multi-Module Projects
JetBrains IDEs support *multi-module projects*, where a project can reference other projects as modules.
Serena, however, requires that a project is self-contained within a single root folder.
There has to be a one-to-one relationship between the project root folder and the folder that is open in the IDE.
Therefore, to get a multi-module setup working with Serena, the recommended approach is to create a **monorepo folder**,
i.e. a folder that contains all the projects as sub-folders, and open that monorepo folder in both Serena and your IDE.
You do not necessarily need to physically move your projects into a common parent folder;
you can also use symbolic links to achieve the same effect
(i.e. use `mklink` on Windows or `ln` on Linux/macOS to link the project folders into a common parent folder).
### Using Serena with Windows Subsystem for Linux (WSL)
JetBrains IDEs have built-in support for WSL, allowing you to run the IDE on Windows while working with code in the WSL environment.
The Serena JetBrains plugin works seamlessly in this setup as well.
#### Using JetBrains Remote Development
Recommended constellation:
* Your project is in the WSL file system
* Serena is run in WSL (not Windows)
* The IDE has a host component (in WSL) and a client component (on Windows).
The Serena JetBrains plugin should normally be **installed in the host** (not the client) for code intelligence to be accessible.
:::{admonition} Plugin Installation Location
:class: note
If the plugin is already installed, check the options on the button for disabling the plugin.
Choose the respective options to ensure the correct installation location (i.e. host, removing it from the client if necessary).
:::
:::{admonition} Using mapped Windows paths in WSL is not recommended!
:class: warning
Keeping your project in the Windows file system and accessing it via `/mnt/` in WSL is extremely slow and not recommended.
:::
**Special Network Setup**.
If you are using a special setup where Serena and the IDE are running on different machines,
make sure Serena can communicate with the JetBrains plugin.
You can configure `jetbrains_plugin_server_address` in your [serena_config.yml](050_configuration) and
configure the listen address of the JetBrains plugin in the IDE via Settings / Tools / Serena
(e.g. set it to 0.0.0.0 to listen on all interfaces, but be aware of the security implications of doing so).
#### Other WSL Integrations (e.g. WSL interpreter)
* Your project is in the Windows file system
* WSL is used only for running tools (e.g. using a WSL Python interpreter in the IDE)
* Serena, the IDE and the plugin are all running on Windows
In this constellation, no special setup is required.
## Serena Plugin Configuration Options
You can configure plugin options in the IDE under Settings / Tools / Serena.
* **Listen address** (default: `127.0.0.1`)
the address the plugin's server listens on.
The default will work as long as Serena is running on the same machine (or on a virtual machine using mirrored networking).
But if the Serena MCP server is running on a different machine, configure the listen address to ensure that connections are possible.
You can use `0.0.0.0` to listen on all interfaces (but be aware of the security implications of doing so).
* **Sync file system before every operation** (default: enabled)
whether to synchronise the file system state before processing requests from Serena.
This is important to ensure that the plugin does not read stale data, but it can have a performance impact,
especially when using slow file systems (e.g. WSL file system while the IDE is running on Windows).
Note, however, that without synchronisation being forced by the Serena plugin, you will have to ensure synchronisation yourself.
Operations that apply changes to files in your project that are *not* made either in the IDE itself or by Serena may not be seen by the IDE.
Normally, the IDE synchronises automatically when it has the focus, using file watchers to achieve this (though this may or may not work reliably for the WSL file system).
Also, if you are working primarily in another application (e.g. AI chat), the IDE may not have the focus frequently.
So when external changes are made to your project, you will have to either give the IDE the focus (if that works) or trigger a sync manually (right-click root folder / Reload from Disk).
Further, note that even an edit made using, for example, Claude Code's internal editing tools would count as an external modification.
Only Serena's editing tools are "JetBrains-aware" and will tell the IDE to update the state of the edited file.
So if you are making AI-based edits using tools other than Serena's tools, do make sure that the lack of synchronisation is not a problem if you decide to disable this option.
## Usage with Other Editors
We realize that not everyone uses a JetBrains IDE as their main code editor.
You can still take advantage of the JetBrains plugin by running a JetBrains IDE instance alongside your
preferred editor. Most JetBrains IDEs have a free community edition that you can use for this purpose.
You just need to make sure that the project you are working on is open and indexed in the JetBrains IDE,
so that Serena can connect to it.
## /docs/02-usage/030_clients.md
# Connecting Your MCP Client
In the following, we provide general instructions on how to connect Serena to your MCP-enabled client,
as well as specific instructions for popular clients.
(clients-general-instructions)=
## General Instructions
In general, Serena can be used with any MCP-enabled client.
To connect Serena to your favourite client, simply
1. determine how to add a custom MCP server to your client (refer to the client's documentation).
2. add a new MCP server entry by specifying either
* a [run command](start-mcp-server) that allows the client to start the MCP server in stdio mode as a subprocess, or
* the URL of the HTTP/SSE endpoint, having started the [Serena MCP server in HTTP/SSE mode](streamable-http) beforehand.
Find concrete examples for popular clients below.
Depending on your needs, you might want to further customize Serena's behaviour by
* [adding command-line arguments](mcp-args)
* [adjusting configuration](050_configuration).
**Mode of Operation**.
Note that some clients have a per-workspace MCP configuration (e.g, VSCode and Claude Code),
while others have a global MCP configuration (e.g. Codex and Claude Desktop).
- In the per-workspace case, you typically want to start Serena with your workspace directory as the project directory
and never switch to a different project. This is achieved by specifying the
`--project <path>` argument with a single-project [context](#contexts) (e.g. `ide` or `claude-code`).
- In the global configuration case, you must first activate the project you want to work on, which you can do by asking
the LLM to do so (e.g., "Activate the current dir as project using serena"). In such settings, the `activate_project`
tool is required.
**Tool Selection**.
While you may be able to turn off tools through your client's interface (e.g., in VSCode or Claude Desktop),
we recommend selecting your base tool set through Serena's configuration, as Serena's prompts automatically
adjust based on which tools are enabled/disabled.
A key mechanism for this is to use the appropriate [context](#contexts) when starting Serena.
(clients-common-pitfalls)=
### Common Pitfalls
**Discoverability of the `serena` command**.
Your client may not find the `serena` CLI command, even if it is on your system PATH.
In this case, a workaround is to provide the full path to the `serena` executable.
**Serena's tools not being used**.
With some clients, you may experience that Serena's tools are not being used.
This is mainly due to problems in the client itself (like a poorly implemented tool discovery). To counteract this,
Serena comes with a set of commands that can be used in _hooks_. See the sections on hooks for Claude Code and VSCode below.
**Environment Variables**.
Some language servers may require additional environment variables to be set (e.g. F# on macOS with Homebrew),
which you may need to explicitly add to the MCP server configuration.
Note that for some clients (e.g. Claude Desktop), the spawned MCP server process may not inherit environment variables that
are only configured in your shell profile (e.g. `.bashrc`, `.zshrc`, etc.); they would need to be set system-wide instead.
An easy fix is to add them explicitly to the MCP server entry.
For example, in Claude Desktop and other clients, you can simply add an `env` key to the `serena`
object, e.g.
```
"env": {
"DOTNET_ROOT": "/opt/homebrew/Cellar/dotnet/9.0.8/libexec"
}
```
## Copilot in JetBrains
Open the settings of your JetBrains IDE and go to Tools / GitHub Copilot / Model Context Protocol (MCP). Then click
on the Configure button. This will open your global `mcp.json` file, where you can add the following entry for Serena:
```json
{
"servers": {
"serena": {
"type": "stdio",
"command": "serena",
"args": [
"start-mcp-server",
"--context=jb-copilot-plugin"
]
}
}
}
```
**Verification.**
Open Copilot, switch to Agent mode, and click on the configure tools button. You should see Serena's tools in the list and be able to start
the Serena server there (you do not generally have to start Serena in the future, Copilot will start the server by itself). If the server is shown as running, Copilot is successfully connected to Serena. Most models will understand how to use Serena's tools out of the box, but for some models you may have to prompt "Activate the current project with Serena and read initial instructions" in the beginning of the chat.
**Recommended Configuration**.
The `jb-copilot-plugin` context (see above) comes with our recommended subset of Serena's tools for Copilot in JetBrains IDEs. We also
recommend *disabling* the following built-in tools for optimal performance:
replace_string_in_file, apply_patch, list_dir, file_search, grep_search. Note that running subagents may not use MCP servers, consider deactivating the run_subagent tool as well.
Serena offers better alternatives to these basic tools. If you do prefer to use the built-in tools instead,
you should disable corresponding Serena tools instead to prevent context bloat.
We also recommend marking Serena's tools as approved so you don't have to manually approve them in agent sessions.
You can do this in Tools / GitHub Copilot / Chat, where at the bottom you can click on the Configure button for MCP tool auto-approval.
## Claude Code
Serena is a great way to make Claude Code both more efficient and more powerful!
To set up the Serena MCP server for Claude Code, you can simply run this command:
serena setup claude-code
Find manual setup instructions as well as workarounds for Claude Code's recent regressions pertaining to (external) tool use below.
:::{attention}
Recent updates to Claude Code (CC) and to the Opus line of models resulted in drastically reduced
adherence to instructions pertaining to Serena's tools.
After extensive analysis, we identified part of the reason to be very long and detailed
tool descriptions for built-in tools and parts of the default system prompt.
The descriptions of CC's system tools take almost 16k tokens, cannot be adjusted by the user,
and introduce a very strong bias towards internal tools, making it almost impossible to convince Opus 4.7 to use Serena.
As a workaround, we crafted a system prompt that counteracts this bias.
When using Serena, we highly recommend that you start CC as
```shell
claude --system-prompt="$(serena prompts print-cc-system-prompt-override)"
```
You can also consider adding the content of `serena cc-system-prompt-override` to your `CLAUDE.md` files,
but the effect be insufficient for counteracting Claude Code's bias towards internal tools.
:::
**Global Configuration**. To add the Serena MCP server for all your projects, use the user-level configuration of claude code and the `--project-from-cwd` flag:
```shell
claude mcp add --scope user serena -- serena start-mcp-server --context claude-code --project-from-cwd
```
**Per-Project Configuration.** Alternatively, to add Serena only for the current project in the current directory,
use the command:
```shell
claude mcp add serena -- serena start-mcp-server --context claude-code --project "$(pwd)"
```
**Verification.**
Confirm that Claude Code is connected to Serena by running the `/mcp` command and by reconnecting, if necessary.
If Serena fails to start fast enough, you should set `MCP_TIMEOUT` to a sufficiently high value
(e.g. by adding `export MCP_TIMEOUT=60000` to your shell profile)
**Hooks.**
Due to recent changes (especially dynamic tool loading) in Claude Code, the agent will often fail to make proper use
of Serena's tools, either by failing to load them in the beginning or by forgetting the instructions in a long session
(a behavior known as agent drift). To counteract this, we provide reminder hooks. We **strongly recommend** setting
up the hooks as below (or a variation thereof) for optimal performance of Serena in Claude Code.
:::{note}
While recommended, hooks are an **alpha feature**. Provide feedback via the [GitHub issue tracker](https://github.com/oraios/serena/issues) if you encounter any issues.
:::
To set up hooks, add the following to your Claude Code settings file
(`.claude/settings.json` in your project directory, or `~/.claude/settings.json` globally):
All hooks below are opt-in — include only the ones you want. Add the following to your
Claude Code settings file (`.claude/settings.json` in your project directory, or
`~/.claude/settings.json` globally):
```json
{
"hooks": {
"PreToolUse": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "serena-hooks remind --client=claude-code"
}
]
},
{
"matcher": "mcp__serena__*",
"hooks": [
{
"type": "command",
"command": "serena-hooks auto-approve --client=claude-code"
}
]
}
],
"SessionStart": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "serena-hooks activate --client=claude-code"
}
]
}
],
"SessionEnd": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "serena-hooks cleanup --client=claude-code"
}
]
}
]
}
}
```
The hooks will:
- **`remind`**: Nudge the agent to use Serena's symbolic tools when it makes too many consecutive
`grep` or `read_file` calls without using any Serena tools in between.
- **`activate`**: Prompt the agent to activate the project and read Serena's instructions at session start.
- **`cleanup`**: Clean up hook session data when the session ends.
- **`auto-approve`**: Auto-approve Serena tool calls whenever Claude Code is in a permissive
permission mode (`acceptEdits` or `auto`), so blanket approvals cover Serena's destructive
tools (e.g. `replace_symbol_body`, `rename_symbol`) instead of prompting on every call.
For more details on Claude Code's hook system, see the
[Claude Code hooks documentation](https://code.claude.com/docs/en/hooks).
## VSCode
You can add Serena to VSCode by running the MCP: Add Server command.
In that dialogue, select the Command (stdio) option. You can decide between installing it globally
or in the workspace (only for the currently open project), and the command you should enter depends on that choice.
(You will be asked to choose after entering the mcp run command.)
**Global.** (Recommended)
Enter `serena start-mcp-server --context=vscode`. Unfortunately, due to a [bug in VSCode](https://github.com/microsoft/vscode/issues/245905),
in this setting Serena won't be able to activate the project automatically. You will have to remember to prompt
"Activate the current dir as project using serena" at the start of each session.
**Workspace.**
Enter `serena start-mcp-server --context=vscode --project ${workspaceFolder}`. This will allow Serena to automatically activate the project,
with the downside that you will have to add Serena to each project you want to use it in.
In both cases, proceed to enter Serena as the name, then select either global or workspace.
**Verification.**
You should be able to see Serena in the tools overview in the AI Chat window.
**Hooks.**
Due to recent changes (especially dynamic tool loading) in VSCode, the agent will often fail to make proper use
of Serena's tools, either by failing to load them in the beginning or by forgetting the instructions in a long session
(a behaviour known as agent drift). To counteract this, we provide reminder hooks. We **strongly recommend** setting
up the hooks as below (or a variation thereof) for optimal performance of Serena in VSCode.
The hooks will:
- **`remind`**: Nudge the agent to use Serena's symbolic tools when it makes too many consecutive
`grep` or `read_file` calls without using any Serena tools in between.
- **`activate`**: Prompt the agent to activate the project and read Serena's instructions at session start.
- **`cleanup`**: Clean up hook session data when the session ends.
To set this up, create the file `~/.copilot/hooks/serena-hooks.json` with the following content:
```json
{
"hooks": {
"PreToolUse": [
{
"type": "command",
"command": "serena-hooks remind --client=vscode"
}
],
"SessionStart": [
{
"type": "command",
"command": "serena-hooks activate --client=vscode"
}
],
"Stop": [
{
"type": "command",
"command": "serena-hooks cleanup --client=vscode"
}
]
}
}
```
The `SessionStart` hook also addresses the global configuration limitation mentioned above — it will
automatically prompt the agent to activate the project directory, so you no longer need to do this manually.
## Copilot CLI
Use the interactive `/mcp add` slash command, choose Serena as the name, STDIO as the server type, and
`serena start-mcp-server --context=copilot-cli --project-from-cwd` as command. Copilot CLI will immediately notify you
that Serena is running if everything is set up correctly or display an error otherwise.
You should add the same **hooks** as in VSCode (see above) if Copilot CLI didn't pick them up automatically.
## Codex (CLI and App)
You can simply run `serena setup codex`.
Alternatively, you can manually add the following to `~/.codex/config.toml` (create the file if it does not exist):
```toml
[mcp_servers.serena]
startup_timeout_sec = 15
command = "serena"
args = ["start-mcp-server", "--project-from-cwd", "--context=codex"]
```
**Verification.**
Run the `/mcp` command and verify that Serena is connected.
The Codex app does not start a session in the project's directory, so when using the app, we recommend
asking Codex to "Activate the current dir as project using serena" at the start of each session (though Codex might
do this automatically).
**Hooks.**
Codex supports lifecycle hooks; see the
[Codex hooks documentation](https://developers.openai.com/codex/hooks) for details. To enable
Serena's hooks for Codex, add this feature flag to `~/.codex/config.toml`:
```toml
[features]
codex_hooks = true
```
Then create `~/.codex/hooks.json` with the following content:
```json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "serena-hooks remind --client=codex"
}
]
}
],
"SessionStart": [
{
"matcher": "startup|resume",
"hooks": [
{
"type": "command",
"command": "serena-hooks activate --client=codex"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "serena-hooks cleanup --client=codex"
}
]
}
]
}
}
```
The hooks will:
- **`activate`**: Prompt the agent to activate the current project and read Serena's instructions
when a Codex session starts or resumes.
- **`remind`**: Nudge the agent to use Serena's symbolic tools when it makes too many consecutive
code-search or code-file-read calls without using Serena tools in between.
- **`cleanup`**: Clean up hook session data when the session ends.
The `PreToolUse` matcher is intentionally restricted to `Bash`. The Serena reminder hook for Codex
tracks shell-based grep and code-file reads, so running it for every tool call is unnecessary.
## Claude Desktop
On Windows and macOS, there are official [Claude Desktop applications by Anthropic](https://claude.ai/download); for Linux, there is an [open-source
community version](https://github.com/aaddrick/claude-desktop-debian).
To configure MCP server settings, go to File / Settings / Developer / MCP Servers / Edit Config,
which will let you open the JSON file `claude_desktop_config.json`.
Add the `serena` MCP server configuration
```json
{
"mcpServers": {
"serena": {
"command": "serena",
"args": [
"start-mcp-server",
"--context=claude-desktop"
]
}
}
}
```
If your language server requires specific environment variables to be set (e.g. F# on macOS with Homebrew),
you can add them via an `env` key (see [above](#clients-common-pitfalls)).
**Verification.**
Once you have created the new MCP server entry, save the config and then restart Claude Desktop.
:::{attention}
Be sure to fully quit the Claude Desktop application via File / Exit, as regularly closing the application will just
minimize it.
:::
After restarting, you should see Serena's tools in your chat interface (notice the small hammer icon).
## Copilot CLI
In the interactive mode, you can call `/mcp add` from within the copilot CLI. There, use serena as name,
STDIO as the server type, and `serena start-mcp-server --context=copilot-cli --project-from-cwd` as command.
Alternatively, add the following to `~/.copilot/mcp-config.json` (create the file if it does not exist):
```json
{
"mcpServers": {
"serena": {
"type": "stdio",
"command": "serena",
"tools": [
"*"
],
"args": [
"start-mcp-server",
"--context=copilot-cli",
"--project-from-cwd"
]
}
}
}
```
**Verification.**
Copilot should now show that Serena is running, though you may have to restart it.
## JetBrains Junie
For the Junie plugin in JetBrains IDEs you can add Serena either to the global configuration in `~/.junie/mcp/mcp.json`
or to the project configuration in `<project>/.junie/mcp/mcp.json`. Important, don't add both!
In both cases the entry should be:
```json
{
"mcpServers": {
"serena": {
"command": "serena",
"args": [
"start-mcp-server",
"--context=junie",
"--project-from-cwd"
]
}
}
}
```
With the global configuration, Serena will be available in all projects. However,
within the Junie plugin, projects will not be automatically activated in Serena.
You may thus have to prompt
Junie to "Activate the current project using serena's activation tool" at the start of each session (though some models are
smart enough to activate the project automatically).
With the project-scoped configuration, Serena will be available only in that project, and the project will automatically
be recognized as active by Serena.
## JetBrains AI Assistant
Go to Settings / Tools / AI Assistant / MCP and enter the following configuration:
```json
{
"mcpServers": {
"serena": {
"command": "serena",
"args": [
"start-mcp-server",
"--context=jb-ai-assistant",
"--project-from-cwd"
]
}
}
}
```
Like for Junie, you have the choice between the global and the project-scoped configuration,
with the same trade-off.
## Antigravity
Add this configuration:
```json
{
"mcpServers": {
"serena": {
"command": "serena",
"args": [
"start-mcp-server",
"--context=antigravity"
]
}
}
}
```
You will have to prompt Antigravity's agent to "Activate the current project using serena's activation tool" after starting Antigravity in the project directory (once in the first chat enough, all other chat sessions will continue using the same Serena session).
Unlike VSCode, Antigravity does not currently support including the working directory in the MCP configuration.
Also, the current client will be shown as `none` in Serena's dashboard (Antigravity currently does not fully support the MCP specifications). This is not a problem, all tools will work as expected.
## Other Clients
For other clients, follow the [general instructions](#clients-general-instructions) above to set up Serena as an MCP server.
### Terminal-Based Clients
There are many terminal-based coding assistants that support MCP servers, such as
* [Gemini-CLI](https://github.com/google-gemini/gemini-cli),
* [Qwen3-Coder](https://github.com/QwenLM/Qwen3-Coder),
* [rovodev](https://community.atlassian.com/forums/Rovo-for-Software-Teams-Beta/Introducing-Rovo-Dev-CLI-AI-Powered-Development-in-your-terminal/ba-p/3043623),
* [OpenHands CLI](https://docs.all-hands.dev/usage/how-to/cli-mode) and
* [opencode](https://github.com/sst/opencode).
They generally benefit from the symbolic tools provided by Serena. You might want to customize some aspects of Serena
by writing your own context, modes or prompts to adjust it to the client's respective internal capabilities (and your general workflow).
In most cases, the `ide` context is likely to be appropriate for such clients, i.e. add the arguments `--context ide`
in order to reduce tool duplication.
### MCP-Enabled IDEs and Coding Clients (Cline, Roo-Code, Cursor, Windsurf, etc.)
Most of the popular existing coding assistants (e.g. IDE extensions) and AI-enabled IDEs themselves support connections
to MCP Servers. Serena generally boosts performance by providing efficient tools for symbolic operations.
We generally recommend using the `ide` context for these integrations by adding the arguments `--context ide`
in order to reduce tool duplication.
### Local GUIs and Agent Frameworks
Over the last months, several technologies have emerged that allow you to run a local GUI client
and connect it to an MCP server. The respective applications will typically work with Serena out of the box.
Some of the leading open source GUI applications are
* [Jan](https://jan.ai/docs/mcp),
* [OpenHands](https://github.com/All-Hands-AI/OpenHands/),
* [OpenWebUI](https://docs.openwebui.com/openapi-servers/mcp) and
* [Agno](https://docs.agno.com/introduction/playground).
These applications allow combining Serena with almost any LLM (including locally running ones)
and offer various other integrations.
## /docs/02-usage/040_workflow.md
# The Project Workflow
Serena uses a project-based workflow.
A **project** is simply a directory on your filesystem that contains code and other files
that you want Serena to work with.
Assuming that you have project you want to work with (which may initially be empty),
setting up a project with Serena typically involves the following steps:
1. **Project creation**: Configuring project settings for Serena (and indexing the project, if desired)
2. **Project activation**: Making Serena aware of the project you want to work with
3. **Onboarding**: Getting Serena familiar with the project (creating memories)
4. **Working on coding tasks**: Using Serena to help you with actual coding tasks in the project
(project-creation-indexing)=
## Project Creation & Indexing
Project creation is the process of defining fundamental project settings that are relevant to Serena's operation.
You can create a project either
* explicitly, using the project creation command (see below), or
* implicitly, by just activating a directory as a project while already in a conversation; this will use default settings for your project (skip to the next section).
### Explicit Project Creation
To explicitly create a project, use the following command while in the project directory:
serena project create [options] [project directory]
* The project directory defaults to the current directory if not specified.
* For an existing project, the programming languages will be detected based on
the source files present, and the main language will be activated automatically.
If multiple languages are detected, you will be prompted whether you want to enable them.
* For an empty project, you can optionally specify one or more languages
to be activated explicitly via the `--language` parameter
(e.g. `--language python --language typescript`).
* You can optionally specify a custom project name with `--name my-name`.
* You can immediately index the project after creation with `--index`.
(project-config)=
#### Project Configuration
After creation, you can adjust the project settings in the generated `.serena/project.yml` file
within the project directory.
The file allows you to configure ...
* the name by which you want to refer to the project (relevant when telling the LLM to dynamically activate the project)
* the set of programming languages for which language servers are spawned (not relevant when using the JetBrains plugin)
Note that you can dynamically add/remove language servers while Serena is running via the [Dashboard](060_dashboard).
* the [language backend](per-project-language-backend) to use for this project (overriding the global setting)
* the encoding used in source files
* ignore rules
* write access
* [additional workspace folders](additional-workspace-folders) for cross-package reference support in monorepos
* an initial prompt that shall be passed to the LLM whenever the project is activated
* the set of tools and modes to use for the project
* and some other settings.
For detailed information on the parameters and possible settings, see the
[template file](https://github.com/oraios/serena/blob/main/src/serena/resources/project.template.yml).
:::{note}
Many settings in project.yml *extend* or *override* settings in the global configuration file `serena_config.yml`.
So use the project configuration specifically for aspects that apply only to the particular project.
:::
**Local Overrides**. The project.yml file is intended to be versioned together with the project.
You can specify local overrides for the settings in a `project.local.yml` file in the same directory
(which, by default, is ignored by git).
Any keys defined therein will override the respective key in `project.yml`.
(additional-workspace-folders)=
#### Additional Workspace Folders (Cross-Package References)
In monorepos or multi-package setups, Serena's language server normally only sees symbols within the
project root. To enable cross-package references (e.g. `find_referencing_symbols` discovering usages
in sibling packages), configure `additional_workspace_folders` in your `project.yml`:
```yaml
additional_workspace_folders:
- ../shared-lib
- ../api-client
- /absolute/path/to/another-package
```
Paths can be absolute or relative to the project root. Each folder is registered as an LSP workspace
folder, and the language server will discover symbols and references across all listed packages.
**Currently supported for:** TypeScript. Other language servers will raise an error if this setting
is used with them. Support for additional languages can be added by implementing the
`_find_representative_source_file()` method in the respective language server class.
:::{note}
Each additional workspace folder adds startup time, as the language server needs to index the
additional projects. For large monorepos, consider listing only the packages you actively need
cross-references for.
:::
(indexing)=
### Indexing
:::{note}
Indexing is not a relevant operation when using the JetBrains plugin, as indexing is handled by the IDE.
:::
Especially for larger project, it can be advisable to index the project after creation, pre-caching
symbol information provided by the language server(s). This will avoid delays during the first tool invocation
that requires symbol information.
While in the project directory, run this command:
<serena> project index
Indexing has to be called only once. During regular usage, Serena will automatically update the index whenever files change.
(project-activation)=
## Project Activation
Project activation makes Serena aware of the project you want to work with.
You can either choose to do this
* while in a conversation, by telling the LLM to activate a project, e.g.,
* "Activate the project /path/to/my_project" (for first-time activation with auto-creation)
* "Activate the project my_project"
Note that this option requires the `activate_project` tool to be active,
which it isn't in single-project [contexts](contexts) like `ide` or `claude-code` *if* a project is provided at startup.
(The tool is deactivated, because we assume that in these contexts, user will only work on the single, open project and have
no need to switch it.)
* when the MCP server starts, by passing the project path or name as a command-line argument
(e.g. when using a single-project mode like `ide` or `claude-code`): `--project <path|name>`
When working with the JetBrains plugin, be sure to have the same project folder open as a project in your IDE,
i.e. the folder that is activated in Serena should correspond to the root folder of the project in your IDE.
## Onboarding & Memories
By default, Serena will perform an **onboarding process** when
it is started for the first time for a project.
The goal of the onboarding is for Serena to get familiar with the project
and to store memories, which it can then draw upon in future interactions.
In general, **memories** provide a way for Serena to store and retrieve
information about the project, relevant conventions, and other relevant aspects.
For more information on this, including how to manage
or disable these features, see [Memories & Onboarding](045_memories).
## Preparing Your Project
When using Serena to work on your project, it can be helpful to follow a few best practices.
### Structure Your Codebase
Serena uses the code structure for finding, reading and editing code. This means that it will
work well with well-structured code but may perform poorly on fully unstructured one (like a "God class"
with enormous, non-modular functions).
Furthermore, for languages that are not statically typed, the use of type annotations (if supported)
are highly beneficial.
### Start from a Clean State
It is best to start a code generation task from a clean git state. Not only will
this make it easier for you to inspect the changes, but also the model itself will
have a chance of seeing what it has changed by calling `git diff` and thereby
correct itself or continue working in a followup conversation if needed.
### Use Platform-Native Line Endings
**Important**: since Serena will write to files using the system-native line endings
and it might want to look at the git diff, it is important to
set `git config core.autocrlf` to `true` on Windows.
With `git config core.autocrlf` set to `false` on Windows, you may end up with huge diffs
due to line endings only.
It is generally a good idea to globally enable this git setting on Windows:
```shell
git config --global core.autocrlf true
```
### Logging, Linting, and Automated Tests
Serena can successfully complete tasks in an _agent loop_, where it iteratively
acquires information, performs actions, and reflects on the results.
However, Serena cannot use a debugger; it must rely on the results of program executions,
linting results, and test results to assess the correctness of its actions.
Therefore, software that is designed to meaningful interpretable outputs (e.g. log messages)
and that has a good test coverage is much easier to work with for Serena.
We generally recommend to start an editing task from a state where all linting checks and tests pass.
## Multiple Projects, Multiple Agents
There are several ways in which you might want to work with multiple projects simultaneously.
### A Single Agent Editing Multiple Projects Simultaneously
If fulfilling a task requires a single agent to edit code in multiple projects, the recommended approach is to create a **monorepo folder**,
i.e. a folder that contains all the projects as sub-folders, and open that monorepo folder as a project in Serena.
You may also use symbolic links to create a monorepo folder if the projects are located in different places on your filesystem.
If several languages are used across the projects, specify all of them as needed when using the LSP backend;
For JetBrains mode, make sure that your IDE is configured to work with all the languages used across the projects (e.g. by installing the respective language plugins).
(query-projects)=
### Reading from External Projects
If, while working on a project, you want Serena to be able to read code or other information from another project (e.g. a library or otherwise related project),
this can be enabled via the `query_project` tool.
Provided that the project you want to query is known to Serena (i.e. you have created it as described above),
the `query_project` tool allows the agent to query files and symbolic information from that project.
To enable this tool, [activate the mode](modes) `query-projects`.
This also enables a second tool for listing projects that can be queried.
Depending on the language backend being used, the management of resources for the external projects varies:
* When using the JetBrains backend, make sure that every project for which you want symbolic queries to work is open in an IDE instance.
* When using the LSP backend, executing symbolic tools via the query tool requires that Serena's **Project Server** be started,
which will automatically spawn the necessary language servers for the projects that are queried.
To start the server, run
serena start-project-server
### Multiple Agents Accessing a Single Serena Instance
If you want multiple agents to access the same project via a single Serena instance,
i.e. you do not want several instances of Serena (including its language servers) to be running,
you can achieve this by [starting the Serena MCP server in HTTP mode](streamable-http)
and connecting all client agents to the same HTTP endpoint.
The agents will then share the resources of the single Serena instance.
### Multiple Agents Working on Different Projects
For this use case, simply run a separate instance of Serena for each project, which naturally
occurs when Serena is started by the MCP client in stdio mode.
## /docs/02-usage/045_memories.md
# Memories & Onboarding
Serena provides the functionality of a fully featured agent, and a useful aspect of this is Serena's memory system.
Despite its simplicity, we received positive feedback from many users who tend to combine it with their
agent's internal memory management (e.g., `AGENTS.md` files).
## Memories
Memories are simple, human-readable Markdown files that both you and
your agent can create, read, and edit.
Serena differentiates between
* **project-specific memories**, which are stored in the `.serena/memories/` directory within your project folder, and
* **global memories**, which are shared across all projects and, by default, are stored in `~/.serena/memories/global/`
The LLM is informed about the existence of memories and instructed to read them when appropriate,
inferring appropriateness from the file name.
When the agent starts working on a project, it receives the list of available memories.
The agent should be instructed to update memories by the user when appropriate.
### Organizing Memories
Memories can be organized into **topics** by using `/` in the memory name (e.g. `modules/frontend`).
The structure is mapped to the file system, where topics correspond to subdirectories.
The `list_memories` tool can filter by topic, allowing the agent to explore even large numbers of memories in a structured way.
(global-memories)=
### Global Memories
Global memories use the top-level topic `global`, i.e. whenever a memory name starts with `global/`,
it is stored in the global memories directory and is shared across all projects.
By default, deletion and editing of global memories is allowed.
If you want to protect them from accidental modification by the agent,
you can add regex patterns to `read_only_memory_patterns` in your global or
project-level [configuration](050_configuration). For example, setting "global/.*" will mark all global memories as read-only. The agent will be informed which memories are read-only.
Since global memories are not versioned alongside your project files,
it can be helpful to track global memories with git (i.e. to make `~/.serena/memories/` a git repository)
in order to have a history of changes and the possibility to revert them if needed.
### Ignoring Memories
Projects that accumulate large numbers of archived memory files can use `ignored_memory_patterns`
to exclude them from `list_memories` and `activate_project` output. Add regex patterns to the
global or project-level [configuration](050_configuration):
```yaml
ignored_memory_patterns: ["_archive/.*", "_episodes/.*"]
```
Ignored memories are completely excluded — they cannot be accessed via `read_memory`, `write_memory`,
or any other memory tool. To read an ignored memory file, use the `read_file` tool on the raw file path
(e.g., `.serena/memories/_archive/2026-03/some-topic.md`).
Like `read_only_memory_patterns`, patterns from the global and project-level configurations are merged additively.
### Manually Editing Memories
You may edit memories directly in the file system, using your preferred text editor or IDE.
Alternatively, access them via the [Serena Dashboard](060_dashboard), which provides a graphical interface for
viewing, creating, editing, and deleting memories while Serena is running.
(onboarding)=
## Onboarding
By default, Serena performs an **onboarding process** when it encounters a project
for the first time (i.e., when no project memories exist yet).
The goal of the onboarding is for Serena to get familiar with the project —
its structure, build system, testing setup, and other essential aspects —
and to store this knowledge as memories for future interactions.
In further project activations, Serena will check whether onboarding was already
performed by looking for existing project memories and will skip the onboarding
process if memories are found.
### How Onboarding Works
1. When a project is activated, Serena checks whether onboarding was already
performed (by checking if any memories exist).
2. If no memories are found, Serena triggers the onboarding process, which
reads key files and directories to understand the project.
3. The gathered information is written into project-specific memory files (see above).
### Tips for Onboarding
- **Context usage**: The onboarding process will read a lot of content from the project,
filling up the context window. It is therefore advisable to **switch to a new conversation**
once the onboarding is complete.
- **LLM failures**: If an LLM fails to complete the onboarding and does not actually
write the respective memories to disk, you may need to ask it to do so explicitly.
- **Review the results**: After onboarding, we recommend having a quick look at the
generated memories and editing them or adding new ones as needed.
## Disabling Memories and Onboarding
If you do not require the functionality described in this section, you can selectively disable it.
* To disable all memory related tools (including onboarding), adding `no-memories` to the `base_modes`
in Serena's [global configuration](050_configuration).
* Similarly, to disable only onboarding, add `no-onboarding` to the `base_modes`.
## /docs/02-usage/060_dashboard.md
# The Dashboard and GUI Tool
Serena comes with built-in tools for monitoring and managing the current session:
* the **Serena Dashboard** (enabled by default)
The dashboard provides detailed information on your Serena session, the current configuration and provides access to logs.
Some settings (e.g. the current set of active programming languages) can also be directly modified through the dashboard.
The dashboard is supported on all platforms.
* the **GUI Log Viewer** (disabled by default)
The GUI tool is a legacy native application which displays Serena's live logs.
This is mainly supported on Windows, but it may also work on Linux; macOS is unsupported.
Both can be configured in Serena's [configuration](050_configuration) file (`serena_config.yml`).
## The Serena Dashboard
The dashboard is a web application, which is opened in one of three ways:
* via a native application wrapper with accompanying tray icon (on supported platforms)
* via a tray manager that aggregates multiple instances (on supported platforms)
* via your default web browser (supported on all platforms)
Configure your preferred interface via the setting `web_dashoard_interface` in [Serena's global configuration file](global-config) (see below).
By default, the dashboard can be accessed at `http://localhost:24282/dashboard/index.html`,
but a higher port may be used if the default port is unavailable/multiple instances are running.
### Features
The dashboard provides ...
* a detailed overview of
* the current Serena status and configuration (e.g. active tools, active programming languages, enabled modes and contexts, etc.)
* ongoing and past tool calls (and statistics on tool usage)
* access to Serena's live logs
* the ability to modify settings (e.g. the set of active programming languages) on the fly
* the ability to edit
* configuration files (global `serena_config.yml` and project-specific `project.yml`)
* memories of the current project
* the ability to shut down the Serena MCP server.
### Configuring the Dashboard
You can configure settings for the dashboard in the [global configuration file](global-config).
In particular, you can configure
* the interface through which the dashboard is accessed (see above)
* whether the dashboard is enabled at all.
We highly recommend keeping it enabled, as it provides valuable insights into Serena's operation and allows you to adjust configuration conveniently.
* whether the dashboard window is opened automatically when Serena is started (see below).
* network settings (for cases where you might want to access the Dashboard non-locally).
#### Dashboard Opening Behaviour
When Serena is started, the Dashboard window is opened by default in order to make users aware of its existence.
If you prefer not to have this happen, you can prevent it from opening
by setting `web_dashboard_open_on_launch: False` in the [global configuration file](global-config) or by passing `--open-web-dashboard False`
to the `start-mcp-server` CLI command.
On platforms supporting the tray icon (see also configuration option `web_dashboard_interface`),
you can conveniently open the dashboard at any time by clicking on the tray icon, so automatic
opening is not a requirement to be able to access the dashboard on these platforms.
On other platforms, you may still access it by
* asking the LLM to "open the Serena dashboard", which will open the dashboard in your default browser
(the tool `open_dashboard` is enabled for this purpose, provided that the dashboard is active,
not opened by default and the GUI tool, which can provide the URL, is not enabled)
* navigating directly to the URL (see above).
## The GUI Log Viewer
The Serena GUI Log Viewer is a legacy application which provides access to Serena's live logs.
Via its menu, it furthermore allows you to
* shut down the agent
* access the dashboard's URL (if it is running).
The tool is mainly supported on Windows, but it may work on some Linux systems as well (depending on your desktop environment).
To enable the tool, set `gui_log_window` to `true` in Serena's [global configuration file](global-config).
## /docs/02-usage/065_logs.md
# Logs
It can be vital to understand what is happening in Serena, especially when something goes wrong.
You can access Serena's live logs via
* the [Serena dashboard](060_dashboard) (tab "Logs")
* the [GUI tool](060_dashboard).
Additionally, logs are persisted in the Serena home directory, which, by default, is located at
* `%USERPROFILE%\.serena\logs` on Windows
* `~/.serena/logs` on Linux and macOS.
You can adjust the log level via the [global configuration](global-config).
You additionally have the option of enabling full tracing of language server communication (mostly for development purposes).
## /docs/02-usage/070_security.md
# Security Considerations
Security is important to us, and we take this topic seriously.
## Serena's Assumptions
The current security model for Serena assumes:
- the local machine is trusted,
- the MCP client (i.e. the LLM) is trusted,
- the code repository being worked on is trusted,
- user configuration is trusted,
- package manager configuration (e.g. npm) for downloading additional dependencies (i.e. language servers when using Serena with the LSP backend) is trusted.
Serena contains tools for executing shell commands and modifying files.
As such tools are, however, an essential part of coding agent workflows, they typically need to be made available.
Therefore, the only way to *fully* protect against unintended consequences is to use a [sandboxed environment](sandboxing) for running Serena.
## General Recommendations for Risk Reduction
To reduce the risk of unintended consequences, we recommend that you:
- back up your work regularly (keep the project being worked on under version control),
- restrict the set of allowed tools via the [configuration](050_configuration),
- do not expose [Serena's network services](network-security) to untrusted networks.
If you do not fully the trust the client/the LLM, we additionally recommend to monitor tool executions carefully
(provided that your MCP client supports this).
(sandboxing)=
## Sandboxing
Sandboxing is the most effective way to mitigate risks when using coding agents.
[Running Serena inside a docker container](docker) which only exposes the necessary files and tools to the agent is a good way to achieve this.
While setting up a sandboxed environment may require some initial effort, we highly recommend it for all security-conscious users.
(network-security)=
## Network Security
Serena includes several network services:
- the Serena MCP server itself (when run in [HTTP or SSE mode](streamable-http) instead of stdio mode)
- the Serena Dashboard web server
- the Serena JetBrains Plugin server, which runs within the JetBrains IDE (when using the JetBrains language backend)
- the Serena Project Server (only started explicitly for [project querying](query-projects))
By default, these services accept connections from localhost only, which is a secure default for most users
(given our assumption that the local machine is trusted; see above).
These services can be reconfigured to listen on other addresses, but doing so may have security implications.
If you need to allow connections from other machines, we recommend that you set up a secure networking environment
(e.g. using a VPN or SSH tunnels) and ensure that only trusted machines can connect to these services.
## Supply Chain Security
Serena has two language backends with different security characteristics:
- the JetBrains-based variant, which integrates with a running JetBrains IDE, and
- the language-server-based variant (the free variant), which can automatically acquire language server dependencies on demand.
While we can assume that JetBrains IDEs installed by the user do not pose a security risk,
language server dependencies (if not handled with care) could.
For convenience, Serena downloads or installs certain language server dependencies on demand.
We treat this path as security-sensitive and have hardened it accordingly.
The most important supply chain protections are:
- exact version pinning,
- hash verification,
- host restriction,
- and isolated Serena-managed installation directories.
### Auto-Downloaded Language Server Dependencies
For language servers that are auto-installed by downloading archives, binaries, VSIX packages, NuGet packages, or other release artifacts, Serena uses a hardened shared download path with the following protections:
- **Pinned versions by default**: default downloads use exact versions instead of floating `latest` or nightly channels.
- **Integrity verification**: downloaded artifacts are checked against pinned SHA256 hashes stored in Serena's source code.
- **Host allowlists**: download URLs are restricted to the expected hosts for a given dependency.
- **Safe extraction**: archive extraction validates paths to prevent path traversal and zip-slip style attacks.
- **Managed install locations**: dependencies are installed into Serena-managed directories instead of into the project repository.
In practice, this means that a downloaded artifact must match all of the following:
- the expected version,
- the expected host,
- the expected SHA256 checksum,
- and the expected extraction layout.
If any of these checks fail, Serena aborts the installation instead of continuing.
### npm-Based Language Servers
Some language servers are distributed primarily through npm. For those, Serena currently uses pinned package versions and installs them into Serena-managed directories.
By default, Serena uses the **user's normal npm configuration**. We do **not** force a registry override unless one is explicitly configured. If needed, both the package version and the registry can be overridden through `ls_specific_settings`.
For npm-based installs, Serena's current security posture is based on these rules:
- **Exact package versions are pinned by default**.
- **The install location is isolated from the project** and lives in Serena-managed language-server directories.
- **The user's npm configuration is trusted by default**.
- **Repository and user configuration are assumed to be trusted**.
This means Serena protects well against accidental version drift, but npm installs still rely on the npm ecosystem and package-manager execution model. In particular, Serena does **not** currently use lockfile-based `npm ci` installs for bundled language-server dependencies.
### `uvx` and Python Dependency Pinning
Some parts of Serena rely on `uv` / `uvx`.
One important detail is that `uvx` ignores the lockfile when installing directly from a Git repository. Because of that, we pin Serena's Python dependencies exactly in `pyproject.toml` so that installations from Git still resolve to exact dependency versions rather than floating ranges.
For the `ty` Python language server, Serena also uses an exact pinned version when invoking it through `uvx`.
```{dropdown} What Serena Downloads by Default for Language Servers
:open:
Only the language servers listed below download or install additional dependencies automatically by default when the required dependency is missing. Everything else either relies on a system-installed server or on tooling you install separately.
### Release Artifacts, Archives, or VSIX Packages
- **AL**: the pinned Microsoft AL VS Code extension (`ms-dynamics-smb.al`) from the VS Code Marketplace.
- **C/C++ (`clangd`)**: pinned `clangd` release archives on supported platforms.
- **C# (Roslyn LS)**: pinned Roslyn language-server NuGet package for the current platform.
- **Clojure**: pinned `clojure-lsp` release artifact.
- **Dart**: pinned Dart SDK archive that contains the language server.
- **Elixir (`expert`)**: pinned Expert release binary, if not already available locally.
- **Groovy**: pinned `vscode-java` runtime bundle used to provide Java for the Groovy LS setup.
- **HLSL / shader-language-server**: pinned GitHub release artifacts on supported prebuilt platforms.
- **Java (`eclipse.jdt.ls`)**: pinned Gradle distribution, pinned `vscode-java` extension bundle, and pinned IntelliCode VSIX.
- **Kotlin**: pinned Kotlin LSP archive.
- **Lua**: pinned `lua-language-server` release archive.
- **Luau**: pinned `luau-lsp` release archive. In Roblox or standard-doc modes it may also download Luau/Roblox docs and type-definition files.
- **Markdown (`marksman`)**: pinned Marksman release binary.
- **MATLAB**: the pinned MathWorks MATLAB VS Code extension from the VS Code Marketplace.
- **OmniSharp (legacy C# backend)**: pinned OmniSharp and Razor plugin archives.
- **Pascal**: pinned Pascal language-server release artifact.
- **PHP (`phpactor`)**: pinned `phpactor.phar`.
- **PowerShell**: pinned PowerShell Editor Services archive.
- **SystemVerilog (`verible`)**: pinned Verible release archive on supported platforms.
- **TOML (`taplo`)**: pinned Taplo release artifact.
- **Terraform**: pinned `terraform-ls` release archive. The Terraform CLI itself must still already be installed.
### npm Package Installs
- **Angular**: `@angular/language-server`, `@angular/language-service`, plus `typescript` and `typescript-language-server`
- **Ansible**: `@ansible/ansible-language-server`
- **Bash**: `bash-language-server`
- **Elm**: `@elm-tooling/elm-language-server`
- **HTML**: `vscode-langservers-extracted` (provides `vscode-html-language-server`)
- **PHP (`intelephense`)**: `intelephense`
- **SCSS / Sass / CSS**: `some-sass-language-server`
- **Solidity**: `@nomicfoundation/solidity-language-server`
- **Svelte**: `svelte-language-server`
- **TypeScript**: `typescript` and `typescript-language-server`
- **Vue**: `@vue/language-server`, plus `typescript` and `typescript-language-server`
- **VTSLS**: `@vtsls/language-server`
- **YAML**: `yaml-language-server`
All of the above are installed with exact pinned package versions by default, into Serena-managed directories.
### Other Package-Manager Based Installs
- **F#**: installs pinned `fsautocomplete` via `dotnet tool install`.
- **Ruby (`ruby-lsp`)**: if not already available through Bundler or as a global executable, Serena installs a pinned `ruby-lsp` gem.
- **Python (`ty`)**: launched through `uvx` / `uv x` using an exact pinned `ty` version.
- **HLSL on macOS**: if no prebuilt binary is used, Serena builds `shader_language_server` from a pinned version using Cargo.
### No Automatic Download by Serena
- **Python (`pyright`)**: Serena uses the locally available Python environment and starts `pyright.langserver` from there.
- **Go (`gopls`)**, **Rust (`rust-analyzer`)**, and several other system-tool based integrations expect the language server to be available locally and do not download it automatically.
```
## /docs/02-usage/999_additional-usage.md
# Additional Usage Pointers
## Prompting Strategies
We found that it is often a good idea to spend some time conceptualizing and planning a task
before actually implementing it, especially for non-trivial task. This helps both in achieving
better results and in increasing the feeling of control and staying in the loop. You can
make a detailed plan in one session, where Serena may read a lot of your code to build up the context,
and then continue with the implementation in another (potentially after creating suitable memories).
## Running Out of Context
For long and complicated tasks, or tasks where Serena has read a lot of content, you
may come close to the limits of context tokens. In that case, it is often a good idea to continue
in a new conversation. Serena has a dedicated tool to create a summary of the current state
of the progress and all relevant info for continuing it. You can request to create this summary and
write it to a memory. Then, in a new conversation, you can just ask Serena to read the memory and
continue with the task. In our experience, this worked really well. On the up-side, since in a
single session there is no summarization involved, Serena does not usually get lost (unlike some
other agents that summarize under the hood), and it is also instructed to occasionally check whether
it's on the right track.
Serena instructs the LLM to be economical in general, so the problem of running out of context
should not occur too often, unless the task is very large or complicated.
## Serena and Git Worktrees
[git-worktree](https://git-scm.com/docs/git-worktree) can be an excellent way to parallelize your work. More on this in [Anthropic: Run parallel Claude Code sessions with Git worktrees](https://docs.claude.com/en/docs/claude-code/common-workflows#run-parallel-claude-code-sessions-with-git-worktrees).
When it comes to serena AND git-worktree AND larger projects (that take longer to index),
the recommended way is to COPY your `$ORIG_PROJECT/.serena/cache` to `$GIT_WORKTREE/.serena/cache`.
Perform [pre-indexing of your project](indexing) to avoid having to re-index per each worktree you create.
## /docs/03-special-guides/000_intro.md
# Special Guides
This section contains special guides for certain topics that require more in-depth explanations.
## /docs/03-special-guides/cpp_setup.md
# C/C++ Setup Guide
This guide explains how to prepare a C/C++ project so that Serena can provide reliable code intelligence via clangd or ccls language servers.
This is only necessary if you use the language server variant of Serena, for users of the Serena JetBrains plugin no setup is required
and the limitations described below do not apply.
---
## General
Serena supports two C/C++ language servers, clangd (default) and ccls.
Both have their pros and cons and require a properly configured `compile_commands.json`
for cross-file reference finding, see below for details.
Your project must have a `compile_commands.json` file at the repository root.
This file is essential for correct parsing and cross-file reference finding.
You can use a specific clangd or ccls installation (e.g., a custom build or a version provided by your project),
by specifying the path in your configuration, see [ls-specific-settings](ls-specific-settings) for details.
## compile_commands.json Requirements
For reliable cross-file reference finding with clangd, your `compile_commands.json` must:
1. **Include proper C++ standard flags** (e.g., `-std=c++17`)
2. **Include all necessary include paths** (`-I` flags)
---
### With clangd
By default, Serena automatically downloads and manages clangd. Since clangd does not properly work with relative paths in `compile_commands.json`,
Serena will detect them and transform them into absolute paths automatically (writing a new `compile_commands.json` file), if needed.
#### Customizing the Compilation Database Location
By default, Serena creates the transformed compilation database at `.serena/compile_commands.json`.
You can customize this location via project settings:
```yaml
# .serena/project.yml
language_servers:
cpp:
compile_commands_dir: custom/rel/path (defaults to .serena)
```
### With ccls
ccls requires manual installation and configuration. It may perform better in some situations.
#### Installation
**Linux:**
```bash
# Ubuntu/Debian (22.04+)
sudo apt-get install ccls
# Fedora/RHEL
sudo dnf install ccls
# Arch Linux
sudo pacman -S ccls
```
**macOS:**
```bash
brew install ccls
```
**Windows:**
```bash
choco install ccls
```
#### Configuration
After installing ccls, configure Serena to use it via project settings (in `.serena/project.yml`)
by adding `cpp_ccls` to the `languages` list. Replace `cpp` with `cpp_ccls` if you already have the `cpp` entry.
ccls can handle relative paths in `compile_commands.json`, so no transformation is necessary
and no transformed `compile_commands.json` file will be created.
---
## Known Limitations
### Files Created After Server Initialization
Both clangd and ccls have a fundamental limitation:
**files created by external mechanisms after the language server starts are not automatically indexed**.
Cross-file references to newly created files will not work unless the new file is at some point opened by the language server (for example, by a symbol lookup in it), or until `compile_commands.json` is updated and
the language server is restarted.
---
## Reference
- Clangd official documentation: https://clangd.llvm.org/
- Clangd project setup: https://clangd.llvm.org/installation#project-setup
- CCLS repository: https://github.com/MaskRay/ccls
## /docs/03-special-guides/custom_agent.md
# Custom Agents with Serena
As a reference implementation, we provide an integration with the [Agno](https://docs.agno.com/introduction/playground) agent framework.
Agno is a model-agnostic agent framework that allows you to turn Serena into an agent
(independent of the MCP technology) with a large number of underlying LLMs. While Agno has recently
added support for MCP servers out of the box, our Agno integration predates this and is a good illustration of how
easy it is to integrate Serena into an arbitrary agent framework.
Here's how it works:
1. Download the agent-ui code with npx
```shell
npx create-agent-ui@latest
```
or, alternatively, clone it manually:
```shell
git clone https://github.com/agno-agi/agent-ui.git
cd agent-ui
pnpm install
pnpm dev
```
2. Install serena with the optional requirements:
```shell
# You can also only select agno,google or agno,anthropic instead of all-extras
uv pip install --all-extras -r pyproject.toml -e .
```
3. Copy `.env.example` to `.env` and fill in the API keys for the provider(s) you
intend to use.
4. Start the agno agent app with
```shell
uv run python scripts/agno_agent.py
```
By default, the script uses Claude as the model, but you can choose any model
supported by Agno (which is essentially any existing model).
5. In a new terminal, start the agno UI with
```shell
cd agent-ui
pnpm dev
```
Connect the UI to the agent you started above and start chatting. You will have
the same tools as in the MCP server version.
Here is a short demo of Serena performing a small analysis task with the newest Gemini model:
https://github.com/user-attachments/assets/ccfcb968-277d-4ca9-af7f-b84578858c62
⚠️ IMPORTANT: In contrast to the MCP server approach, tool execution in the Agno UI does
not ask for the user's permission. The shell tool is particularly critical, as it can perform arbitrary code execution.
While we have never encountered any issues with
this in our testing with Claude, allowing this may not be entirely safe.
You may choose to disable certain tools for your setup in your Serena project's
configuration file (`.yml`).
## Other Agent Frameworks
It should be straightforward to incorporate Serena into any
agent framework (like [pydantic-ai](https://ai.pydantic.dev/), [langgraph](https://langchain-ai.github.io/langgraph/tutorials/introduction/) or others).
Typically, you need only to write an adapter for Serena's tools to the tool representation in the framework of your choice,
as was done by us for Agno with `SerenaAgnoToolkit` (see `/src/serena/agno.py`).
## /docs/03-special-guides/godot_gdscript_setup_guide_for_serena.md
# GDScript (Godot Engine) Setup Guide for Serena
This guide explains how to prepare a Godot project so that Serena can provide code intelligence for GDScript (`.gd`) files via Godot's built-in Language Server Protocol (LSP) support.
Unlike most language servers, Serena does **not** launch a separate LSP process for GDScript. Instead, Serena connects over TCP to the LSP server that the Godot editor itself runs while it is open. This means the Godot editor must already be running with your project loaded before you start Serena.
---
## Prerequisites
- Godot Engine 3.x or 4.x installed and available on your system.
- A Godot project with a `project.godot` file at the project root.
No additional language server needs to be installed — Godot ships with a built-in LSP server that is enabled by default.
---
## How It Works
When a Godot project is open in the editor, the editor listens for LSP connections on **TCP port 6008** (the same default for both Godot 3 and Godot 4). Serena connects to this port and communicates using standard LSP Content-Length framing.
Serena automatically detects which major version of Godot your project targets by reading the `config_version` field from `project.godot`:
- `config_version` = 5 → Godot 4
- `config_version` = 4 → Godot 3
If `config_version` is not recognized (e.g. from a future Godot release), Serena logs a warning and still connects — both Godot 3 and Godot 4 use the same port.
No additional configuration is needed for version detection.
---
## Setup Steps
1. Open your Godot project in the Godot editor and allow it to finish loading.
2. Verify that the built-in LSP is enabled (it is on by default):
- Go to **Editor → Editor Settings → Network → Language Server**
- Confirm **"Use Language Server"** is checked.
- Confirm the port is **6008** (the default).
3. Add `gdscript` to the `languages` list in your project's Serena configuration:
```yaml
# .serena/project.yml
languages:
- gdscript
```
4. Start Serena in your project root. Serena will connect to the already-running Godot editor automatically.
---
## Using Serena with GDScript
- Serena recognizes `.gd` and `.gdscript` files. The language identifier used in LSP communication is `gdscript`.
- The Godot editor must remain open for the entire Serena session. If the editor is closed, Serena will lose its connection and will need to be restarted once the editor is open again.
- On first use, you may see a brief delay while Serena establishes the TCP connection and the editor indexes your project files — this is expected.
---
## Performance Note
Godot's built-in LSP does not implement the `workspace/symbol` request (global symbol search across the whole project). As a result, when Serena performs a workspace-wide symbol search — for example, calling `find_symbol` without a `relative_path` — it must fall back to sending a `textDocument/documentSymbol` request for **every `.gd` file** in the project individually.
For large projects, this initial full-project scan can take **30–60 seconds or more**.
To mitigate this:
- **Pass `relative_path` whenever possible.** Narrowing a search to a specific file or subdirectory avoids scanning the entire workspace.
- **Let the first full scan complete.** Serena caches the results to disk after the initial scan. Subsequent Serena sessions will use the on-disk cache and start instantly.
---
## Known Limitations
| Limitation | Detail |
|---|---|
| No `workspace/symbol` support | Godot's LSP does not implement this request. All symbol lookups fall back to per-file `documentSymbol` requests, making the first full-project scan slow. |
| Editor must stay open | Serena requires the Godot editor to be running throughout the session. Closing the editor breaks the TCP connection; restart Serena after reopening the editor. |
| Slower workspace operations | `find_symbol` and `find_references` across the whole workspace are slower than for languages whose LSP servers support native workspace-wide queries. |
---
## Advanced Configuration
You can customize Serena's GDScript connection via `ls_specific_settings` in your `serena_config.yml` or `project.yml`:
```yaml
ls_specific_settings:
gdscript:
port: 6008 # TCP port the Godot editor listens on (default: 6008)
request_timeout: 30.0 # seconds to wait for an LSP response (default: 30.0)
```
These override the defaults only if explicitly set.
---
## Reference
- Godot LSP documentation: [https://docs.godotengine.org/en/stable/tutorials/editor/external_editor.html](https://docs.godotengine.org/en/stable/tutorials/editor/external_editor.html)
- GDScript language reference: [https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/](https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/)
## /docs/03-special-guides/groovy_setup_guide_for_serena.md
# Groovy Setup Guide for Serena
The Groovy support in Serena is incomplete and requires the user to provide a functioning,
JVM-based Groovy language server as a jar. This intermediate state allows the contributors
of Groovy support to use Serena internally and hopefully to accelerate their open-source
release of a Groovy language server in the future.
If you happen to have a Groovy language server JAR file, you can configure Serena to use it
by following the instructions below.
---
## Prerequisites
- Groovy Language Server JAR file
- Can be any open-source Groovy language server or your custom implementation
- The JAR must be compatible with standard LSP protocol
---
## Configuration
Configure Groovy Language Server by adding settings to your `~/.serena/serena_config.yml`:
### Basic Configuration
```yaml
ls_specific_settings:
groovy:
ls_jar_path: '/path/to/groovy-language-server.jar'
ls_jar_options: '-Xmx2G -Xms512m'
```
### Custom Java Paths
If you have specific Java installations:
```yaml
ls_specific_settings:
groovy:
ls_jar_path: '/path/to/groovy-language-server.jar'
ls_java_home_path: '/usr/lib/jvm/java-21-openjdk' # Custom JAVA_HOME directory
ls_jar_options: '-Xmx2G -Xms512m' # Optional JVM options
```
### Configuration Options
- `ls_jar_path`: Absolute path to your Groovy Language Server JAR file (required)
- `ls_java_home_path`: Custom JAVA_HOME directory for Java installation (optional)
- When specified, Serena will use this Java installation instead of downloading bundled Java
- Java executable path is automatically determined based on platform:
- Windows: `{ls_java_home_path}/bin/java.exe`
- Linux/macOS: `{ls_java_home_path}/bin/java`
- Validates that Java executable exists at the expected location
- `ls_jar_options`: JVM options for language server (optional)
- Common options:
- `-Xmx<size>`: Maximum heap size (e.g., `-Xmx2G` for 2GB)
- `-Xms<size>`: Initial heap size (e.g., `-Xms512m` for 512MB)
---
## Project Structure Requirements
For optimal Groovy Language Server performance, ensure your project follows standard Groovy/Gradle structure:
```
project-root/
├── src/
│ ├── main/
│ │ ├── groovy/
│ │ └── resources/
│ └── test/
│ ├── groovy/
│ └── resources/
├── build.gradle or build.gradle.kts
├── settings.gradle or settings.gradle.kts
└── gradle/
└── wrapper/
```
---
## Using Serena with Groovy
- Serena automatically detects Groovy files (`*.groovy`, `*.gvy`) and will start a Groovy Language Server JAR process per project when needed.
- Optimal results require that your project compiles successfully via Gradle or Maven. If compilation fails, fix build errors in your build tool first.
## Reference
- **Groovy Documentation**: [https://groovy-lang.org/documentation.html](https://groovy-lang.org/documentation.html)
- **Gradle Documentation**: [https://docs.gradle.org](https://docs.gradle.org)
- **Serena Configuration**: [../02-usage/050_configuration.md](../02-usage/050_configuration.md)
## /docs/03-special-guides/ocaml_setup_guide_for_serena.md
# OCaml Setup Guide for Serena
This guide explains how to set up an OCaml project so that Serena can provide code intelligence via ocaml-lsp-server (ocamllsp).
Unlike some other languages, Serena does not download the OCaml language server automatically. You must install it yourself via opam, as OCaml tooling is compiled from source against your specific environment.
---
## Prerequisites
Install the following on your system and ensure they are available on `PATH`:
- **opam** (OCaml package manager)
- macOS: `brew install opam`
- Ubuntu/Debian: `sudo apt install opam`
- Fedora: `sudo dnf install opam`
- Other: https://opam.ocaml.org/doc/Install.html
- **OCaml compiler** (via opam)
- OCaml < 5.1 or >= 5.1.1 (OCaml 5.1.0 is **not supported** by ocaml-lsp-server)
- Recommended: OCaml 4.14.x (stable) or 5.2+ (for cross-file references)
- **ocaml-lsp-server** (via opam)
- **dune** (build system, via opam)
---
## Installation
1. Initialize opam if you haven't already:
```bash
opam init
eval $(opam env)
```
2. Create an opam switch with a compatible OCaml version:
```bash
# For cross-file reference support (recommended)
opam switch create serena-ocaml ocaml-base-compiler.5.2.1
eval $(opam env)
# Or for stable OCaml 4.14.x
opam switch create serena-ocaml ocaml-base-compiler.4.14.2
eval $(opam env)
```
3. Install the language server and build tools:
```bash
opam install ocaml-lsp-server dune
```
4. Verify the installation:
```bash
opam exec -- ocamllsp --version
opam exec -- ocaml -version
```
---
## Cross-File References
Cross-file reference support (finding all usages of a symbol across your project) requires:
- OCaml >= 5.2
- ocaml-lsp-server >= 1.23.0
- dune >= 3.16.0
When these requirements are met, Serena automatically builds the cross-file index during startup via `dune build @ocaml-index`. Without these versions, references are limited to the current file.
---
## Using Serena with OCaml
- Serena automatically detects OCaml files (`*.ml`, `*.mli`) and Reason files (`*.re`, `*.rei`).
- The language server is started via `opam exec -- ocamllsp`, so your opam environment must be configured.
- Ensure your project builds successfully with `dune build` before using Serena for best results.
---
## Troubleshooting
| Problem | Solution |
|---------|----------|
| "opam not found" | Install opam and add it to PATH |
| "OCaml 5.1.0 is incompatible" | Create a new switch: `opam switch create <name> ocaml-base-compiler.5.2.1` |
| "ocaml-lsp-server not found" | `opam install ocaml-lsp-server` |
| Cross-file refs not working | Ensure OCaml >= 5.2 and ocaml-lsp-server >= 1.23.0; run `dune build` first |
| Stale index | Rebuild with `dune build @ocaml-index` |
---
## Reference
- opam: https://opam.ocaml.org
- ocaml-lsp-server: https://github.com/ocaml/ocaml-lsp
- Project-wide occurrences: https://discuss.ocaml.org/t/ann-project-wide-occurrences-in-merlin-and-lsp/14847
## /docs/04-evaluation/020_prompts/000_prompts.md
# Prompts
Our evaluation uses two prompts, which are passed to the LLM in order to generate the evaluation results:
1. the [main evaluation prompt](010_evaluation-prompt), which performs the analysis
2. the [summary prompt](020_summary-prompt), which condenses the results
## /docs/04-evaluation/020_prompts/020_summary-prompt.md
# Summary Prompt
We used the prompt below to summarize the evaluation of Serena.
```
Write a one-sentence user-facing summary about the value that Serena's tools
provide for coding. With a bit of emotion but grounded in the evaluation that
you have done above. It should be written from the perspective of a coding AI
agent and make it clear whether an AI agent would ask its owner to add Serena's
tools or not. It will be the first sentence that a potential new user will see
about how useful Serena is for an AI agent.
```
## /src/serena/config/__init__.py
```py path="/src/serena/config/__init__.py"
```
The content has been capped at 50000 tokens. The user could consider applying other filters to refine the result. The better and more specific the context, the better the LLM can follow instructions. If the context seems verbose, the user can refine the filter using uithub. Thank you for using https://uithub.com - Perfect LLM context for any GitHub repo.