#
tokens: 49672/50000 190/410 files (page 1/21)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 1 of 21. Use http://codebase.md/oraios/serena?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .devcontainer
│   └── devcontainer.json
├── .dockerignore
├── .env.example
├── .github
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE
│   │   ├── config.yml
│   │   ├── feature_request.md
│   │   └── issue--bug--performance-problem--question-.md
│   └── workflows
│       ├── codespell.yml
│       ├── docker.yml
│       ├── docs.yaml
│       ├── junie.yml
│       ├── publish.yml
│       └── pytest.yml
├── .gitignore
├── .serena
│   ├── .gitignore
│   ├── memories
│   │   ├── adding_new_language_support_guide.md
│   │   ├── serena_core_concepts_and_architecture.md
│   │   ├── serena_repository_structure.md
│   │   └── suggested_commands.md
│   └── project.yml
├── .vscode
│   └── settings.json
├── CHANGELOG.md
├── CLAUDE.md
├── compose.yaml
├── CONTRIBUTING.md
├── docker_build_and_run.sh
├── DOCKER.md
├── Dockerfile
├── docs
│   ├── _config.yml
│   ├── _static
│   │   └── images
│   │       └── jetbrains-marketplace-button.png
│   ├── .gitignore
│   ├── 01-about
│   │   ├── 000_intro.md
│   │   ├── 010_llm-integration.md
│   │   ├── 020_programming-languages.md
│   │   ├── 030_serena-in-action.md
│   │   ├── 035_tools.md
│   │   ├── 040_comparison-to-other-agents.md
│   │   └── 050_acknowledgements.md
│   ├── 02-usage
│   │   ├── 000_intro.md
│   │   ├── 010_prerequisites.md
│   │   ├── 020_running.md
│   │   ├── 025_jetbrains_plugin.md
│   │   ├── 030_clients.md
│   │   ├── 040_workflow.md
│   │   ├── 050_configuration.md
│   │   ├── 060_dashboard.md
│   │   ├── 070_security.md
│   │   └── 999_additional-usage.md
│   ├── 03-special-guides
│   │   ├── 000_intro.md
│   │   ├── custom_agent.md
│   │   ├── groovy_setup_guide_for_serena.md
│   │   ├── scala_setup_guide_for_serena.md
│   │   └── serena_on_chatgpt.md
│   ├── autogen_rst.py
│   ├── create_toc.py
│   └── index.md
├── flake.lock
├── flake.nix
├── lessons_learned.md
├── LICENSE
├── llms-install.md
├── pyproject.toml
├── README.md
├── repo_dir_sync.py
├── resources
│   ├── jetbrains-marketplace-button.cdr
│   ├── serena-icons.cdr
│   ├── serena-logo-dark-mode.svg
│   ├── serena-logo.cdr
│   ├── serena-logo.svg
│   └── vscode_sponsor_logo.png
├── roadmap.md
├── scripts
│   ├── agno_agent.py
│   ├── demo_run_tools.py
│   ├── gen_prompt_factory.py
│   ├── mcp_server.py
│   ├── print_mode_context_options.py
│   ├── print_tool_overview.py
│   └── profile_tool_call.py
├── src
│   ├── interprompt
│   │   ├── __init__.py
│   │   ├── .syncCommitId.remote
│   │   ├── .syncCommitId.this
│   │   ├── jinja_template.py
│   │   ├── multilang_prompt.py
│   │   ├── prompt_factory.py
│   │   └── util
│   │       ├── __init__.py
│   │       └── class_decorators.py
│   ├── README.md
│   ├── serena
│   │   ├── __init__.py
│   │   ├── agent.py
│   │   ├── agno.py
│   │   ├── analytics.py
│   │   ├── cli.py
│   │   ├── code_editor.py
│   │   ├── config
│   │   │   ├── __init__.py
│   │   │   ├── context_mode.py
│   │   │   └── serena_config.py
│   │   ├── constants.py
│   │   ├── dashboard.py
│   │   ├── generated
│   │   │   └── generated_prompt_factory.py
│   │   ├── gui_log_viewer.py
│   │   ├── ls_manager.py
│   │   ├── mcp.py
│   │   ├── project.py
│   │   ├── prompt_factory.py
│   │   ├── resources
│   │   │   ├── config
│   │   │   │   ├── contexts
│   │   │   │   │   ├── agent.yml
│   │   │   │   │   ├── chatgpt.yml
│   │   │   │   │   ├── claude-code.yml
│   │   │   │   │   ├── codex.yml
│   │   │   │   │   ├── context.template.yml
│   │   │   │   │   ├── desktop-app.yml
│   │   │   │   │   ├── ide.yml
│   │   │   │   │   └── oaicompat-agent.yml
│   │   │   │   ├── internal_modes
│   │   │   │   │   └── jetbrains.yml
│   │   │   │   ├── modes
│   │   │   │   │   ├── editing.yml
│   │   │   │   │   ├── interactive.yml
│   │   │   │   │   ├── mode.template.yml
│   │   │   │   │   ├── no-memories.yml
│   │   │   │   │   ├── no-onboarding.yml
│   │   │   │   │   ├── onboarding.yml
│   │   │   │   │   ├── one-shot.yml
│   │   │   │   │   └── planning.yml
│   │   │   │   └── prompt_templates
│   │   │   │       ├── simple_tool_outputs.yml
│   │   │   │       └── system_prompt.yml
│   │   │   ├── dashboard
│   │   │   │   ├── dashboard.css
│   │   │   │   ├── dashboard.js
│   │   │   │   ├── index.html
│   │   │   │   ├── jquery.min.js
│   │   │   │   ├── serena-icon-16.png
│   │   │   │   ├── serena-icon-32.png
│   │   │   │   ├── serena-icon-48.png
│   │   │   │   ├── serena-logo-dark-mode.svg
│   │   │   │   ├── serena-logo.svg
│   │   │   │   ├── serena-logs-dark-mode.png
│   │   │   │   └── serena-logs.png
│   │   │   ├── project.template.yml
│   │   │   └── serena_config.template.yml
│   │   ├── symbol.py
│   │   ├── task_executor.py
│   │   ├── text_utils.py
│   │   ├── tools
│   │   │   ├── __init__.py
│   │   │   ├── cmd_tools.py
│   │   │   ├── config_tools.py
│   │   │   ├── file_tools.py
│   │   │   ├── jetbrains_plugin_client.py
│   │   │   ├── jetbrains_tools.py
│   │   │   ├── memory_tools.py
│   │   │   ├── symbol_tools.py
│   │   │   ├── tools_base.py
│   │   │   └── workflow_tools.py
│   │   └── util
│   │       ├── class_decorators.py
│   │       ├── cli_util.py
│   │       ├── exception.py
│   │       ├── file_system.py
│   │       ├── general.py
│   │       ├── git.py
│   │       ├── gui.py
│   │       ├── inspection.py
│   │       ├── logging.py
│   │       ├── shell.py
│   │       └── thread.py
│   └── solidlsp
│       ├── __init__.py
│       ├── .gitignore
│       ├── language_servers
│       │   ├── al_language_server.py
│       │   ├── bash_language_server.py
│       │   ├── clangd_language_server.py
│       │   ├── clojure_lsp.py
│       │   ├── common.py
│       │   ├── csharp_language_server.py
│       │   ├── dart_language_server.py
│       │   ├── eclipse_jdtls.py
│       │   ├── elixir_tools
│       │   │   ├── __init__.py
│       │   │   ├── elixir_tools.py
│       │   │   └── README.md
│       │   ├── elm_language_server.py
│       │   ├── erlang_language_server.py
│       │   ├── fortran_language_server.py
│       │   ├── fsharp_language_server.py
│       │   ├── gopls.py
│       │   ├── groovy_language_server.py
│       │   ├── haskell_language_server.py
│       │   ├── intelephense.py
│       │   ├── jedi_server.py
│       │   ├── julia_server.py
│       │   ├── kotlin_language_server.py
│       │   ├── lua_ls.py
│       │   ├── marksman.py
│       │   ├── matlab_language_server.py
│       │   ├── nixd_ls.py
│       │   ├── omnisharp
│       │   │   ├── initialize_params.json
│       │   │   ├── runtime_dependencies.json
│       │   │   └── workspace_did_change_configuration.json
│       │   ├── omnisharp.py
│       │   ├── pascal_server.py
│       │   ├── perl_language_server.py
│       │   ├── powershell_language_server.py
│       │   ├── pyright_server.py
│       │   ├── r_language_server.py
│       │   ├── regal_server.py
│       │   ├── ruby_lsp.py
│       │   ├── rust_analyzer.py
│       │   ├── scala_language_server.py
│       │   ├── solargraph.py
│       │   ├── sourcekit_lsp.py
│       │   ├── taplo_server.py
│       │   ├── terraform_ls.py
│       │   ├── typescript_language_server.py
│       │   ├── vts_language_server.py
│       │   ├── vue_language_server.py
│       │   ├── yaml_language_server.py
│       │   └── zls.py
│       ├── ls_config.py
│       ├── ls_exceptions.py
│       ├── ls_handler.py
│       ├── ls_request.py
│       ├── ls_types.py
│       ├── ls_utils.py
│       ├── ls.py
│       ├── lsp_protocol_handler
│       │   ├── lsp_constants.py
│       │   ├── lsp_requests.py
│       │   ├── lsp_types.py
│       │   └── server.py
│       ├── settings.py
│       └── util
│           ├── cache.py
│           ├── subprocess_util.py
│           └── zip.py
├── sync.py
├── test
│   ├── __init__.py
│   ├── conftest.py
│   ├── resources
│   │   └── repos
│   │       ├── al
│   │       │   └── test_repo
│   │       │       ├── app.json
│   │       │       └── src
│   │       │           ├── Codeunits
│   │       │           │   ├── CustomerMgt.Codeunit.al
│   │       │           │   └── PaymentProcessorImpl.Codeunit.al
│   │       │           ├── Enums
│   │       │           │   └── CustomerType.Enum.al
│   │       │           ├── Interfaces
│   │       │           │   └── IPaymentProcessor.Interface.al
│   │       │           ├── Pages
│   │       │           │   ├── CustomerCard.Page.al
│   │       │           │   └── CustomerList.Page.al
│   │       │           ├── TableExtensions
│   │       │           │   └── Item.TableExt.al
│   │       │           └── Tables
│   │       │               └── Customer.Table.al
│   │       ├── bash
│   │       │   └── test_repo
│   │       │       ├── config.sh
│   │       │       ├── main.sh
│   │       │       └── utils.sh
│   │       ├── clojure
│   │       │   └── test_repo
│   │       │       ├── deps.edn
│   │       │       └── src
│   │       │           └── test_app
│   │       │               ├── core.clj
│   │       │               └── utils.clj
│   │       ├── csharp
│   │       │   └── test_repo
│   │       │       ├── .gitignore
│   │       │       ├── Models
│   │       │       │   └── Person.cs
│   │       │       ├── Program.cs
│   │       │       ├── serena.sln
│   │       │       └── TestProject.csproj
│   │       ├── dart
│   │       │   └── test_repo
│   │       │       ├── .gitignore
│   │       │       ├── lib
│   │       │       │   ├── helper.dart
│   │       │       │   ├── main.dart
│   │       │       │   └── models.dart
│   │       │       └── pubspec.yaml
│   │       ├── elixir
│   │       │   └── test_repo
│   │       │       ├── .gitignore
│   │       │       ├── lib
│   │       │       │   ├── examples.ex
│   │       │       │   ├── ignored_dir
│   │       │       │   │   └── ignored_module.ex
│   │       │       │   ├── models.ex
│   │       │       │   ├── services.ex
│   │       │       │   ├── test_repo.ex
│   │       │       │   └── utils.ex
│   │       │       ├── mix.exs
│   │       │       ├── mix.lock
│   │       │       ├── scripts
│   │       │       │   └── build_script.ex
│   │       │       └── test
│   │       │           ├── models_test.exs
│   │       │           └── test_repo_test.exs
│   │       ├── elm
│   │       │   └── test_repo
│   │       │       ├── elm.json
│   │       │       ├── Main.elm
│   │       │       └── Utils.elm
│   │       ├── erlang
│   │       │   └── test_repo
│   │       │       ├── hello.erl
│   │       │       ├── ignored_dir
│   │       │       │   └── ignored_module.erl
│   │       │       ├── include
│   │       │       │   ├── records.hrl
│   │       │       │   └── types.hrl
│   │       │       ├── math_utils.erl
│   │       │       ├── rebar.config
│   │       │       ├── src
│   │       │       │   ├── app.erl
│   │       │       │   ├── models.erl
│   │       │       │   ├── services.erl
│   │       │       │   └── utils.erl
│   │       │       └── test
│   │       │           ├── models_tests.erl
│   │       │           └── utils_tests.erl
│   │       ├── fortran
│   │       │   └── test_repo
│   │       │       ├── main.f90
│   │       │       └── modules
│   │       │           ├── geometry.f90
│   │       │           └── math_utils.f90
│   │       ├── fsharp
│   │       │   └── test_repo
│   │       │       ├── .gitignore
│   │       │       ├── Calculator.fs
│   │       │       ├── Models
│   │       │       │   └── Person.fs
│   │       │       ├── Program.fs
│   │       │       ├── README.md
│   │       │       └── TestProject.fsproj
│   │       ├── go
│   │       │   └── test_repo
│   │       │       └── main.go
│   │       ├── groovy
│   │       │   └── test_repo
│   │       │       ├── .gitignore
│   │       │       ├── build.gradle
│   │       │       └── src
│   │       │           └── main
│   │       │               └── groovy
│   │       │                   └── com
│   │       │                       └── example
│   │       │                           ├── Main.groovy
│   │       │                           ├── Model.groovy
│   │       │                           ├── ModelUser.groovy
│   │       │                           └── Utils.groovy
│   │       ├── haskell
│   │       │   └── test_repo
│   │       │       ├── app
│   │       │       │   └── Main.hs
│   │       │       ├── haskell-test-repo.cabal
│   │       │       ├── package.yaml
│   │       │       ├── src
│   │       │       │   ├── Calculator.hs
│   │       │       │   └── Helper.hs
│   │       │       └── stack.yaml
│   │       ├── java
│   │       │   └── test_repo
│   │       │       ├── pom.xml
│   │       │       └── src
│   │       │           └── main
│   │       │               └── java
│   │       │                   └── test_repo
│   │       │                       ├── Main.java
│   │       │                       ├── Model.java
│   │       │                       ├── ModelUser.java
│   │       │                       └── Utils.java
│   │       ├── julia
│   │       │   └── test_repo
│   │       │       ├── lib
│   │       │       │   └── helper.jl
│   │       │       └── main.jl
│   │       ├── kotlin
│   │       │   └── test_repo
│   │       │       ├── .gitignore
│   │       │       ├── build.gradle.kts
│   │       │       └── src
│   │       │           └── main
│   │       │               └── kotlin
│   │       │                   └── test_repo
│   │       │                       ├── Main.kt
│   │       │                       ├── Model.kt
│   │       │                       ├── ModelUser.kt
│   │       │                       └── Utils.kt
│   │       ├── lua
│   │       │   └── test_repo
│   │       │       ├── .gitignore
│   │       │       ├── main.lua
│   │       │       ├── src
│   │       │       │   ├── calculator.lua
│   │       │       │   └── utils.lua
│   │       │       └── tests
│   │       │           └── test_calculator.lua
│   │       ├── markdown
│   │       │   └── test_repo
│   │       │       ├── api.md
│   │       │       ├── CONTRIBUTING.md
│   │       │       ├── guide.md
│   │       │       └── README.md
│   │       ├── matlab
│   │       │   └── test_repo
│   │       │       ├── Calculator.m
│   │       │       └── main.m
│   │       ├── nix
│   │       │   └── test_repo
│   │       │       ├── .gitignore
│   │       │       ├── default.nix
│   │       │       ├── flake.nix
│   │       │       ├── lib
│   │       │       │   └── utils.nix
│   │       │       ├── modules
│   │       │       │   └── example.nix
│   │       │       └── scripts
│   │       │           └── hello.sh
│   │       ├── pascal
│   │       │   └── test_repo
│   │       │       ├── .gitignore
│   │       │       ├── lib
│   │       │       │   └── helper.pas
│   │       │       └── main.pas
│   │       ├── perl
│   │       │   └── test_repo
│   │       │       ├── helper.pl
│   │       │       └── main.pl
│   │       ├── php
│   │       │   └── test_repo
│   │       │       ├── helper.php
│   │       │       ├── index.php
│   │       │       └── simple_var.php
│   │       ├── powershell
│   │       │   └── test_repo
│   │       │       ├── main.ps1
│   │       │       ├── PowerShellEditorServices.json
│   │       │       └── utils.ps1
│   │       ├── python
│   │       │   └── test_repo
│   │       │       ├── .gitignore
│   │       │       ├── custom_test
│   │       │       │   ├── __init__.py
│   │       │       │   └── advanced_features.py
│   │       │       ├── examples
│   │       │       │   ├── __init__.py
│   │       │       │   └── user_management.py
│   │       │       ├── ignore_this_dir_with_postfix
│   │       │       │   └── ignored_module.py
│   │       │       ├── scripts
│   │       │       │   ├── __init__.py
│   │       │       │   └── run_app.py
│   │       │       └── test_repo
│   │       │           ├── __init__.py
│   │       │           ├── complex_types.py
│   │       │           ├── models.py
│   │       │           ├── name_collisions.py
│   │       │           ├── nested_base.py
│   │       │           ├── nested.py
│   │       │           ├── overloaded.py
│   │       │           ├── services.py
│   │       │           ├── utils.py
│   │       │           └── variables.py
│   │       ├── r
│   │       │   └── test_repo
│   │       │       ├── .Rbuildignore
│   │       │       ├── DESCRIPTION
│   │       │       ├── examples
│   │       │       │   └── analysis.R
│   │       │       ├── NAMESPACE
│   │       │       └── R
│   │       │           ├── models.R
│   │       │           └── utils.R
│   │       ├── rego
│   │       │   └── test_repo
│   │       │       ├── policies
│   │       │       │   ├── authz.rego
│   │       │       │   └── validation.rego
│   │       │       └── utils
│   │       │           └── helpers.rego
│   │       ├── ruby
│   │       │   └── test_repo
│   │       │       ├── .solargraph.yml
│   │       │       ├── examples
│   │       │       │   └── user_management.rb
│   │       │       ├── lib.rb
│   │       │       ├── main.rb
│   │       │       ├── models.rb
│   │       │       ├── nested.rb
│   │       │       ├── services.rb
│   │       │       └── variables.rb
│   │       ├── rust
│   │       │   ├── test_repo
│   │       │   │   ├── Cargo.lock
│   │       │   │   ├── Cargo.toml
│   │       │   │   └── src
│   │       │   │       ├── lib.rs
│   │       │   │       └── main.rs
│   │       │   └── test_repo_2024
│   │       │       ├── Cargo.lock
│   │       │       ├── Cargo.toml
│   │       │       └── src
│   │       │           ├── lib.rs
│   │       │           └── main.rs
│   │       ├── scala
│   │       │   ├── build.sbt
│   │       │   ├── project
│   │       │   │   ├── build.properties
│   │       │   │   ├── metals.sbt
│   │       │   │   └── plugins.sbt
│   │       │   └── src
│   │       │       └── main
│   │       │           └── scala
│   │       │               └── com
│   │       │                   └── example
│   │       │                       ├── Main.scala
│   │       │                       └── Utils.scala
│   │       ├── swift
│   │       │   └── test_repo
│   │       │       ├── Package.swift
│   │       │       └── src
│   │       │           ├── main.swift
│   │       │           └── utils.swift
│   │       ├── terraform
│   │       │   └── test_repo
│   │       │       ├── data.tf
│   │       │       ├── main.tf
│   │       │       ├── outputs.tf
│   │       │       └── variables.tf
│   │       ├── toml
│   │       │   └── test_repo
│   │       │       ├── Cargo.toml
│   │       │       ├── config.toml
│   │       │       └── pyproject.toml
│   │       ├── typescript
│   │       │   └── test_repo
│   │       │       ├── .serena
│   │       │       │   └── project.yml
│   │       │       ├── index.ts
│   │       │       ├── tsconfig.json
│   │       │       ├── use_helper.ts
│   │       │       └── ws_manager.js
│   │       ├── vue
│   │       │   └── test_repo
│   │       │       ├── .gitignore
│   │       │       ├── index.html
│   │       │       ├── package.json
│   │       │       ├── src
│   │       │       │   ├── App.vue
│   │       │       │   ├── components
│   │       │       │   │   ├── CalculatorButton.vue
│   │       │       │   │   ├── CalculatorDisplay.vue
│   │       │       │   │   └── CalculatorInput.vue
│   │       │       │   ├── composables
│   │       │       │   │   ├── useFormatter.ts
│   │       │       │   │   └── useTheme.ts
│   │       │       │   ├── main.ts
│   │       │       │   ├── stores
│   │       │       │   │   └── calculator.ts
│   │       │       │   └── types
│   │       │       │       └── index.ts
│   │       │       ├── tsconfig.json
│   │       │       ├── tsconfig.node.json
│   │       │       └── vite.config.ts
│   │       ├── yaml
│   │       │   └── test_repo
│   │       │       ├── config.yaml
│   │       │       ├── data.yaml
│   │       │       └── services.yml
│   │       └── zig
│   │           └── test_repo
│   │               ├── .gitignore
│   │               ├── build.zig
│   │               ├── src
│   │               │   ├── calculator.zig
│   │               │   ├── main.zig
│   │               │   └── math_utils.zig
│   │               └── zls.json
│   ├── serena
│   │   ├── __init__.py
│   │   ├── __snapshots__
│   │   │   └── test_symbol_editing.ambr
│   │   ├── config
│   │   │   ├── __init__.py
│   │   │   └── test_serena_config.py
│   │   ├── test_cli_project_commands.py
│   │   ├── test_edit_marker.py
│   │   ├── test_mcp.py
│   │   ├── test_serena_agent.py
│   │   ├── test_symbol_editing.py
│   │   ├── test_symbol.py
│   │   ├── test_task_executor.py
│   │   ├── test_text_utils.py
│   │   ├── test_tool_parameter_types.py
│   │   └── util
│   │       ├── test_exception.py
│   │       └── test_file_system.py
│   └── solidlsp
│       ├── al
│       │   └── test_al_basic.py
│       ├── bash
│       │   ├── __init__.py
│       │   └── test_bash_basic.py
│       ├── clojure
│       │   ├── __init__.py
│       │   └── test_clojure_basic.py
│       ├── csharp
│       │   └── test_csharp_basic.py
│       ├── dart
│       │   ├── __init__.py
│       │   └── test_dart_basic.py
│       ├── elixir
│       │   ├── __init__.py
│       │   ├── conftest.py
│       │   ├── test_elixir_basic.py
│       │   ├── test_elixir_ignored_dirs.py
│       │   ├── test_elixir_integration.py
│       │   └── test_elixir_symbol_retrieval.py
│       ├── elm
│       │   └── test_elm_basic.py
│       ├── erlang
│       │   ├── __init__.py
│       │   ├── conftest.py
│       │   ├── test_erlang_basic.py
│       │   ├── test_erlang_ignored_dirs.py
│       │   └── test_erlang_symbol_retrieval.py
│       ├── fortran
│       │   ├── __init__.py
│       │   └── test_fortran_basic.py
│       ├── fsharp
│       │   └── test_fsharp_basic.py
│       ├── go
│       │   └── test_go_basic.py
│       ├── groovy
│       │   └── test_groovy_basic.py
│       ├── haskell
│       │   ├── __init__.py
│       │   └── test_haskell_basic.py
│       ├── java
│       │   └── test_java_basic.py
│       ├── julia
│       │   └── test_julia_basic.py
│       ├── kotlin
│       │   └── test_kotlin_basic.py
│       ├── lua
│       │   └── test_lua_basic.py
│       ├── markdown
│       │   ├── __init__.py
│       │   └── test_markdown_basic.py
│       ├── matlab
│       │   ├── __init__.py
│       │   └── test_matlab_basic.py
│       ├── nix
│       │   └── test_nix_basic.py
│       ├── pascal
│       │   ├── __init__.py
│       │   └── test_pascal_basic.py
│       ├── perl
│       │   └── test_perl_basic.py
│       ├── php
│       │   └── test_php_basic.py
│       ├── powershell
│       │   ├── __init__.py
│       │   └── test_powershell_basic.py
│       ├── python
│       │   ├── test_python_basic.py
│       │   ├── test_retrieval_with_ignored_dirs.py
│       │   └── test_symbol_retrieval.py
│       ├── r
│       │   ├── __init__.py
│       │   └── test_r_basic.py
│       ├── rego
│       │   └── test_rego_basic.py
│       ├── ruby
│       │   ├── test_ruby_basic.py
│       │   └── test_ruby_symbol_retrieval.py
│       ├── rust
│       │   ├── test_rust_2024_edition.py
│       │   ├── test_rust_analyzer_detection.py
│       │   └── test_rust_basic.py
│       ├── scala
│       │   └── test_scala_language_server.py
│       ├── swift
│       │   └── test_swift_basic.py
│       ├── terraform
│       │   └── test_terraform_basic.py
│       ├── test_lsp_protocol_handler_server.py
│       ├── toml
│       │   ├── __init__.py
│       │   ├── test_toml_basic.py
│       │   ├── test_toml_edge_cases.py
│       │   ├── test_toml_ignored_dirs.py
│       │   └── test_toml_symbol_retrieval.py
│       ├── typescript
│       │   └── test_typescript_basic.py
│       ├── util
│       │   └── test_zip.py
│       ├── vue
│       │   ├── __init__.py
│       │   ├── test_vue_basic.py
│       │   ├── test_vue_error_cases.py
│       │   ├── test_vue_rename.py
│       │   └── test_vue_symbol_retrieval.py
│       ├── yaml_ls
│       │   ├── __init__.py
│       │   └── test_yaml_basic.py
│       └── zig
│           └── test_zig_basic.py
└── uv.lock
```

# Files

--------------------------------------------------------------------------------
/test/resources/repos/elixir/test_repo/.gitignore:
--------------------------------------------------------------------------------

```
1 | 
```

--------------------------------------------------------------------------------
/.serena/.gitignore:
--------------------------------------------------------------------------------

```
1 | /cache
2 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/groovy/test_repo/.gitignore:
--------------------------------------------------------------------------------

```
1 | .gradle/
2 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/kotlin/test_repo/.gitignore:
--------------------------------------------------------------------------------

```
1 | .gradle/
2 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/python/test_repo/.gitignore:
--------------------------------------------------------------------------------

```
1 | ignore_this_dir*/
```

--------------------------------------------------------------------------------
/src/solidlsp/.gitignore:
--------------------------------------------------------------------------------

```
1 | language_servers/static
```

--------------------------------------------------------------------------------
/test/resources/repos/fsharp/test_repo/.gitignore:
--------------------------------------------------------------------------------

```
1 | bin/
2 | obj/
3 | *.user
4 | .vscode/
5 | .ionide/
```

--------------------------------------------------------------------------------
/test/resources/repos/r/test_repo/.Rbuildignore:
--------------------------------------------------------------------------------

```
1 | ^.*\.Rproj$
2 | ^\.Rproj\.user$
3 | ^\.serena$
```

--------------------------------------------------------------------------------
/src/interprompt/.syncCommitId.remote:
--------------------------------------------------------------------------------

```
1 | 059d50b7d4d7e8fb9e7a13df7f7f33bae1aed5e2
```

--------------------------------------------------------------------------------
/src/interprompt/.syncCommitId.this:
--------------------------------------------------------------------------------

```
1 | 53ee7f47c08f29ae336567bcfaf89f79e7d447a2
```

--------------------------------------------------------------------------------
/test/resources/repos/ruby/test_repo/.solargraph.yml:
--------------------------------------------------------------------------------

```yaml
1 | ---
2 | include:
3 |   - "main.rb"
4 |   - "lib.rb"
5 | 
```

--------------------------------------------------------------------------------
/docs/.gitignore:
--------------------------------------------------------------------------------

```
1 | /_toc.yml
2 | /jupyter_execute
3 | /conf.py
4 | /_build
5 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/zig/test_repo/.gitignore:
--------------------------------------------------------------------------------

```
1 | zig-cache/
2 | zig-out/
3 | .zig-cache/
4 | build/
5 | dist/
```

--------------------------------------------------------------------------------
/test/resources/repos/pascal/test_repo/.gitignore:
--------------------------------------------------------------------------------

```
1 | backup/
2 | *.o
3 | *.ppu
4 | *.exe
5 | *.lps
6 | *.compiled
7 | __history/
8 | __recovery/
9 | 
```

--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------

```
1 | GOOGLE_API_KEY=<your_google_api_key>
2 | ANTHROPIC_API_KEY=<your_key>
3 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/nix/test_repo/.gitignore:
--------------------------------------------------------------------------------

```
 1 | # Nix specific
 2 | result
 3 | result-*
 4 | .direnv/
 5 | 
 6 | # Build artifacts
 7 | *.drv
 8 | 
 9 | # IDE
10 | .vscode/
11 | .idea/
```

--------------------------------------------------------------------------------
/test/resources/repos/lua/test_repo/.gitignore:
--------------------------------------------------------------------------------

```
 1 | # Lua specific
 2 | *.luac
 3 | .luarocks/
 4 | lua_modules/
 5 | luarocks/
 6 | 
 7 | # Build artifacts
 8 | build/
 9 | dist/
10 | 
11 | # IDE
12 | .vscode/
13 | .idea/
```

--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------

```
 1 | data
 2 | logs
 3 | log
 4 | test/log
 5 | docs/jupyter_execute
 6 | docs/.jupyter_cache
 7 | docs/_build
 8 | coverage.xml
 9 | docker_build_and_run.sh
10 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/vue/test_repo/.gitignore:
--------------------------------------------------------------------------------

```
 1 | # Logs
 2 | logs
 3 | *.log
 4 | npm-debug.log*
 5 | yarn-debug.log*
 6 | yarn-error.log*
 7 | pnpm-debug.log*
 8 | lerna-debug.log*
 9 | 
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 | 
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/csharp/test_repo/.gitignore:
--------------------------------------------------------------------------------

```
 1 | # Build results
 2 | [Dd]ebug/
 3 | [Dd]ebugPublic/
 4 | [Rr]elease/
 5 | [Rr]eleases/
 6 | x64/
 7 | x86/
 8 | [Aa][Rr][Mm]/
 9 | [Aa][Rr][Mm]64/
10 | bld/
11 | [Bb]in/
12 | [Oo]bj/
13 | [Ll]og/
14 | [Ll]ogs/
15 | 
16 | # Visual Studio temporary files
17 | .vs/
18 | 
19 | # .NET Core
20 | project.lock.json
21 | project.fragment.lock.json
22 | artifacts/
23 | 
24 | # Files built by Visual Studio
25 | *.user
26 | *.userosscache
27 | *.sln.docstates
28 | 
29 | # Build results
30 | *.dll
31 | *.exe
32 | *.pdb
33 | 
34 | # NuGet
35 | *.nupkg
36 | *.snupkg
37 | packages/
```

--------------------------------------------------------------------------------
/test/resources/repos/dart/test_repo/.gitignore:
--------------------------------------------------------------------------------

```
 1 | # Files and directories created by pub
 2 | .dart_tool/
 3 | .packages
 4 | pubspec.lock
 5 | build/
 6 | 
 7 | # If you're building an application, you may want to check-in your pubspec.lock
 8 | # pubspec.lock
 9 | 
10 | # Directory created by dartdoc
11 | doc/api/
12 | 
13 | # dotenv environment variables file
14 | .env*
15 | 
16 | # Avoid committing generated Javascript files
17 | *.dart.js
18 | *.info.json      # Produced by the --dump-info flag.
19 | *.js             # When generated by dart2js. Don't specify *.js if your
20 |                  # project includes source files written in JavaScript.
21 | *.js_
22 | *.js.deps
23 | *.js.map
```

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
  1 | # macOS specific files
  2 | .DS_Store
  3 | .AppleDouble
  4 | .LSOverride
  5 | ._*
  6 | .Spotlight-V100
  7 | .Trashes
  8 | Icon
  9 | .fseventsd
 10 | .DocumentRevisions-V100
 11 | .TemporaryItems
 12 | .VolumeIcon.icns
 13 | .com.apple.timemachine.donotpresent
 14 | 
 15 | # Windows specific files
 16 | Thumbs.db
 17 | Thumbs.db:encryptable
 18 | ehthumbs.db
 19 | ehthumbs_vista.db
 20 | *.stackdump
 21 | [Dd]esktop.ini
 22 | $RECYCLE.BIN/
 23 | *.cab
 24 | *.msi
 25 | *.msix
 26 | *.msm
 27 | *.msp
 28 | *.lnk
 29 | 
 30 | # Linux specific files
 31 | *~
 32 | .fuse_hidden*
 33 | .directory
 34 | .Trash-*
 35 | .nfs*
 36 | 
 37 | # IDE/Text Editors
 38 | # VS Code
 39 | .vscode/*
 40 | !.vscode/settings.json
 41 | !.vscode/tasks.json
 42 | !.vscode/launch.json
 43 | !.vscode/extensions.json
 44 | *.code-workspace
 45 | .history/
 46 | 
 47 | # JetBrains IDEs (beyond .idea/)
 48 | *.iml
 49 | *.ipr
 50 | *.iws
 51 | out/
 52 | .idea_modules/
 53 | 
 54 | # Sublime Text
 55 | *.tmlanguage.cache
 56 | *.tmPreferences.cache
 57 | *.stTheme.cache
 58 | *.sublime-workspace
 59 | *.sublime-project
 60 | 
 61 | # Project specific ignore
 62 | .idea
 63 | temp
 64 | 
 65 | # Byte-compiled / optimized / DLL files
 66 | __pycache__/
 67 | *.py[cod]
 68 | *$py.class
 69 | 
 70 | # C extensions
 71 | *.so
 72 | 
 73 | # Distribution / packaging
 74 | .Python
 75 | build/
 76 | develop-eggs/
 77 | dist/
 78 | downloads/
 79 | eggs/
 80 | .eggs/
 81 | lib/
 82 | lib64/
 83 | parts/
 84 | sdist/
 85 | var/
 86 | wheels/
 87 | pip-wheel-metadata/
 88 | share/python-wheels/
 89 | *.egg-info/
 90 | .installed.cfg
 91 | *.egg
 92 | MANIFEST
 93 | 
 94 | # PyInstaller
 95 | #  Usually these files are written by a python script from a template
 96 | #  before PyInstaller builds the exe, so as to inject date/other infos into it.
 97 | *.manifest
 98 | *.spec
 99 | 
100 | # Installer logs
101 | pip-log.txt
102 | pip-delete-this-directory.txt
103 | 
104 | # Unit test / coverage reports
105 | htmlcov/
106 | .tox/
107 | .nox/
108 | .coverage
109 | .coverage.*
110 | .cache
111 | nosetests.xml
112 | coverage.xml
113 | *.cover
114 | *.py,cover
115 | .hypothesis/
116 | .pytest_cache/
117 | 
118 | # Translations
119 | *.mo
120 | *.pot
121 | 
122 | # Django stuff:
123 | *.log
124 | local_settings.py
125 | db.sqlite3
126 | db.sqlite3-journal
127 | 
128 | # Flask stuff:
129 | instance/
130 | .webassets-cache
131 | 
132 | # Scrapy stuff:
133 | .scrapy
134 | 
135 | # Sphinx documentation
136 | docs/_build/
137 | 
138 | # PyBuilder
139 | target/
140 | 
141 | # Jupyter Notebook
142 | .ipynb_checkpoints
143 | 
144 | # IPython
145 | profile_default/
146 | ipython_config.py
147 | 
148 | # pyenv
149 | .python-version
150 | 
151 | # pipenv
152 | #   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
153 | #   However, in case of collaboration, if having platform-specific dependencies or dependencies
154 | #   having no cross-platform support, pipenv may install dependencies that don't work, or not
155 | #   install all needed dependencies.
156 | #Pipfile.lock
157 | 
158 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
159 | __pypackages__/
160 | 
161 | # Celery stuff
162 | celerybeat-schedule
163 | celerybeat.pid
164 | 
165 | # SageMath parsed files
166 | *.sage.py
167 | 
168 | # Environments
169 | .env
170 | .venv
171 | env/
172 | venv/
173 | ENV/
174 | env.bak/
175 | venv.bak/
176 | 
177 | # Spyder project settings
178 | .spyderproject
179 | .spyproject
180 | 
181 | # Rope project settings
182 | .ropeproject
183 | 
184 | # mkdocs documentation
185 | /site
186 | 
187 | # mypy
188 | .mypy_cache/
189 | .dmypy.json
190 | dmypy.json
191 | 
192 | # Pyre type checker
193 | .pyre/
194 | 
195 | # reports
196 | pylint.html
197 | .pylint.d
198 | 
199 | # Serena-specific
200 | /*.yml
201 | !*.template.yml
202 | /agent-ui
203 | /test/**/.serena
204 | 
205 | # clojure-lsp temporary files
206 | .calva/
207 | .clj-kondo/
208 | .cpcache/
209 | .lsp/
210 | 
211 | # temporary and backup files
212 | *.bak
213 | *.tmp
214 | tmp/
215 | 
216 | .vscode/
217 | 
218 | # Claude settings
219 | .claude/settings.local.json
220 | 
221 | # Elixir
222 | /test/resources/repos/elixir/test_repo/deps
223 | # Exception: Don't ignore Elixir test repository lib directory (contains source code)
224 | !/test/resources/repos/elixir/test_repo/lib
225 | 
226 | # Exception: Don't ignore Nix test repository lib directory (contains source code)
227 | !/test/resources/repos/nix/test_repo/lib
228 | 
229 | # Exception: Don't ignore Julia test repository lib directory (contains source code)
230 | !/test/resources/repos/julia/test_repo/lib
231 | 
232 | # Swift
233 | /test/resources/repos/swift/test_repo/.build
234 | /test/resources/repos/swift/test_repo/.swiftpm
235 | 
236 | # Elm
237 | /test/resources/repos/elm/test_repo/.elm/
238 | /test/resources/repos/elm/test_repo/elm-stuff/
239 | 
240 | # Scala
241 | .metals/
242 | .bsp/
243 | .scala-build/
244 | .bloop/
245 | bootstrap
246 | test/resources/repos/scala/.bloop/
247 | 
248 | # Haskell
249 | .stack-work/
250 | *.cabal
251 | stack.yaml.lock
252 | dist-newstyle/
253 | cabal.project.local*
254 | .ghc.environment.*
255 | 
256 | zz-misc/
257 | vue-implementation/
```

--------------------------------------------------------------------------------
/src/README.md:
--------------------------------------------------------------------------------

```markdown
1 | Serena uses (modified) versions of other libraries/packages:
2 | 
3 |  * solidlsp (our fork of [microsoft/multilspy](https://github.com/microsoft/multilspy) for fully synchronous language server communication)
4 |  * [interprompt](https://github.com/oraios/interprompt) (our prompt templating library)
5 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/fsharp/test_repo/README.md:
--------------------------------------------------------------------------------

```markdown
 1 | # F# Test Project
 2 | 
 3 | This is a test F# project for testing Serena's F# language support.
 4 | 
 5 | ## Project Structure
 6 | 
 7 | - `Program.fs` - Main program entry point
 8 | - `Calculator.fs` - Calculator functions and types
 9 | - `Models/Person.fs` - Person and Employee data models
10 | 
11 | ## Build
12 | 
13 | ```bash
14 | dotnet build
15 | ```
16 | 
17 | ## Run
18 | 
19 | ```bash
20 | dotnet run
21 | ```
```

--------------------------------------------------------------------------------
/test/resources/repos/markdown/test_repo/README.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Test Repository
 2 | 
 3 | This is a test repository for markdown language server testing.
 4 | 
 5 | ## Overview
 6 | 
 7 | This repository contains sample markdown files for testing LSP features.
 8 | 
 9 | ## Features
10 | 
11 | - Document symbol detection
12 | - Link navigation
13 | - Reference finding
14 | - Code completion
15 | 
16 | ### Installation
17 | 
18 | To use this test repository:
19 | 
20 | 1. Clone the repository
21 | 2. Install dependencies
22 | 3. Run tests
23 | 
24 | ### Usage
25 | 
26 | See [guide.md](guide.md) for detailed usage instructions.
27 | 
28 | ## Code Examples
29 | 
30 | Here's a simple example:
31 | 
32 | ```python
33 | def hello_world():
34 |     print("Hello, World!")
35 | ```
36 | 
37 | ### JavaScript Example
38 | 
39 | ```javascript
40 | function greet(name) {
41 |     console.log(`Hello, ${name}!`);
42 | }
43 | ```
44 | 
45 | ## References
46 | 
47 | - [Official Documentation](https://example.com/docs)
48 | - [API Reference](api.md)
49 | - [Contributing Guide](CONTRIBUTING.md)
50 | 
51 | ## License
52 | 
53 | MIT License
54 | 
```

--------------------------------------------------------------------------------
/src/solidlsp/language_servers/elixir_tools/README.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Elixir Language Server Integration
 2 | 
 3 | This directory contains the integration for Elixir language support using [Expert](https://github.com/elixir-lang/expert), the official Elixir language server.
 4 | 
 5 | ## Prerequisites
 6 | 
 7 | Before using the Elixir language server integration, you need to have:
 8 | 
 9 | 1. **Elixir** installed and available in your PATH
10 |    - Install from: https://elixir-lang.org/install.html
11 |    - Verify with: `elixir --version`
12 | 
13 | 2. **Expert** (optional - will be downloaded automatically if not found)
14 |    - Expert binaries are automatically downloaded from GitHub releases
15 |    - Manual installation: https://github.com/elixir-lang/expert#installation
16 |    - If installed manually, ensure `expert` is in your PATH
17 | 
18 | ## Features
19 | 
20 | The Elixir integration provides:
21 | 
22 | - **Language Server Protocol (LSP) support** via Next LS
23 | - **File extension recognition** for `.ex` and `.exs` files
24 | - **Project structure awareness** with proper handling of Elixir-specific directories:
25 |   - `_build/` - Compiled artifacts (ignored)
26 |   - `deps/` - Dependencies (ignored)
27 |   - `.elixir_ls/` - ElixirLS artifacts (ignored)
28 |   - `cover/` - Coverage reports (ignored)
29 |   - `lib/` - Source code (not ignored)
30 |   - `test/` - Test files (not ignored)
31 | 
32 | ## Configuration
33 | 
34 | The integration uses the default Expert configuration with:
35 | 
36 | - **MIX_ENV**: `dev`
37 | - **MIX_TARGET**: `host`
38 | - **Experimental completions**: Disabled by default
39 | - **Credo extension**: Enabled by default
40 | 
41 | ### Version Management (asdf)
42 | 
43 | Expert automatically respects project-specific Elixir versions when using asdf:
44 | - If a `.tool-versions` file exists in the project root, Expert will use the specified Elixir version
45 | - Expert is launched from the project directory, allowing it to pick up project configuration
46 | - No additional configuration needed - just ensure asdf is installed and the project has a `.tool-versions` file
47 | 
48 | ## Usage
49 | 
50 | The Elixir language server is automatically selected when working with Elixir projects. It will be used for:
51 | 
52 | - Code completion
53 | - Go to definition
54 | - Find references
55 | - Document symbols
56 | - Hover information
57 | - Code formatting
58 | - Diagnostics (via Credo integration)
59 | 
60 | ### Important: Project Compilation
61 | 
62 | Expert requires your Elixir project to be **compiled** for optimal performance, especially for:
63 | - Cross-file reference resolution
64 | - Complete symbol information
65 | - Accurate go-to-definition
66 | 
67 | **For production use**: Ensure your project is compiled with `mix compile` before using the language server.
68 | 
69 | **For testing**: The test suite automatically compiles the test repositories before running tests to ensure optimal Expert performance.
70 | 
71 | ## Testing
72 | 
73 | Run the Elixir-specific tests with:
74 | 
75 | ```bash
76 | pytest test/solidlsp/elixir/ -m elixir
77 | ```
78 | 
79 | ## Implementation Details
80 | 
81 | - **Main class**: `ElixirTools` in `elixir_tools.py`
82 | - **Language identifier**: `"elixir"`
83 | - **Command**: `expert --stdio`
84 | - **Supported platforms**: Linux (x64, arm64), macOS (x64, arm64), Windows (x64, arm64)
85 | - **Binary distribution**: Downloaded from [GitHub releases](https://github.com/elixir-lang/expert/releases)
86 | 
87 | The implementation follows the same patterns as other language servers in this project, inheriting from `SolidLanguageServer` and providing Elixir-specific configuration and behavior.
88 | 
```

--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------

```markdown
  1 | <p align="center" style="text-align:center">
  2 |   <img src="resources/serena-logo.svg#gh-light-mode-only" style="width:500px">
  3 |   <img src="resources/serena-logo-dark-mode.svg#gh-dark-mode-only" style="width:500px">
  4 | </p>
  5 | 
  6 | * :rocket: Serena is a powerful **coding agent toolkit** capable of turning an LLM into a fully-featured agent that works **directly on your codebase**.
  7 |   Unlike most other tools, it is not tied to an LLM, framework or an interface, making it easy to use it in a variety of ways.
  8 | * :wrench: Serena provides essential **semantic code retrieval and editing tools** that are akin to an IDE's capabilities, extracting code entities at the symbol level and exploiting relational structure. When combined with an existing coding agent, these tools greatly enhance (token) efficiency.
  9 | * :free: Serena is **free & open-source**, enhancing the capabilities of LLMs you already have access to free of charge.
 10 | 
 11 | You can think of Serena as providing IDE-like tools to your LLM/coding agent. 
 12 | With it, the agent no longer needs to read entire files, perform grep-like searches or basic string replacements to find the right parts of the code and to edit code. 
 13 | Instead, it can use code-centric tools like `find_symbol`, `find_referencing_symbols` and `insert_after_symbol`.
 14 | 
 15 | <p align="center">
 16 |   <em>Serena is under active development! See the latest updates, upcoming features, and lessons learned to stay up to date.</em>
 17 | </p>
 18 | 
 19 | <p align="center">
 20 |   <a href="CHANGELOG.md"><img src="https://img.shields.io/badge/Updates-1e293b?style=flat&logo=rss&logoColor=white&labelColor=1e293b" alt="Changelog" /></a>
 21 |   <a href="roadmap.md"><img src="https://img.shields.io/badge/Roadmap-14532d?style=flat&logo=target&logoColor=white&labelColor=14532d" alt="Roadmap" /></a>
 22 |   <a href="lessons_learned.md"><img src="https://img.shields.io/badge/Lessons-Learned-7c4700?style=flat&logo=readthedocs&logoColor=white&labelColor=7c4700" alt="Lessons Learned" /></a>
 23 | </p>
 24 | 
 25 | > [!TIP]
 26 | > The [**Serena JetBrains plugin**](#the-serena-jetbrains-plugin) has been released!
 27 | 
 28 | ## LLM Integration
 29 | 
 30 | 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,
 31 | orchestrating tool use.
 32 | 
 33 | In general, Serena can be integrated with an LLM in several ways:
 34 | 
 35 | * by using the **model context protocol (MCP)**.
 36 |   Serena provides an MCP server which integrates with
 37 |     * Claude Code and Claude Desktop,
 38 |     * terminal-based clients like Codex, Gemini-CLI, Qwen3-Coder, rovodev, OpenHands CLI and others,
 39 |     * IDEs like VSCode, Cursor or IntelliJ,
 40 |     * Extensions like Cline or Roo Code
 41 |     * Local clients like [OpenWebUI](https://docs.openwebui.com/openapi-servers/mcp), [Jan](https://jan.ai/docs/mcp-examples/browser/browserbase#enable-mcp), [Agno](https://docs.agno.com/introduction/playground) and others
 42 | * by using [mcpo to connect it to ChatGPT](docs/03-special-guides/serena_on_chatgpt.md) or other clients that don't support MCP but do support tool calling via OpenAPI.
 43 | * by incorporating Serena's tools into an agent framework of your choice, as illustrated [here](docs/03-special-guides/custom_agent.md).
 44 |   Serena's tool implementation is decoupled from the framework-specific code and can thus easily be adapted to any agent framework.
 45 | 
 46 | ## Serena in Action
 47 | 
 48 | #### Demonstration 1: Efficient Operation in Claude Code
 49 | 
 50 | 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.
 51 | 
 52 | https://github.com/user-attachments/assets/ab78ebe0-f77d-43cc-879a-cc399efefd87
 53 | 
 54 | #### Demonstration 2: Serena in Claude Desktop
 55 | 
 56 | A demonstration of Serena implementing a small feature for itself (a better log GUI) with Claude Desktop.
 57 | Note how Serena's tools enable Claude to find and edit the right symbols.
 58 | 
 59 | https://github.com/user-attachments/assets/6eaa9aa1-610d-4723-a2d6-bf1e487ba753
 60 | 
 61 | ## Programming Language Support & Semantic Analysis Capabilities
 62 | 
 63 | Serena provides a set of versatile code querying and editing functionalities
 64 | based on symbolic understanding of the code.
 65 | Equipped with these capabilities, Serena discovers and edits code just like a seasoned developer
 66 | making use of an IDE's capabilities would.
 67 | Serena can efficiently find the right context and do the right thing even in very large and
 68 | complex projects!
 69 | 
 70 | There are two alternative technologies powering these capabilities:
 71 | 
 72 | * **Language servers** implementing the language server Protocol (LSP) — the free/open-source alternative.
 73 | * **The Serena JetBrains Plugin**, which leverages the powerful code analysis and editing
 74 |   capabilities of your JetBrains IDE.
 75 | 
 76 | You can choose either of these backends depending on your preferences and requirements.
 77 | 
 78 | ### Language Servers
 79 | 
 80 | Serena incorporates a powerful abstraction layer for the integration of language servers
 81 | that implement the language server protocol (LSP).
 82 | The underlying language servers are typically open-source projects (like Serena) or at least freely available for use.
 83 | 
 84 | With Serena's LSP library, we provide **support for over 30 programming languages**, including
 85 | AL, Bash, C#, C/C++, Clojure, Dart, Elixir, Elm, Erlang, Fortran, Go, Groovy (partial support), Haskell, Java, Javascript, Julia, Kotlin, Lua, Markdown, MATLAB, Nix, Perl, PHP, PowerShell, Python, R, Ruby, Rust, Scala, Swift, TOML, TypeScript, YAML, and Zig.
 86 | 
 87 | > [!IMPORTANT]
 88 | > Some language servers require additional dependencies to be installed; see the [Language Support](https://oraios.github.io/serena/01-about/020_programming-languages.html) page for details.
 89 | 
 90 | ### The Serena JetBrains Plugin
 91 | 
 92 | As an alternative to language servers, the [Serena JetBrains Plugin](https://plugins.jetbrains.com/plugin/28946-serena/)
 93 | leverages the powerful code analysis capabilities of your JetBrains IDE. 
 94 | The plugin naturally supports all programming languages and frameworks that are supported by JetBrains IDEs, 
 95 | including IntelliJ IDEA, PyCharm, Android Studio, WebStorm, PhpStorm, RubyMine, GoLand, CLion, and others.
 96 | Only Rider is not supported.
 97 | 
 98 | <a href="https://plugins.jetbrains.com/plugin/28946-serena/"><img src="docs/_static/images/jetbrains-marketplace-button.png"></a>
 99 | 
100 | The plugin offers the most robust and most powerful Serena experience.  
101 | See our [documentation page](https://oraios.github.io/serena/02-usage/025_jetbrains_plugin.html) for further details and instructions.
102 | 
103 | ## Quick Start
104 | 
105 | **Prerequisites**. Serena is managed by *uv*. If you don’t already have it, you need to [install uv](https://docs.astral.sh/uv/getting-started/installation/) before proceeding.
106 | 
107 | **Starting the MCP Server**. The easiest way to start the Serena MCP server is by running the latest version from GitHub using uvx.
108 | Issue this command to see available options:
109 | 
110 | ```bash
111 | uvx --from git+https://github.com/oraios/serena serena start-mcp-server --help
112 | ```
113 | 
114 | **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).
115 | 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). 
116 | 
117 | > [!TIP]
118 | > While getting started quickly is easy, Serena is a powerful toolkit with many configuration options.
119 | > 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.
120 | > 
121 | > Specifically, we recommend to read about ...
122 | >   * [Serena's project-based workflow](https://oraios.github.io/serena/02-usage/040_workflow.html) and
123 | >   * [configuring Serena](https://oraios.github.io/serena/02-usage/050_configuration.html).
124 | 
125 | ## User Guide
126 | 
127 | 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.
128 | 
129 | ## Community Feedback
130 | 
131 | Most users report that Serena has strong positive effects on the results of their coding agents, even when used within
132 | very capable agents like Claude Code. Serena is often described to be a [game changer](https://www.reddit.com/r/ClaudeAI/comments/1lfsdll/try_out_serena_mcp_thank_me_later/), providing an enormous [productivity boost](https://www.reddit.com/r/ClaudeCode/comments/1mguoia/absolutely_insane_improvement_of_claude_code).
133 | 
134 | Serena excels at navigating and manipulating complex codebases, providing tools that support precise code retrieval and editing in the presence of large, strongly structured codebases.
135 | However, when dealing with tasks that involve only very few/small files, you may not benefit from including Serena on top of your existing coding agent.
136 | In particular, when writing code from scratch, Serena will not provide much value initially, as the more complex structures that Serena handles more gracefully than simplistic, file-based approaches are yet to be created.
137 | 
138 | Several videos and blog posts have talked about Serena:
139 | 
140 | * YouTube:
141 |     * [AI Labs](https://www.youtube.com/watch?v=wYWyJNs1HVk&t=1s)
142 |     * [Yo Van Eyck](https://www.youtube.com/watch?v=UqfxuQKuMo8&t=45s)
143 |     * [JeredBlu](https://www.youtube.com/watch?v=fzPnM3ySmjE&t=32s)
144 | 
145 | * Blog posts:
146 |     * [Serena's Design Principles](https://medium.com/@souradip1000/deconstructing-serenas-mcp-powered-semantic-code-understanding-architecture-75802515d116)
147 |     * [Serena with Claude Code (in Japanese)](https://blog.lai.so/serena/)
148 |     * [Turning Claude Code into a Development Powerhouse](https://robertmarshall.dev/blog/turning-claude-code-into-a-development-powerhouse/)
149 | 
150 | ## Acknowledgements
151 | 
152 | ### Sponsors
153 | 
154 | We are very grateful to our [sponsors](https://github.com/sponsors/oraios) who help us drive Serena's development. The core team
155 | (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. 
156 | So far, there is no business model behind this project, and sponsors are our only source of income from it.
157 | 
158 | Sponsors help us dedicating more time to the project, managing contributions, and working on larger features (like better tooling based on more advanced
159 | LSP features, VSCode integration, debugging via the DAP, and several others).
160 | If you find this project useful to your work, or would like to accelerate the development of Serena, consider becoming a sponsor.
161 | 
162 | We are proud to announce that the Visual Studio Code team, together with Microsoft’s Open Source Programs Office and GitHub Open Source
163 | have decided to sponsor Serena with a one-time contribution!
164 | 
165 | <p align="center">
166 |   <img src="resources/vscode_sponsor_logo.png" alt="Visual Studio Code sponsor logo" width="220">
167 | </p>
168 | 
169 | ### Community Contributions
170 | 
171 | A significant part of Serena, especially support for various languages, was contributed by the open source community.
172 | We are very grateful for the many contributors who made this possible and who played an important role in making Serena
173 | what it is today.
174 | 
175 | ### Technologies
176 | We built Serena on top of multiple existing open-source technologies, the most important ones being:
177 | 
178 | 1. [multilspy](https://github.com/microsoft/multilspy).
179 |    A library which wraps language server implementations and adapts them for interaction via Python.
180 |    It provided the basis for our library Solid-LSP (`src/solidlsp`).
181 |    Solid-LSP provides pure synchronous LSP calls and extends the original library with the symbolic logic
182 |    that Serena required.
183 | 2. [Python MCP SDK](https://github.com/modelcontextprotocol/python-sdk)
184 | 3. All the language servers that we use through Solid-LSP.
185 | 
186 | Without these projects, Serena would not have been possible (or would have been significantly more difficult to build).
187 | 
188 | ## Customizing and Extending Serena
189 | 
190 | It is straightforward to extend Serena's AI functionality with your own ideas.
191 | Simply implement a new tool by subclassing
192 | `serena.agent.Tool` and implement the `apply` method with a signature
193 | that matches the tool's requirements.
194 | Once implemented, `SerenaAgent` will automatically have access to the new tool.
195 | 
196 | It is also relatively straightforward to add [support for a new programming language](/.serena/memories/adding_new_language_support_guide.md).
197 | 
198 | We look forward to seeing what the community will come up with!
199 | For details on contributing, see [contributing guidelines](/CONTRIBUTING.md).
200 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/markdown/test_repo/CONTRIBUTING.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Contributing Guidelines
 2 | 
 3 | Thank you for considering contributing to this project!
 4 | 
 5 | ## Table of Contents
 6 | 
 7 | - [Code of Conduct](#code-of-conduct)
 8 | - [Getting Started](#getting-started)
 9 | - [Development Setup](#development-setup)
10 | - [Submitting Changes](#submitting-changes)
11 | 
12 | ## Code of Conduct
13 | 
14 | Please be respectful and considerate in all interactions.
15 | 
16 | ## Getting Started
17 | 
18 | To contribute:
19 | 
20 | 1. Fork the repository
21 | 2. Create a feature branch
22 | 3. Make your changes
23 | 4. Submit a pull request
24 | 
25 | ## Development Setup
26 | 
27 | ### Prerequisites
28 | 
29 | - Git
30 | - Node.js (v16+)
31 | - npm or yarn
32 | 
33 | ### Installation Steps
34 | 
35 | ```bash
36 | git clone https://github.com/example/repo.git
37 | cd repo
38 | npm install
39 | ```
40 | 
41 | ## Submitting Changes
42 | 
43 | ### Pull Request Process
44 | 
45 | 1. Update documentation
46 | 2. Add tests for new features
47 | 3. Ensure all tests pass
48 | 4. Update the [README](README.md)
49 | 
50 | ### Commit Messages
51 | 
52 | Use clear and descriptive commit messages:
53 | 
54 | - feat: Add new feature
55 | - fix: Bug fix
56 | - docs: Documentation changes
57 | - test: Add or update tests
58 | 
59 | ## Testing
60 | 
61 | Run the test suite before submitting:
62 | 
63 | ```bash
64 | npm test
65 | ```
66 | 
67 | For more information, see:
68 | 
69 | - [User Guide](guide.md)
70 | - [API Reference](api.md)
71 | 
72 | ## Questions?
73 | 
74 | Contact the maintainers or open an issue.
75 | 
```

--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Contributing to Serena
 2 | 
 3 | Serena is under active development. We are just discovering what it can do and where the limitations lie.
 4 | 
 5 | Feel free to share your learnings by opening new issues, feature requests and extensions.
 6 | 
 7 | ## Developer Environment Setup
 8 | 
 9 | You can have a local setup via `uv` or a docker interpreter-based setup. 
10 | The repository is also configured to seamlessly work within a GitHub Codespace. See the instructions
11 | for the various setup scenarios below.
12 | 
13 | Independently of how the setup was done, the virtual environment can be 
14 | created and activated via `uv` (see below), and the various tasks like formatting, testing, and documentation building
15 | can be executed using `poe`. For example, `poe format` will format the code, including the 
16 | notebooks. Just run `poe` to see the available commands.
17 | 
18 | ### Python (uv) setup
19 | 
20 | You can install a virtual environment with the required as follows
21 | 
22 | 1. Create a new virtual environment: `uv venv`
23 | 2. Activate the environment:
24 |     * On Linux/Unix/macOS or Windows with Git Bash: `source .venv/bin/activate`
25 |     * On Windows outside of Git Bash: `.venv\Scripts\activate.bat` (in cmd/ps) or `source .venv/Scripts/activate` (in git-bash) 
26 | 3. Install the required packages with all extras: `uv pip install --all-extras -r pyproject.toml -e .`
27 | 
28 | ## Running Tools Locally
29 | 
30 | The Serena tools (and in fact all Serena code) can be executed without an LLM, and also without
31 | any MCP specifics (though you can use the mcp inspector, if you want).
32 | 
33 | An example script for running tools is provided in [scripts/demo_run_tools.py](scripts/demo_run_tools.py).
34 | 
35 | ## Adding a New Supported Language
36 | 
37 | See the corresponding [memory](.serena/memories/adding_new_language_support_guide.md).
```

--------------------------------------------------------------------------------
/CLAUDE.md:
--------------------------------------------------------------------------------

```markdown
  1 | # CLAUDE.md
  2 | 
  3 | This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
  4 | 
  5 | ## Development Commands
  6 | 
  7 | **Essential Commands (use these exact commands):**
  8 | - `uv run poe format` - Format code (BLACK + RUFF) - ONLY allowed formatting command
  9 | - `uv run poe type-check` - Run mypy type checking - ONLY allowed type checking command  
 10 | - `uv run poe test` - Run tests with default markers (excludes java/rust by default)
 11 | - `uv run poe test -m "python or go"` - Run specific language tests
 12 | - `uv run poe test -m vue` - Run Vue tests
 13 | - `uv run poe lint` - Check code style without fixing
 14 | 
 15 | **Test Markers:**
 16 | Available pytest markers for selective testing:
 17 | - `python`, `go`, `java`, `rust`, `typescript`, `vue`, `php`, `perl`, `powershell`, `csharp`, `elixir`, `terraform`, `clojure`, `swift`, `bash`, `ruby`, `ruby_solargraph`
 18 | - `snapshot` - for symbolic editing operation tests
 19 | 
 20 | **Project Management:**
 21 | - `uv run serena-mcp-server` - Start MCP server from project root
 22 | - `uv run index-project` - Index project for faster tool performance
 23 | 
 24 | **Always run format, type-check, and test before completing any task.**
 25 | 
 26 | ## Architecture Overview
 27 | 
 28 | Serena is a dual-layer coding agent toolkit:
 29 | 
 30 | ### Core Components
 31 | 
 32 | **1. SerenaAgent (`src/serena/agent.py`)**
 33 | - Central orchestrator managing projects, tools, and user interactions
 34 | - Coordinates language servers, memory persistence, and MCP server interface
 35 | - Manages tool registry and context/mode configurations
 36 | 
 37 | **2. SolidLanguageServer (`src/solidlsp/ls.py`)**  
 38 | - Unified wrapper around Language Server Protocol (LSP) implementations
 39 | - Provides language-agnostic interface for symbol operations
 40 | - Handles caching, error recovery, and multiple language server lifecycle
 41 | 
 42 | **3. Tool System (`src/serena/tools/`)**
 43 | - **file_tools.py** - File system operations, search, regex replacements
 44 | - **symbol_tools.py** - Language-aware symbol finding, navigation, editing
 45 | - **memory_tools.py** - Project knowledge persistence and retrieval
 46 | - **config_tools.py** - Project activation, mode switching
 47 | - **workflow_tools.py** - Onboarding and meta-operations
 48 | 
 49 | **4. Configuration System (`src/serena/config/`)**
 50 | - **Contexts** - Define tool sets for different environments (desktop-app, agent, ide-assistant)
 51 | - **Modes** - Operational patterns (planning, editing, interactive, one-shot)
 52 | - **Projects** - Per-project settings and language server configs
 53 | 
 54 | ### Language Support Architecture
 55 | 
 56 | Each supported language has:
 57 | 1. **Language Server Implementation** in `src/solidlsp/language_servers/`
 58 | 2. **Runtime Dependencies** - Automatic language server downloads when needed
 59 | 3. **Test Repository** in `test/resources/repos/<language>/`
 60 | 4. **Test Suite** in `test/solidlsp/<language>/`
 61 | 
 62 | ### Memory & Knowledge System
 63 | 
 64 | - **Markdown-based storage** in `.serena/memories/` directories
 65 | - **Project-specific knowledge** persistence across sessions
 66 | - **Contextual retrieval** based on relevance
 67 | - **Onboarding support** for new projects
 68 | 
 69 | ## Development Patterns
 70 | 
 71 | ### Adding New Languages
 72 | 1. Create language server class in `src/solidlsp/language_servers/`
 73 | 2. Add to Language enum in `src/solidlsp/ls_config.py` 
 74 | 3. Update factory method in `src/solidlsp/ls.py`
 75 | 4. Create test repository in `test/resources/repos/<language>/`
 76 | 5. Write test suite in `test/solidlsp/<language>/`
 77 | 6. Add pytest marker to `pyproject.toml`
 78 | 
 79 | ### Adding New Tools
 80 | 1. Inherit from `Tool` base class in `src/serena/tools/tools_base.py`
 81 | 2. Implement required methods and parameter validation
 82 | 3. Register in appropriate tool registry
 83 | 4. Add to context/mode configurations
 84 | 
 85 | ### Testing Strategy
 86 | - Language-specific tests use pytest markers
 87 | - Symbolic editing operations have snapshot tests
 88 | - Integration tests in `test_serena_agent.py`
 89 | - Test repositories provide realistic symbol structures
 90 | 
 91 | ## Configuration Hierarchy
 92 | 
 93 | Configuration is loaded from (in order of precedence):
 94 | 1. Command-line arguments to `serena-mcp-server`
 95 | 2. Project-specific `.serena/project.yml`
 96 | 3. User config `~/.serena/serena_config.yml`
 97 | 4. Active modes and contexts
 98 | 
 99 | ## Key Implementation Notes
100 | 
101 | - **Symbol-based editing** - Uses LSP for precise code manipulation
102 | - **Caching strategy** - Reduces language server overhead
103 | - **Error recovery** - Automatic language server restart on crashes
104 | - **Multi-language support** - 19 languages with LSP integration (including Vue)
105 | - **MCP protocol** - Exposes tools to AI agents via Model Context Protocol
106 | - **Async operation** - Non-blocking language server interactions
107 | 
108 | ## Working with the Codebase
109 | 
110 | - Project uses Python 3.11 with `uv` for dependency management
111 | - Strict typing with mypy, formatted with black + ruff
112 | - Language servers run as separate processes with LSP communication
113 | - Memory system enables persistent project knowledge
114 | - Context/mode system allows workflow customization
```

--------------------------------------------------------------------------------
/src/interprompt/util/__init__.py:
--------------------------------------------------------------------------------

```python
1 | 
```

--------------------------------------------------------------------------------
/src/serena/config/__init__.py:
--------------------------------------------------------------------------------

```python
1 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/python/test_repo/test_repo/__init__.py:
--------------------------------------------------------------------------------

```python
1 | 
```

--------------------------------------------------------------------------------
/test/solidlsp/bash/__init__.py:
--------------------------------------------------------------------------------

```python
1 | 
```

--------------------------------------------------------------------------------
/test/solidlsp/dart/__init__.py:
--------------------------------------------------------------------------------

```python
1 | 
```

--------------------------------------------------------------------------------
/test/solidlsp/yaml_ls/__init__.py:
--------------------------------------------------------------------------------

```python
1 | 
```

--------------------------------------------------------------------------------
/src/solidlsp/language_servers/elixir_tools/__init__.py:
--------------------------------------------------------------------------------

```python
1 | 
2 | 
```

--------------------------------------------------------------------------------
/test/__init__.py:
--------------------------------------------------------------------------------

```python
1 | 
2 | 
```

--------------------------------------------------------------------------------
/test/serena/__init__.py:
--------------------------------------------------------------------------------

```python
1 | 
2 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/scala/project/build.properties:
--------------------------------------------------------------------------------

```
1 | sbt.version=1.10.1
2 | 
```

--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------

```yaml
1 | blank_issues_enabled: false
```

--------------------------------------------------------------------------------
/test/solidlsp/r/__init__.py:
--------------------------------------------------------------------------------

```python
1 | # Empty init file for R tests
2 | 
```

--------------------------------------------------------------------------------
/test/solidlsp/matlab/__init__.py:
--------------------------------------------------------------------------------

```python
1 | # MATLAB language server tests
2 | 
```

--------------------------------------------------------------------------------
/test/solidlsp/fortran/__init__.py:
--------------------------------------------------------------------------------

```python
1 | # Fortran language server tests
2 | 
```

--------------------------------------------------------------------------------
/test/solidlsp/haskell/__init__.py:
--------------------------------------------------------------------------------

```python
1 | # Haskell language server tests
2 | 
```

--------------------------------------------------------------------------------
/test/solidlsp/toml/__init__.py:
--------------------------------------------------------------------------------

```python
1 | """TOML language server tests."""
2 | 
```

--------------------------------------------------------------------------------
/test/serena/config/__init__.py:
--------------------------------------------------------------------------------

```python
1 | # Empty init file for test package
2 | 
```

--------------------------------------------------------------------------------
/test/solidlsp/powershell/__init__.py:
--------------------------------------------------------------------------------

```python
1 | # PowerShell language server tests
2 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/php/test_repo/simple_var.php:
--------------------------------------------------------------------------------

```php
1 | <?php
2 | $localVar = "test";
3 | echo $localVar;
4 | ?> 
```

--------------------------------------------------------------------------------
/src/solidlsp/__init__.py:
--------------------------------------------------------------------------------

```python
1 | # ruff: noqa
2 | from .ls import SolidLanguageServer
3 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/kotlin/test_repo/src/main/kotlin/test_repo/Model.kt:
--------------------------------------------------------------------------------

```kotlin
1 | package test_repo
2 | 
3 | data class Model(val name: String)
```

--------------------------------------------------------------------------------
/test/solidlsp/markdown/__init__.py:
--------------------------------------------------------------------------------

```python
1 | """Tests for markdown language server functionality."""
2 | 
```

--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------

```yaml
1 | # These are supported funding model platforms
2 | 
3 | github: oraios
4 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/groovy/test_repo/build.gradle:
--------------------------------------------------------------------------------

```
1 | plugins {
2 |     id 'groovy'
3 | }
4 | 
5 | repositories {
6 |     mavenCentral()
7 | }
8 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/python/test_repo/custom_test/__init__.py:
--------------------------------------------------------------------------------

```python
1 | """
2 | Custom test package for testing code parsing capabilities.
3 | """
4 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/python/test_repo/examples/__init__.py:
--------------------------------------------------------------------------------

```python
1 | """
2 | Examples package for demonstrating test_repo module usage.
3 | """
4 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/haskell/test_repo/stack.yaml:
--------------------------------------------------------------------------------

```yaml
1 | resolver: ghc-9.8.4
2 | system-ghc: true
3 | install-ghc: false
4 | packages:
5 |   - .
6 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/nix/test_repo/scripts/hello.sh:
--------------------------------------------------------------------------------

```bash
1 | #!/usr/bin/env bash
2 | # Simple hello script for testing
3 | echo "Hello from Nix!"
```

--------------------------------------------------------------------------------
/test/resources/repos/python/test_repo/scripts/__init__.py:
--------------------------------------------------------------------------------

```python
1 | """
2 | Scripts package containing entry point scripts for the application.
3 | """
4 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/rust/test_repo/Cargo.toml:
--------------------------------------------------------------------------------

```toml
1 | [package]
2 | name = "rsandbox"
3 | version = "0.1.0"
4 | edition = "2021"
5 | 
6 | [dependencies]
7 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/powershell/test_repo/PowerShellEditorServices.json:
--------------------------------------------------------------------------------

```json
1 | {"status":"started","languageServiceTransport":"Stdio","powerShellVersion":"7.5.3"}
```

--------------------------------------------------------------------------------
/test/resources/repos/rust/test_repo_2024/Cargo.toml:
--------------------------------------------------------------------------------

```toml
1 | [package]
2 | name = "rsandbox_2024"
3 | version = "0.1.0"
4 | edition = "2024"
5 | 
6 | [dependencies]
```

--------------------------------------------------------------------------------
/test/resources/repos/php/test_repo/helper.php:
--------------------------------------------------------------------------------

```php
1 | <?php
2 | 
3 | function helperFunction(): void {
4 |     echo "Helper function was called.";
5 | }
6 | 
7 | ?> 
```

--------------------------------------------------------------------------------
/test/resources/repos/ruby/test_repo/lib.rb:
--------------------------------------------------------------------------------

```ruby
 1 | class Calculator
 2 |   def add(a, b)
 3 |     a + b
 4 |   end
 5 | 
 6 |   def subtract(a, b)
 7 |     a - b
 8 |   end
 9 | end
10 | 
```

--------------------------------------------------------------------------------
/docker_build_and_run.sh:
--------------------------------------------------------------------------------

```bash
1 | #!/usr/bin/bash
2 | 
3 | docker build -t serena .
4 | 
5 | docker run -it --rm -v "$(pwd)":/workspace serena
6 | 
```

--------------------------------------------------------------------------------
/scripts/mcp_server.py:
--------------------------------------------------------------------------------

```python
1 | from serena.cli import start_mcp_server
2 | 
3 | if __name__ == "__main__":
4 |     start_mcp_server()
5 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/kotlin/test_repo/src/main/kotlin/test_repo/Utils.kt:
--------------------------------------------------------------------------------

```kotlin
1 | package test_repo
2 | 
3 | object Utils {
4 |     fun printHello() {
5 |         println("Hello from Utils!")
6 |     }
7 | }
```

--------------------------------------------------------------------------------
/scripts/print_tool_overview.py:
--------------------------------------------------------------------------------

```python
1 | from serena.agent import ToolRegistry
2 | 
3 | if __name__ == "__main__":
4 |     ToolRegistry().print_tool_overview()
5 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/groovy/test_repo/src/main/groovy/com/example/Model.groovy:
--------------------------------------------------------------------------------

```
 1 | package com.example
 2 | 
 3 | class Model {
 4 |     String name
 5 | 
 6 |     Model(String name) {
 7 |         this.name = name
 8 |     }
 9 | }
10 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/typescript/test_repo/use_helper.ts:
--------------------------------------------------------------------------------

```typescript
1 | import {helperFunction} from "./index";
2 | 
3 | 
4 | export function useHelper() {
5 |     helperFunction();
6 | }
7 | 
8 | useHelper();
9 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/groovy/test_repo/src/main/groovy/com/example/Utils.groovy:
--------------------------------------------------------------------------------

```
1 | package com.example
2 | 
3 | class Utils {
4 |     static void printHello() {
5 |         println("Hello from Utils!")
6 |     }
7 | }
8 | 
```

--------------------------------------------------------------------------------
/src/interprompt/__init__.py:
--------------------------------------------------------------------------------

```python
1 | from .prompt_factory import autogenerate_prompt_factory_module
2 | 
3 | __all__ = ["autogenerate_prompt_factory_module"]
4 | 
```

--------------------------------------------------------------------------------
/docs/03-special-guides/000_intro.md:
--------------------------------------------------------------------------------

```markdown
1 | # Special Guides
2 | 
3 | This section contains special guides for certain topics that require more in-depth explanations.
```

--------------------------------------------------------------------------------
/test/resources/repos/rust/test_repo/src/lib.rs:
--------------------------------------------------------------------------------

```rust
 1 | // This function returns the sum of 2 + 2
 2 | pub fn add() -> i32 {
 3 |     let res = 2 + 2;
 4 |     res
 5 | }
 6 | pub fn multiply() -> i32 {
 7 |     2 * 3
 8 | }
 9 | 
10 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/java/test_repo/src/main/java/test_repo/Utils.java:
--------------------------------------------------------------------------------

```java
1 | package test_repo;
2 | 
3 | public class Utils {
4 |     public static void printHello() {
5 |         System.out.println("Hello from Utils!");
6 |     }
7 | }
8 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/kotlin/test_repo/build.gradle.kts:
--------------------------------------------------------------------------------

```kotlin
 1 | plugins {
 2 |     kotlin("jvm") version "1.9.21"
 3 |     application
 4 | }
 5 | 
 6 | group = "test.serena"
 7 | version = "1.0-SNAPSHOT"
 8 | 
 9 | repositories {
10 |     mavenCentral()
11 | }
```

--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------

```markdown
1 | <meta http-equiv="refresh" content="0; url=01-about/000_intro.html">
2 | If you are not redirected automatically, [click here](01-about/000_intro.html).
3 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/typescript/test_repo/.serena/project.yml:
--------------------------------------------------------------------------------

```yaml
1 | excluded_tools: []
2 | ignore_all_files_in_gitignore: true
3 | ignored_paths: []
4 | initial_prompt: ''
5 | language: typescript
6 | project_name: test_repo
7 | read_only: false
8 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/groovy/test_repo/src/main/groovy/com/example/ModelUser.groovy:
--------------------------------------------------------------------------------

```
1 | package com.example
2 | 
3 | class ModelUser {
4 |     static void main(String[] args) {
5 |         Model model = new Model("Cascade")
6 |         println(model.name)
7 |     }
8 | }
9 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/kotlin/test_repo/src/main/kotlin/test_repo/ModelUser.kt:
--------------------------------------------------------------------------------

```kotlin
1 | package test_repo
2 | 
3 | object ModelUser {
4 |     @JvmStatic
5 |     fun main(args: Array<String>) {
6 |         val model = Model("Cascade")
7 |         println(model.name)
8 |     }
9 | }
```

--------------------------------------------------------------------------------
/test/resources/repos/rust/test_repo/src/main.rs:
--------------------------------------------------------------------------------

```rust
1 | use rsandbox::add;
2 | 
3 | fn main() {
4 |     println!("Hello, World!");
5 |     println!("Good morning!");
6 |     println!("add result: {}", add());
7 |     println!("inserted line");
8 | }
9 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/groovy/test_repo/src/main/groovy/com/example/Main.groovy:
--------------------------------------------------------------------------------

```
 1 | package com.example
 2 | 
 3 | class Main {
 4 |     static void main(String[] args) {
 5 |         Utils.printHello()
 6 |         Model model = new Model("Cascade")
 7 |         println(model.name)
 8 |     }
 9 | }
10 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/vue/test_repo/src/main.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { createApp } from 'vue'
 2 | import { createPinia } from 'pinia'
 3 | import App from './App.vue'
 4 | 
 5 | const app = createApp(App)
 6 | const pinia = createPinia()
 7 | 
 8 | app.use(pinia)
 9 | app.mount('#app')
10 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/java/test_repo/src/main/java/test_repo/ModelUser.java:
--------------------------------------------------------------------------------

```java
1 | package test_repo;
2 | 
3 | public class ModelUser {
4 |     public static void main(String[] args) {
5 |         Model model = new Model("Cascade");
6 |         System.out.println(model.getName());
7 |     }
8 | }
9 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/dart/test_repo/pubspec.yaml:
--------------------------------------------------------------------------------

```yaml
 1 | name: test_repo
 2 | description: A test repository for Serena Dart language server testing
 3 | version: 1.0.0
 4 | 
 5 | environment:
 6 |   sdk: '>=3.0.0 <4.0.0'
 7 | 
 8 | dependencies:
 9 |   
10 | dev_dependencies:
11 |   lints: ^3.0.0
```

--------------------------------------------------------------------------------
/src/serena/resources/config/modes/no-onboarding.yml:
--------------------------------------------------------------------------------

```yaml
1 | description: The onboarding process is not used (memories may have been created externally)
2 | prompt: |
3 |   The onboarding process is not applied.
4 | excluded_tools:
5 |   - onboarding
6 |   - check_onboarding_performed
7 | 
```

--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |     "cSpell.words": [
 3 |         "agno",
 4 |         "asyncio",
 5 |         "genai",
 6 |         "getpid",
 7 |         "Gopls",
 8 |         "langsrv",
 9 |         "multilspy",
10 |         "pixi",
11 |         "sensai",
12 |         "vibing"
13 |     ],
14 | }
15 | 
```

--------------------------------------------------------------------------------
/src/serena/resources/config/contexts/agent.yml:
--------------------------------------------------------------------------------

```yaml
1 | description: Agent context where the system prompt (initial instructions) are provided at startup
2 | prompt: |
3 |   You are running in an agent context.
4 | excluded_tools:
5 |   - initial_instructions
6 | 
7 | tool_description_overrides: {}
```

--------------------------------------------------------------------------------
/sync.py:
--------------------------------------------------------------------------------

```python
1 | import os
2 | from repo_dir_sync import LibRepo, OtherRepo
3 | 
4 | r = LibRepo(name="serena", libDirectory="src")
5 | r.add(OtherRepo(name="mux", branch="mux", pathToLib=os.path.join("..", "serena-multiplexer", "src-serena")))
6 | r.runMain()
7 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/go/test_repo/main.go:
--------------------------------------------------------------------------------

```go
 1 | package main
 2 | 
 3 | import "fmt"
 4 | 
 5 | func main() {
 6 |     fmt.Println("Hello, Go!")
 7 |     Helper()
 8 | }
 9 | 
10 | func Helper() {
11 |     fmt.Println("Helper function called")
12 | }
13 | 
14 | type DemoStruct struct {
15 |     Field int
16 | }
17 | 
18 | func UsingHelper() {
19 |     Helper()
20 | }
21 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/typescript/test_repo/tsconfig.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "compilerOptions": {
 3 |     "target": "ES2017",
 4 |     "module": "commonjs",
 5 |     "strict": true,
 6 |     "esModuleInterop": true,
 7 |     "forceConsistentCasingInFileNames": true,
 8 |     "skipLibCheck": true
 9 |   },
10 |   "include": ["**/*.ts"]
11 | }
12 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/vue/test_repo/tsconfig.node.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "compilerOptions": {
 3 |     "composite": true,
 4 |     "skipLibCheck": true,
 5 |     "module": "ESNext",
 6 |     "moduleResolution": "bundler",
 7 |     "allowSyntheticDefaultImports": true,
 8 |     "strict": true
 9 |   },
10 |   "include": ["vite.config.ts"]
11 | }
12 | 
```

--------------------------------------------------------------------------------
/src/serena/tools/__init__.py:
--------------------------------------------------------------------------------

```python
 1 | # ruff: noqa
 2 | from .tools_base import *
 3 | from .file_tools import *
 4 | from .symbol_tools import *
 5 | from .memory_tools import *
 6 | from .cmd_tools import *
 7 | from .config_tools import *
 8 | from .workflow_tools import *
 9 | from .jetbrains_tools import *
10 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/php/test_repo/index.php:
--------------------------------------------------------------------------------

```php
 1 | <?php
 2 | 
 3 | require_once 'helper.php';
 4 | 
 5 | function greet(string $name): string {
 6 |     return "Hello, " . $name . "!";
 7 | }
 8 | 
 9 | $userName = "PHP User";
10 | $greeting = greet($userName);
11 | 
12 | echo $greeting;
13 | 
14 | helperFunction();
15 | 
16 | function useHelperFunction() {
17 |     helperFunction();
18 | }
19 | 
20 | ?> 
```

--------------------------------------------------------------------------------
/test/resources/repos/vue/test_repo/vite.config.ts:
--------------------------------------------------------------------------------

```typescript
 1 | import { defineConfig } from 'vite'
 2 | import vue from '@vitejs/plugin-vue'
 3 | import { fileURLToPath, URL } from 'node:url'
 4 | 
 5 | export default defineConfig({
 6 |   plugins: [vue()],
 7 |   resolve: {
 8 |     alias: {
 9 |       '@': fileURLToPath(new URL('./src', import.meta.url))
10 |     }
11 |   }
12 | })
13 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/typescript/test_repo/index.ts:
--------------------------------------------------------------------------------

```typescript
 1 | export class DemoClass {
 2 |     value: number;
 3 |     constructor(value: number) {
 4 |         this.value = value;
 5 |     }
 6 |     printValue() {
 7 |         console.log(this.value);
 8 |     }
 9 | }
10 | 
11 | export function helperFunction() {
12 |     const demo = new DemoClass(42);
13 |     demo.printValue();
14 | }
15 | 
16 | helperFunction();
17 | 
```

--------------------------------------------------------------------------------
/src/interprompt/util/class_decorators.py:
--------------------------------------------------------------------------------

```python
 1 | from typing import Any
 2 | 
 3 | 
 4 | def singleton(cls: type[Any]) -> Any:
 5 |     instance = None
 6 | 
 7 |     def get_instance(*args: Any, **kwargs: Any) -> Any:
 8 |         nonlocal instance
 9 |         if instance is None:
10 |             instance = cls(*args, **kwargs)
11 |         return instance
12 | 
13 |     return get_instance
14 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/rust/test_repo_2024/src/main.rs:
--------------------------------------------------------------------------------

```rust
 1 | fn main() {
 2 |     println!("Hello, Rust 2024 edition!");
 3 |     let result = add(2, 3);
 4 |     println!("2 + 3 = {}", result);
 5 | }
 6 | 
 7 | pub fn add(a: i32, b: i32) -> i32 {
 8 |     a + b
 9 | }
10 | 
11 | #[cfg(test)]
12 | mod tests {
13 |     use super::*;
14 | 
15 |     #[test]
16 |     fn test_add() {
17 |         assert_eq!(add(2, 3), 5);
18 |     }
19 | }
```

--------------------------------------------------------------------------------
/test/resources/repos/kotlin/test_repo/src/main/kotlin/test_repo/Main.kt:
--------------------------------------------------------------------------------

```kotlin
 1 | package test_repo
 2 | 
 3 | object Main {
 4 |     @JvmStatic
 5 |     fun main(args: Array<String>) {
 6 |         Utils.printHello()
 7 |         val model = Model("Cascade")
 8 |         println(model.name)
 9 |         acceptModel(model)
10 |     }
11 | 
12 |     fun acceptModel(m: Model?) {
13 |         // Do nothing, just for LSP reference
14 |     }
15 | }
```

--------------------------------------------------------------------------------
/test/resources/repos/ruby/test_repo/main.rb:
--------------------------------------------------------------------------------

```ruby
 1 | require './lib.rb'
 2 | 
 3 | class DemoClass
 4 |   attr_accessor :value
 5 | 
 6 |   def initialize(value)
 7 |     @value = value
 8 |   end
 9 | 
10 |   def print_value
11 |     puts @value
12 |   end
13 | end
14 | 
15 | def helper_function(number = 42)
16 |   demo = DemoClass.new(number)
17 |   Calculator.new.add(demo.value, 10)
18 |   demo.print_value
19 | end
20 | 
21 | helper_function
22 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/python/test_repo/test_repo/nested.py:
--------------------------------------------------------------------------------

```python
 1 | class OuterClass:
 2 |     class NestedClass:
 3 |         def find_me(self):
 4 |             pass
 5 | 
 6 |     def nested_test(self):
 7 |         class WithinMethod:
 8 |             pass
 9 | 
10 |         def func_within_func():
11 |             pass
12 | 
13 |         a = self.NestedClass()  # noqa: F841
14 | 
15 | 
16 | b = OuterClass().NestedClass().find_me()
17 | 
```

--------------------------------------------------------------------------------
/docs/02-usage/000_intro.md:
--------------------------------------------------------------------------------

```markdown
1 | # Usage
2 | 
3 | Serena can be used in various ways and supports coding workflows through a project-based approach.
4 | Its configuration is flexible and allows tailoring it to your specific needs.
5 | 
6 | In this section, you will find general usage instructions as well as concrete instructions for selected integrations.
7 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/swift/test_repo/Package.swift:
--------------------------------------------------------------------------------

```swift
 1 | // swift-tools-version: 5.9
 2 | import PackageDescription
 3 | 
 4 | let package = Package(
 5 |     name: "test_repo",
 6 |     products: [
 7 |         .library(
 8 |             name: "test_repo",
 9 |             targets: ["test_repo"]),
10 |     ],
11 |     targets: [
12 |         .target(
13 |             name: "test_repo",
14 |             dependencies: []),
15 |     ]
16 | )
```

--------------------------------------------------------------------------------
/docs/create_toc.py:
--------------------------------------------------------------------------------

```python
 1 | import os
 2 | from pathlib import Path
 3 | 
 4 | # This script provides a platform-independent way of making the jupyter-book call (used in pyproject.toml)
 5 | folder = Path(__file__).parent
 6 | toc_file = folder / "_toc.yml"
 7 | cmd = f"jupyter-book toc from-project docs -e .rst -e .md -e .ipynb >{toc_file}"
 8 | print(cmd)
 9 | os.system(cmd)
10 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/rust/test_repo_2024/src/lib.rs:
--------------------------------------------------------------------------------

```rust
 1 | pub fn multiply(a: i32, b: i32) -> i32 {
 2 |     a * b
 3 | }
 4 | 
 5 | pub struct Calculator {
 6 |     pub result: i32,
 7 | }
 8 | 
 9 | impl Calculator {
10 |     pub fn new() -> Self {
11 |         Calculator { result: 0 }
12 |     }
13 | 
14 |     pub fn add(&mut self, value: i32) {
15 |         self.result += value;
16 |     }
17 | 
18 |     pub fn get_result(&self) -> i32 {
19 |         self.result
20 |     }
21 | }
```

--------------------------------------------------------------------------------
/test/resources/repos/vue/test_repo/package.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "name": "vue-calculator-test-fixture",
 3 |   "version": "1.0.0",
 4 |   "type": "module",
 5 |   "description": "Vue 3 + Pinia + TypeScript test fixtures for Serena LSP testing",
 6 |   "dependencies": {
 7 |     "vue": "^3.4.0",
 8 |     "pinia": "^2.1.0"
 9 |   },
10 |   "devDependencies": {
11 |     "@vue/language-server": "^2.0.0",
12 |     "typescript": "~5.5.4"
13 |   }
14 | }
15 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/java/test_repo/src/main/java/test_repo/Main.java:
--------------------------------------------------------------------------------

```java
 1 | package test_repo;
 2 | 
 3 | public class Main {
 4 |     public static void main(String[] args) {
 5 |         Utils.printHello();
 6 |         Model model = new Model("Cascade");
 7 |         System.out.println(model.getName());
 8 |         acceptModel(model);
 9 |     }
10 |     public static void acceptModel(Model m) {
11 |         // Do nothing, just for LSP reference
12 |     }
13 | }
14 | 
```

--------------------------------------------------------------------------------
/src/serena/resources/config/modes/no-memories.yml:
--------------------------------------------------------------------------------

```yaml
 1 | description: Excludes Serena's memory tools (and onboarding tools, which rely on memory)
 2 | prompt: |
 3 |   Serena's memory tools are not available and the onboarding workflow is not being applied.
 4 | excluded_tools:
 5 |   - write_memory
 6 |   - read_memory
 7 |   - delete_memory
 8 |   - edit_memory
 9 |   - list_memories
10 |   - onboarding
11 |   - check_onboarding_performed
12 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/python/test_repo/test_repo/complex_types.py:
--------------------------------------------------------------------------------

```python
 1 | from typing import TypedDict
 2 | 
 3 | a: list[int] = [1]
 4 | 
 5 | 
 6 | class CustomListInt(list[int]):
 7 |     def some_method(self):
 8 |         pass
 9 | 
10 | 
11 | class CustomTypedDict(TypedDict):
12 |     a: int
13 |     b: str
14 | 
15 | 
16 | class Outer2:
17 |     class InnerTypedDict(TypedDict):
18 |         a: int
19 |         b: str
20 | 
21 | 
22 | class ComplexExtension(Outer2.InnerTypedDict, total=False):
23 |     c: bool
24 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/yaml/test_repo/config.yaml:
--------------------------------------------------------------------------------

```yaml
 1 | # Application configuration
 2 | app:
 3 |   name: test-application
 4 |   version: 1.0.0
 5 |   port: 8080
 6 |   debug: true
 7 | 
 8 | database:
 9 |   host: localhost
10 |   port: 5432
11 |   name: testdb
12 |   username: admin
13 |   password: secret123
14 | 
15 | logging:
16 |   level: info
17 |   format: json
18 |   outputs:
19 |     - console
20 |     - file
21 | 
22 | features:
23 |   authentication: true
24 |   caching: false
25 |   monitoring: true
26 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/vue/test_repo/index.html:
--------------------------------------------------------------------------------

```html
 1 | <!DOCTYPE html>
 2 | <html lang="en">
 3 |   <head>
 4 |     <meta charset="UTF-8">
 5 |     <link rel="icon" type="image/svg+xml" href="/vite.svg">
 6 |     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 7 |     <title>Vue Calculator</title>
 8 |   </head>
 9 |   <body>
10 |     <div id="app"></div>
11 |     <script type="module" src="/src/main.ts"></script>
12 |   </body>
13 | </html>
14 | 
```

--------------------------------------------------------------------------------
/src/serena/resources/config/contexts/oaicompat-agent.yml:
--------------------------------------------------------------------------------

```yaml
1 | description: All tools except InitialInstructionsTool for agent context, uses OpenAI compatible tool definitions
2 | prompt: |
3 |   You are running in agent context where the system prompt is provided externally. You should use symbolic
4 |   tools when possible for code understanding and modification.
5 | excluded_tools:
6 |   - initial_instructions
7 | 
8 | tool_description_overrides: {}
```

--------------------------------------------------------------------------------
/test/resources/repos/zig/test_repo/zls.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |     "enable_build_on_save": true,
 3 |     "build_on_save_args": ["build"],
 4 |     "enable_autofix": false,
 5 |     "semantic_tokens": "full",
 6 |     "enable_inlay_hints": true,
 7 |     "inlay_hints_show_builtin": true,
 8 |     "inlay_hints_exclude_single_argument": true,
 9 |     "inlay_hints_show_parameter_name": true,
10 |     "skip_std_references": false,
11 |     "max_detail_length": 1048576
12 | }
13 | 
```

--------------------------------------------------------------------------------
/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "name": "serena Project",
 3 |   "dockerFile": "../Dockerfile",
 4 |   "workspaceFolder": "/workspaces/serena",
 5 |   "settings": {
 6 |     "terminal.integrated.shell.linux": "/bin/bash",
 7 |     "python.pythonPath": "/usr/local/bin/python",
 8 |   },
 9 |   "extensions": [
10 |     "ms-python.python",
11 |     "ms-toolsai.jupyter",
12 |     "ms-python.vscode-pylance"
13 |   ],
14 |   "forwardPorts": [],
15 |   "remoteUser": "root",
16 | }
17 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/java/test_repo/src/main/java/test_repo/Model.java:
--------------------------------------------------------------------------------

```java
 1 | package test_repo;
 2 | 
 3 | public class Model {
 4 |     private String name;
 5 | 
 6 |     public Model(String name) {
 7 |         this.name = name;
 8 |     }
 9 | 
10 |     public String getName() {
11 |         return name;
12 |     }
13 | 
14 |     public String getName(int maxChars) {
15 |         if (name.length() <= maxChars) {
16 |             return name;
17 |         } else {
18 |             return name.substring(0, maxChars) + "...";
19 |         }
20 |     }
21 | }
22 | 
```

--------------------------------------------------------------------------------
/test/solidlsp/pascal/__init__.py:
--------------------------------------------------------------------------------

```python
 1 | def _check_pascal_available() -> bool:
 2 |     """Check if Pascal language server (pasls) is available.
 3 | 
 4 |     Note: pasls will be auto-downloaded if not present, so Pascal
 5 |     support is always available.
 6 |     """
 7 |     return True
 8 | 
 9 | 
10 | PASCAL_AVAILABLE = _check_pascal_available()
11 | 
12 | 
13 | def is_pascal_available() -> bool:
14 |     """Return True if Pascal language server can be used."""
15 |     return PASCAL_AVAILABLE
16 | 
```

--------------------------------------------------------------------------------
/test/solidlsp/vue/__init__.py:
--------------------------------------------------------------------------------

```python
 1 | """Vue language server tests."""
 2 | 
 3 | import shutil
 4 | 
 5 | 
 6 | def _test_npm_available() -> str:
 7 |     """Test if npm is available and return error reason if not."""
 8 |     # Check if npm is installed
 9 |     if not shutil.which("npm"):
10 |         return "npm is not installed or not in PATH"
11 |     return ""  # No error, npm is available
12 | 
13 | 
14 | NPM_UNAVAILABLE_REASON = _test_npm_available()
15 | NPM_UNAVAILABLE = bool(NPM_UNAVAILABLE_REASON)
16 | 
```

--------------------------------------------------------------------------------
/src/serena/resources/config/modes/mode.template.yml:
--------------------------------------------------------------------------------

```yaml
1 | # See Serena's documentation for more details on concept of modes.
2 | description: Description of the mode (meta-information only)
3 | prompt: |
4 |   Provide a prompt that will form part of the instructions sent to the model when this mode is activated.
5 | # tools that are to be excluded by this mode
6 | excluded_tools: []
7 | # several tools are excluded by default and have to be explicitly included by the user
8 | included_optional_tools: []
```

--------------------------------------------------------------------------------
/test/resources/repos/haskell/test_repo/package.yaml:
--------------------------------------------------------------------------------

```yaml
 1 | name: haskell-test-repo
 2 | version: 0.1.0.0
 3 | github: "test/haskell-test-repo"
 4 | license: BSD3
 5 | author: "Test Author"
 6 | maintainer: "[email protected]"
 7 | 
 8 | dependencies:
 9 |   - base >= 4.7 && < 5
10 | 
11 | library:
12 |   source-dirs: src
13 |   exposed-modules:
14 |     - Calculator
15 |     - Helper
16 | 
17 | executables:
18 |   haskell-test-repo-exe:
19 |     main: Main.hs
20 |     source-dirs: app
21 |     dependencies:
22 |       - haskell-test-repo
23 | 
24 | default-extensions:
25 |   - OverloadedStrings
26 | 
```

--------------------------------------------------------------------------------
/src/serena/util/class_decorators.py:
--------------------------------------------------------------------------------

```python
 1 | from typing import Any
 2 | 
 3 | 
 4 | # duplicate of interprompt.class_decorators
 5 | # We don't want to depend on interprompt for this in serena, so we duplicate it here
 6 | def singleton(cls: type[Any]) -> Any:
 7 |     instance = None
 8 | 
 9 |     def get_instance(*args: Any, **kwargs: Any) -> Any:
10 |         nonlocal instance
11 |         if instance is None:
12 |             instance = cls(*args, **kwargs)
13 |         return instance
14 | 
15 |     return get_instance
16 | 
```

--------------------------------------------------------------------------------
/src/serena/util/cli_util.py:
--------------------------------------------------------------------------------

```python
 1 | def ask_yes_no(question: str, default: bool | None = None) -> bool:
 2 |     default_prompt = "Y/n" if default else "y/N"
 3 | 
 4 |     while True:
 5 |         answer = input(f"{question} [{default_prompt}] ").strip().lower()
 6 |         if answer == "" and default is not None:
 7 |             return default
 8 |         if answer in ("y", "yes"):
 9 |             return True
10 |         if answer in ("n", "no"):
11 |             return False
12 |         print("Please answer yes/y or no/n.")
13 | 
```

--------------------------------------------------------------------------------
/test/serena/test_edit_marker.py:
--------------------------------------------------------------------------------

```python
 1 | from serena.tools import CreateTextFileTool, ReadFileTool, Tool
 2 | 
 3 | 
 4 | class TestEditMarker:
 5 |     def test_tool_can_edit_method(self):
 6 |         """Test that Tool.can_edit() method works correctly"""
 7 |         # Non-editing tool should return False
 8 |         assert issubclass(ReadFileTool, Tool)
 9 |         assert not ReadFileTool.can_edit()
10 | 
11 |         # Editing tool should return True
12 |         assert issubclass(CreateTextFileTool, Tool)
13 |         assert CreateTextFileTool.can_edit()
14 | 
```

--------------------------------------------------------------------------------
/.github/workflows/junie.yml:
--------------------------------------------------------------------------------

```yaml
 1 | name: Junie
 2 | run-name: Junie run ${{ inputs.run_id }}
 3 | 
 4 | permissions:
 5 |   contents: write
 6 | 
 7 | on:
 8 |   workflow_dispatch:
 9 |     inputs:
10 |       run_id:
11 |         description: "id of workflow process"
12 |         required: true
13 |       workflow_params:
14 |         description: "stringified params"
15 |         required: true
16 | 
17 | jobs:
18 |   call-workflow-passing-data:
19 |     uses: jetbrains-junie/junie-workflows/.github/workflows/ej-issue.yml@main
20 |     with:
21 |       workflow_params: ${{ inputs.workflow_params }}
22 | 
```

--------------------------------------------------------------------------------
/test/solidlsp/clojure/__init__.py:
--------------------------------------------------------------------------------

```python
 1 | from pathlib import Path
 2 | 
 3 | from solidlsp.language_servers.clojure_lsp import verify_clojure_cli
 4 | 
 5 | 
 6 | def _test_clojure_cli() -> bool:
 7 |     try:
 8 |         verify_clojure_cli()
 9 |         return False
10 |     except (FileNotFoundError, RuntimeError):
11 |         return True
12 | 
13 | 
14 | CLI_FAIL = _test_clojure_cli()
15 | TEST_APP_PATH = Path("src") / "test_app"
16 | CORE_PATH = str(TEST_APP_PATH / "core.clj")
17 | UTILS_PATH = str(TEST_APP_PATH / "utils.clj")
18 | 
19 | 
20 | def is_clojure_cli_available() -> bool:
21 |     return not CLI_FAIL
22 | 
```

--------------------------------------------------------------------------------
/src/serena/resources/config/modes/planning.yml:
--------------------------------------------------------------------------------

```yaml
 1 | description: Only read-only tools, focused on analysis and planning
 2 | prompt: |
 3 |   You are operating in planning mode. Your task is to analyze code but not write any code.
 4 |   The user may ask you to assist in creating a comprehensive plan, or to learn something about the codebase.
 5 | excluded_tools:
 6 |   - create_text_file
 7 |   - replace_symbol_body
 8 |   - insert_after_symbol
 9 |   - insert_before_symbol
10 |   - delete_lines
11 |   - replace_lines
12 |   - insert_at_line
13 |   - execute_shell_command
14 |   - replace_content
15 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/python/test_repo/test_repo/name_collisions.py:
--------------------------------------------------------------------------------

```python
 1 | # ruff: noqa
 2 | var_will_be_overwritten = 1
 3 | 
 4 | var_will_be_overwritten = 2
 5 | 
 6 | 
 7 | def func_using_overwritten_var():
 8 |     print(var_will_be_overwritten)
 9 | 
10 | 
11 | class ClassWillBeOverwritten:
12 |     def method1(self):
13 |         pass
14 | 
15 | 
16 | class ClassWillBeOverwritten:
17 |     def method2(self):
18 |         pass
19 | 
20 | 
21 | def func_will_be_overwritten():
22 |     pass
23 | 
24 | 
25 | def func_will_be_overwritten():
26 |     pass
27 | 
28 | 
29 | def func_calling_overwritten_func():
30 |     func_will_be_overwritten()
31 | 
32 | 
33 | def func_calling_overwritten_class():
34 |     ClassWillBeOverwritten()
35 | 
```

--------------------------------------------------------------------------------
/docs/02-usage/010_prerequisites.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Prerequisites
 2 | 
 3 | ## Package Manager: uv
 4 | 
 5 | Serena is managed by `uv`.
 6 | If you do not have it yet, install it following the instructions [here](https://docs.astral.sh/uv/getting-started/installation/).
 7 | 
 8 | ## Language-Specific Requirements
 9 | 
10 | Depending on the programming language you intend to use with Serena, you may need to install additional tools or SDKs if you 
11 | intend to use the language server backend of Serena.  
12 | See the [language support documentation](../01-about/020_programming-languages) for details. 
13 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/elm/test_repo/elm.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |     "type": "application",
 3 |     "source-directories": [
 4 |         "."
 5 |     ],
 6 |     "elm-version": "0.19.1",
 7 |     "dependencies": {
 8 |         "direct": {
 9 |             "elm/browser": "1.0.2",
10 |             "elm/core": "1.0.5",
11 |             "elm/html": "1.0.0"
12 |         },
13 |         "indirect": {
14 |             "elm/json": "1.1.3",
15 |             "elm/time": "1.0.0",
16 |             "elm/url": "1.0.0",
17 |             "elm/virtual-dom": "1.0.3"
18 |         }
19 |     },
20 |     "test-dependencies": {
21 |         "direct": {},
22 |         "indirect": {}
23 |     }
24 | }
25 | 
```

--------------------------------------------------------------------------------
/src/serena/__init__.py:
--------------------------------------------------------------------------------

```python
 1 | __version__ = "0.1.4"
 2 | 
 3 | import logging
 4 | 
 5 | log = logging.getLogger(__name__)
 6 | 
 7 | 
 8 | def serena_version() -> str:
 9 |     """
10 |     :return: the version of the package, including git status if available.
11 |     """
12 |     from serena.util.git import get_git_status
13 | 
14 |     version = __version__
15 |     try:
16 |         git_status = get_git_status()
17 |         if git_status is not None:
18 |             version += f"-{git_status.commit[:8]}"
19 |             if not git_status.is_clean:
20 |                 version += "-dirty"
21 |     except:
22 |         pass
23 |     return version
24 | 
```

--------------------------------------------------------------------------------
/.github/workflows/codespell.yml:
--------------------------------------------------------------------------------

```yaml
 1 | # Codespell configuration is within pyproject.toml
 2 | ---
 3 | name: Codespell
 4 | 
 5 | on:
 6 |   push:
 7 |     branches: [main]
 8 |   pull_request:
 9 |     branches: [main]
10 | 
11 | permissions:
12 |   contents: read
13 | 
14 | jobs:
15 |   codespell:
16 |     name: Check for spelling errors
17 |     runs-on: ubuntu-latest
18 |     timeout-minutes: 2
19 | 
20 |     steps:
21 |       - name: Checkout
22 |         uses: actions/checkout@v4
23 |       - name: Annotate locations with typos
24 |         uses: codespell-project/codespell-problem-matcher@v1
25 |       - name: Codespell
26 |         uses: codespell-project/actions-codespell@v2
27 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/toml/test_repo/Cargo.toml:
--------------------------------------------------------------------------------

```toml
 1 | [package]
 2 | name = "test_project"
 3 | version = "0.1.0"
 4 | edition = "2021"
 5 | description = "A test TOML file for Serena TOML language support"
 6 | authors = ["Test Author <[email protected]>"]
 7 | license = "MIT"
 8 | 
 9 | [dependencies]
10 | serde = { version = "1.0", features = ["derive"] }
11 | tokio = { version = "1.0", features = ["full"] }
12 | 
13 | [dev-dependencies]
14 | proptest = "1.0"
15 | 
16 | [features]
17 | default = ["feature1"]
18 | feature1 = []
19 | feature2 = ["feature1"]
20 | 
21 | [profile.release]
22 | lto = true
23 | opt-level = 3
24 | 
25 | [[bin]]
26 | name = "main"
27 | path = "src/main.rs"
28 | 
29 | [workspace]
30 | members = ["crates/*"]
31 | 
```

--------------------------------------------------------------------------------
/src/solidlsp/util/subprocess_util.py:
--------------------------------------------------------------------------------

```python
 1 | import platform
 2 | import subprocess
 3 | 
 4 | 
 5 | def subprocess_kwargs() -> dict:
 6 |     """
 7 |     Returns a dictionary of keyword arguments for subprocess calls, adding platform-specific
 8 |     flags that we want to use consistently.
 9 |     """
10 |     kwargs = {}
11 |     if platform.system() == "Windows":
12 |         kwargs["creationflags"] = subprocess.CREATE_NO_WINDOW  # type: ignore
13 |     return kwargs
14 | 
15 | 
16 | def quote_arg(arg: str) -> str:
17 |     """
18 |     Adds quotes around an argument if it contains spaces.
19 |     """
20 |     if " " not in arg:
21 |         return arg
22 |     return f'"{arg}"'
23 | 
```

--------------------------------------------------------------------------------
/scripts/print_mode_context_options.py:
--------------------------------------------------------------------------------

```python
 1 | from serena.config.context_mode import SerenaAgentContext, SerenaAgentMode
 2 | 
 3 | if __name__ == "__main__":
 4 |     print("---------- Available modes: ----------")
 5 |     for mode_name in SerenaAgentMode.list_registered_mode_names():
 6 |         mode = SerenaAgentMode.load(mode_name)
 7 |         mode.print_overview()
 8 |         print("\n")
 9 |     print("---------- Available contexts: ----------")
10 |     for context_name in SerenaAgentContext.list_registered_context_names():
11 |         context = SerenaAgentContext.load(context_name)
12 |         context.print_overview()
13 |         print("\n")
14 | 
```

--------------------------------------------------------------------------------
/src/serena/prompt_factory.py:
--------------------------------------------------------------------------------

```python
 1 | import os
 2 | 
 3 | from serena.config.serena_config import SerenaPaths
 4 | from serena.constants import PROMPT_TEMPLATES_DIR_INTERNAL
 5 | from serena.generated.generated_prompt_factory import PromptFactory
 6 | 
 7 | 
 8 | class SerenaPromptFactory(PromptFactory):
 9 |     """
10 |     A class for retrieving and rendering prompt templates and prompt lists.
11 |     """
12 | 
13 |     def __init__(self) -> None:
14 |         user_templates_dir = SerenaPaths().user_prompt_templates_dir
15 |         os.makedirs(user_templates_dir, exist_ok=True)
16 |         super().__init__(prompts_dir=[user_templates_dir, PROMPT_TEMPLATES_DIR_INTERNAL])
17 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/erlang/test_repo/rebar.config:
--------------------------------------------------------------------------------

```
 1 | %% Rebar3 configuration for test repository
 2 | {erl_opts, [
 3 |     debug_info,
 4 |     warnings_as_errors,
 5 |     warn_export_all,
 6 |     warn_unused_import,
 7 |     {i, "include"}
 8 | ]}.
 9 | 
10 | {deps, [
11 |     {eunit, ".*", {git, "https://github.com/richcarl/eunit.git", {tag, "2.3.6"}}}
12 | ]}.
13 | 
14 | {profiles, [
15 |     {test, [
16 |         {erl_opts, [debug_info]},
17 |         {deps, [
18 |             {proper, "1.3.0"}
19 |         ]}
20 |     ]}
21 | ]}.
22 | 
23 | {cover_enabled, true}.
24 | {cover_print_enabled, true}.
25 | 
26 | {dialyzer, [
27 |     {warnings, [
28 |         unmatched_returns,
29 |         error_handling,
30 |         race_conditions,
31 |         underspecs
32 |     ]}
33 | ]}.
```

--------------------------------------------------------------------------------
/test/resources/repos/swift/test_repo/src/utils.swift:
--------------------------------------------------------------------------------

```swift
 1 | import Foundation
 2 | 
 3 | public struct Utils {
 4 |     public static func formatDate(_ date: Date) -> String {
 5 |         let formatter = DateFormatter()
 6 |         formatter.dateStyle = .medium
 7 |         return formatter.string(from: date)
 8 |     }
 9 |     
10 |     public static func calculateArea(radius: Double) -> Double {
11 |         return Double.pi * radius * radius
12 |     }
13 | }
14 | 
15 | public extension String {
16 |     func isValidEmail() -> Bool {
17 |         let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}"
18 |         return NSPredicate(format: "SELF MATCHES %@", emailRegex).evaluate(with: self)
19 |     }
20 | }
```

--------------------------------------------------------------------------------
/scripts/gen_prompt_factory.py:
--------------------------------------------------------------------------------

```python
 1 | """
 2 | Autogenerates the `prompt_factory.py` module
 3 | """
 4 | 
 5 | from pathlib import Path
 6 | 
 7 | from sensai.util import logging
 8 | 
 9 | from interprompt import autogenerate_prompt_factory_module
10 | from serena.constants import PROMPT_TEMPLATES_DIR_INTERNAL, REPO_ROOT
11 | 
12 | log = logging.getLogger(__name__)
13 | 
14 | 
15 | def main():
16 |     autogenerate_prompt_factory_module(
17 |         prompts_dir=PROMPT_TEMPLATES_DIR_INTERNAL,
18 |         target_module_path=str(Path(REPO_ROOT) / "src" / "serena" / "generated" / "generated_prompt_factory.py"),
19 |     )
20 | 
21 | 
22 | if __name__ == "__main__":
23 |     logging.run_main(main)
24 | 
```

--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------

```markdown
 1 | ---
 2 | name: Feature request
 3 | about: Suggest an idea for this project
 4 | title: ''
 5 | labels: ''
 6 | assignees: ''
 7 | 
 8 | ---
 9 | 
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 | 
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 | 
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 | 
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 | 
```

--------------------------------------------------------------------------------
/src/serena/resources/config/internal_modes/jetbrains.yml:
--------------------------------------------------------------------------------

```yaml
 1 | description: JetBrains tools replace language server-based tools
 2 | prompt: |
 3 |   You have access to the very powerful JetBrains tools for symbolic operations:
 4 |     * `jet_brains_find_symbol` replaces `find_symbol`
 5 |     * `jet_brains_find_referencing_symbols` replaces `find_referencing_symbols`
 6 |     * `jet_brains_get_symbols_overview` replaces `get_symbols_overview`
 7 | excluded_tools:
 8 |   - find_symbol
 9 |   - find_referencing_symbols
10 |   - get_symbols_overview
11 |   - restart_language_server
12 | included_optional_tools:
13 |   - jet_brains_find_symbol
14 |   - jet_brains_find_referencing_symbols
15 |   - jet_brains_get_symbols_overview
16 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/vue/test_repo/src/types/index.ts:
--------------------------------------------------------------------------------

```typescript
 1 | /**
 2 |  * Represents a single calculation in the history
 3 |  */
 4 | export interface HistoryEntry {
 5 |   expression: string
 6 |   result: number
 7 |   timestamp: Date
 8 | }
 9 | 
10 | /**
11 |  * Valid calculator operations
12 |  */
13 | export type Operation = 'add' | 'subtract' | 'multiply' | 'divide' | null
14 | 
15 | /**
16 |  * The complete state of the calculator
17 |  */
18 | export interface CalculatorState {
19 |   currentValue: number
20 |   previousValue: number | null
21 |   operation: Operation
22 |   history: HistoryEntry[]
23 |   displayValue: string
24 | }
25 | 
26 | /**
27 |  * Format options for displaying numbers
28 |  */
29 | export interface FormatOptions {
30 |   maxDecimals?: number
31 |   useGrouping?: boolean
32 | }
33 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/yaml/test_repo/data.yaml:
--------------------------------------------------------------------------------

```yaml
 1 | # Sample data structure
 2 | users:
 3 |   - id: 1
 4 |     name: John Doe
 5 |     email: [email protected]
 6 |     roles:
 7 |       - admin
 8 |       - developer
 9 |     active: true
10 | 
11 |   - id: 2
12 |     name: Jane Smith
13 |     email: [email protected]
14 |     roles:
15 |       - developer
16 |     active: true
17 | 
18 |   - id: 3
19 |     name: Bob Johnson
20 |     email: [email protected]
21 |     roles:
22 |       - viewer
23 |     active: false
24 | 
25 | projects:
26 |   - name: project-alpha
27 |     status: active
28 |     team:
29 |       - John Doe
30 |       - Jane Smith
31 |     tags:
32 |       - backend
33 |       - api
34 | 
35 |   - name: project-beta
36 |     status: planning
37 |     team:
38 |       - Jane Smith
39 |     tags:
40 |       - frontend
41 |       - ui
42 | 
```

--------------------------------------------------------------------------------
/src/serena/resources/config/modes/interactive.yml:
--------------------------------------------------------------------------------

```yaml
 1 | description: Interactive mode for clarification and step-by-step work
 2 | prompt: |
 3 |   You are operating in interactive mode. You should engage with the user throughout the task, asking for clarification
 4 |   whenever anything is unclear, insufficiently specified, or ambiguous.
 5 |   
 6 |   Break down complex tasks into smaller steps and explain your thinking at each stage. When you're uncertain about
 7 |   a decision, present options to the user and ask for guidance rather than making assumptions.
 8 |   
 9 |   Focus on providing informative results for intermediate steps, such that the user can follow along with your progress and
10 |   provide feedback as needed.
11 | excluded_tools: []
```

--------------------------------------------------------------------------------
/src/serena/resources/config/modes/onboarding.yml:
--------------------------------------------------------------------------------

```yaml
 1 | description: Only read-only tools, focused on analysis and planning
 2 | prompt: |
 3 |   You are operating in onboarding mode. This is the first time you are seeing the project.
 4 |   Your task is to collect relevant information about it and to save memories using the tools provided.
 5 |   Call relevant onboarding tools for more instructions on how to do this.
 6 |   In this mode, you should not be modifying any existing files.
 7 |   If you are also in interactive mode and something about the project is unclear, ask the user for clarification.
 8 | excluded_tools:
 9 |   - create_text_file
10 |   - replace_symbol_body
11 |   - insert_after_symbol
12 |   - insert_before_symbol
13 |   - delete_lines
14 |   - replace_lines
15 |   - insert_at_line
16 |   - execute_shell_command
17 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/vue/test_repo/tsconfig.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "compilerOptions": {
 3 |     "target": "ES2020",
 4 |     "useDefineForClassFields": true,
 5 |     "module": "ESNext",
 6 |     "lib": ["ES2020", "DOM", "DOM.Iterable"],
 7 |     "skipLibCheck": true,
 8 |     "moduleResolution": "bundler",
 9 |     "allowImportingTsExtensions": true,
10 |     "resolveJsonModule": true,
11 |     "isolatedModules": true,
12 |     "noEmit": true,
13 |     "jsx": "preserve",
14 |     "strict": true,
15 |     "noUnusedLocals": true,
16 |     "noUnusedParameters": true,
17 |     "noFallthroughCasesInSwitch": true,
18 |     "baseUrl": ".",
19 |     "paths": {
20 |       "@/*": ["./src/*"]
21 |     }
22 |   },
23 |   "plugins": [
24 |     {
25 |       "name": "@vue/typescript-plugin"
26 |     }
27 |   ],
28 |   "include": ["src/**/*.ts", "src/**/*.vue"],
29 |   "references": [{ "path": "./tsconfig.node.json" }]
30 | }
31 | 
```

--------------------------------------------------------------------------------
/src/serena/util/gui.py:
--------------------------------------------------------------------------------

```python
 1 | import os
 2 | import platform
 3 | 
 4 | 
 5 | def system_has_usable_display() -> bool:
 6 |     system = platform.system()
 7 | 
 8 |     # macOS and native Windows: assume display is available for desktop usage
 9 |     if system == "Darwin" or system == "Windows":
10 |         return True
11 | 
12 |     # Other systems, assumed to be Unix-like (Linux, FreeBSD, Cygwin/MSYS, etc.):
13 |     # detect display availability since users may operate in CLI contexts
14 |     else:
15 |         # Check X11 or Wayland - if environment variables are set to non-empty values, assume display is usable
16 |         display = os.environ.get("DISPLAY", "")
17 |         wayland_display = os.environ.get("WAYLAND_DISPLAY", "")
18 | 
19 |         if display or wayland_display:
20 |             return True
21 | 
22 |         return False
23 | 
```

--------------------------------------------------------------------------------
/src/serena/util/git.py:
--------------------------------------------------------------------------------

```python
 1 | import logging
 2 | 
 3 | from sensai.util.git import GitStatus
 4 | 
 5 | from .shell import subprocess_check_output
 6 | 
 7 | log = logging.getLogger(__name__)
 8 | 
 9 | 
10 | def get_git_status() -> GitStatus | None:
11 |     try:
12 |         commit_hash = subprocess_check_output(["git", "rev-parse", "HEAD"])
13 |         unstaged = bool(subprocess_check_output(["git", "diff", "--name-only"]))
14 |         staged = bool(subprocess_check_output(["git", "diff", "--staged", "--name-only"]))
15 |         untracked = bool(subprocess_check_output(["git", "ls-files", "--others", "--exclude-standard"]))
16 |         return GitStatus(
17 |             commit=commit_hash, has_unstaged_changes=unstaged, has_staged_uncommitted_changes=staged, has_untracked_files=untracked
18 |         )
19 |     except:
20 |         return None
21 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/csharp/test_repo/Models/Person.cs:
--------------------------------------------------------------------------------

```csharp
 1 | using TestProject;
 2 | 
 3 | namespace TestProject.Models
 4 | {
 5 |     public class Person
 6 |     {
 7 |         public string Name { get; set; }
 8 |         public int Age { get; set; }
 9 |         public string Email { get; set; }
10 |         
11 |         public Person(string name, int age, string email)
12 |         {
13 |             Name = name;
14 |             Age = age;
15 |             Email = email;
16 |         }
17 |         
18 |         public override string ToString()
19 |         {
20 |             return $"{Name} ({Age}) - {Email}";
21 |         }
22 |         
23 |         public bool IsAdult()
24 |         {
25 |             return Age >= 18;
26 |         }
27 |         
28 |         public int CalculateYearsUntilRetirement()
29 |         {
30 |             var calculator = new Calculator();
31 |             return calculator.Subtract(65, Age);
32 |         }
33 |     }
34 | }
```

--------------------------------------------------------------------------------
/test/solidlsp/elixir/__init__.py:
--------------------------------------------------------------------------------

```python
 1 | def _test_expert_available() -> str:
 2 |     """Test if Expert is available and return error reason if not."""
 3 |     # Try to import and check Elixir availability
 4 |     try:
 5 |         from solidlsp.language_servers.elixir_tools.elixir_tools import ElixirTools
 6 | 
 7 |         # Check if Elixir is installed
 8 |         elixir_version = ElixirTools._get_elixir_version()
 9 |         if not elixir_version:
10 |             return "Elixir is not installed or not in PATH"
11 | 
12 |         return ""  # No error, Expert should be available
13 | 
14 |     except ImportError as e:
15 |         return f"Failed to import ElixirTools: {e}"
16 |     except Exception as e:
17 |         return f"Error checking Expert availability: {e}"
18 | 
19 | 
20 | EXPERT_UNAVAILABLE_REASON = _test_expert_available()
21 | EXPERT_UNAVAILABLE = bool(EXPERT_UNAVAILABLE_REASON)
22 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/al/test_repo/app.json:
--------------------------------------------------------------------------------

```json
 1 | {
 2 |   "id": "00000001-0000-0000-0000-000000000001",
 3 |   "name": "Test AL Project",
 4 |   "publisher": "Serena Test Publisher",
 5 |   "version": "1.0.0.0",
 6 |   "brief": "Test project for AL Language Server in Serena",
 7 |   "description": "This project contains AL code samples for testing language server features",
 8 |   "privacyStatement": "",
 9 |   "EULA": "",
10 |   "help": "",
11 |   "url": "https://github.com/oraios/serena",
12 |   "logo": "",
13 |   "dependencies": [],
14 |   "screenshots": [],
15 |   "platform": "1.0.0.0",
16 |   "application": "26.0.0.0",
17 |   "idRanges": [
18 |     {
19 |       "from": 50000,
20 |       "to": 50100
21 |     }
22 |   ],
23 |   "resourceExposurePolicy": {
24 |     "allowDebugging": true,
25 |     "allowDownloadingSource": true,
26 |     "includeSourceInSymbolFile": true
27 |   },
28 |   "runtime": "15.0",
29 |   "features": ["NoImplicitWith"],
30 |   "target": "Cloud"
31 | }
```

--------------------------------------------------------------------------------
/src/solidlsp/util/cache.py:
--------------------------------------------------------------------------------

```python
 1 | import logging
 2 | from typing import Any, Optional
 3 | 
 4 | from sensai.util.pickle import dump_pickle, load_pickle
 5 | 
 6 | log = logging.getLogger(__name__)
 7 | 
 8 | 
 9 | def load_cache(path: str, version: Any) -> Optional[Any]:
10 |     data = load_pickle(path)
11 |     if not isinstance(data, dict) or "__cache_version" not in data:
12 |         log.info("Cache is outdated (expected version %s). Ignoring cache at %s", version, path)
13 |         return None
14 |     saved_version = data["__cache_version"]
15 |     if saved_version != version:
16 |         log.info("Cache is outdated (expected version %s, got %s). Ignoring cache at %s", version, saved_version, path)
17 |         return None
18 |     return data["obj"]
19 | 
20 | 
21 | def save_cache(path: str, version: Any, obj: Any) -> None:
22 |     data = {"__cache_version": version, "obj": obj}
23 |     dump_pickle(data, path)
24 | 
```

--------------------------------------------------------------------------------
/compose.yaml:
--------------------------------------------------------------------------------

```yaml
 1 | services:
 2 |   serena:
 3 |     image: serena:latest
 4 |     # To work with projects, you must mount them into /workspace/ in the container:
 5 |     # volumes:
 6 |       # - ./my-project:/workspace/my-project
 7 |       # - /path/to/another/project:/workspace/another-project
 8 |     build:
 9 |       context: ./
10 |       dockerfile: Dockerfile
11 |       target: production
12 |     ports:
13 |       - "${SERENA_PORT:-9121}:9121"  # MCP server port
14 |       - "${SERENA_DASHBOARD_PORT:-24282}:24282"  # Dashboard port (default 0x5EDA = 24282)
15 |     environment:
16 |       - SERENA_DOCKER=1
17 |     command:
18 |       - "uv run --directory . serena-mcp-server --transport sse --port 9121 --host 0.0.0.0"
19 |       # Alternatively add further arguments, e.g. a context
20 |       # - "uv run --directory . serena-mcp-server --transport sse --port 9121 --host 0.0.0.0 --context ide"
21 | 
22 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/toml/test_repo/pyproject.toml:
--------------------------------------------------------------------------------

```toml
 1 | [project]
 2 | name = "test-project"
 3 | version = "0.1.0"
 4 | description = "A test Python project for TOML support"
 5 | readme = "README.md"
 6 | requires-python = ">=3.11"
 7 | license = {text = "MIT"}
 8 | authors = [
 9 |     {name = "Test Author", email = "[email protected]"}
10 | ]
11 | dependencies = [
12 |     "pydantic>=2.0",
13 |     "httpx>=0.24",
14 | ]
15 | 
16 | [project.optional-dependencies]
17 | dev = [
18 |     "pytest>=7.0",
19 |     "ruff>=0.1",
20 |     "mypy>=1.0",
21 | ]
22 | 
23 | [build-system]
24 | requires = ["hatchling"]
25 | build-backend = "hatchling.build"
26 | 
27 | [tool.ruff]
28 | line-length = 88
29 | target-version = "py311"
30 | select = ["E", "F", "I", "N", "W", "B", "S"]
31 | 
32 | [tool.ruff.isort]
33 | known-first-party = ["test_project"]
34 | 
35 | [tool.mypy]
36 | python_version = "3.11"
37 | strict = true
38 | warn_unreachable = true
39 | 
40 | [tool.pytest.ini_options]
41 | testpaths = ["tests"]
42 | python_files = ["test_*.py"]
43 | addopts = "-v --cov=src"
44 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/ruby/test_repo/nested.rb:
--------------------------------------------------------------------------------

```ruby
 1 | class OuterClass
 2 |   def initialize
 3 |     @value = "outer"
 4 |   end
 5 | 
 6 |   def outer_method
 7 |     inner_function = lambda do |x|
 8 |       x * 2
 9 |     end
10 |     
11 |     result = inner_function.call(5)
12 |     puts "Result: #{result}"
13 |   end
14 | 
15 |   class NestedClass
16 |     def initialize(name)
17 |       @name = name
18 |     end
19 | 
20 |     def find_me
21 |       "Found in NestedClass: #{@name}"
22 |     end
23 | 
24 |     def nested_method
25 |       puts "Nested method called"
26 |     end
27 | 
28 |     class DeeplyNested
29 |       def deep_method
30 |         "Deep inside"
31 |       end
32 |     end
33 |   end
34 | 
35 |   module NestedModule
36 |     def module_method
37 |       "Module method"
38 |     end
39 | 
40 |     class ModuleClass
41 |       def module_class_method
42 |         "Module class method"
43 |       end
44 |     end
45 |   end
46 | end
47 | 
48 | # Test usage of nested classes
49 | outer = OuterClass.new
50 | nested = OuterClass::NestedClass.new("test")
51 | result = nested.find_me
```

--------------------------------------------------------------------------------
/test/resources/repos/yaml/test_repo/services.yml:
--------------------------------------------------------------------------------

```yaml
 1 | # Docker compose services definition
 2 | version: '3.8'
 3 | 
 4 | services:
 5 |   web:
 6 |     image: nginx:latest
 7 |     ports:
 8 |       - "80:80"
 9 |       - "443:443"
10 |     volumes:
11 |       - ./html:/usr/share/nginx/html
12 |     environment:
13 |       - NGINX_HOST=localhost
14 |       - NGINX_PORT=80
15 |     networks:
16 |       - frontend
17 | 
18 |   api:
19 |     image: node:18
20 |     ports:
21 |       - "3000:3000"
22 |     depends_on:
23 |       - database
24 |     environment:
25 |       - NODE_ENV=production
26 |       - DB_HOST=database
27 |     networks:
28 |       - frontend
29 |       - backend
30 | 
31 |   database:
32 |     image: postgres:15
33 |     ports:
34 |       - "5432:5432"
35 |     environment:
36 |       - POSTGRES_DB=mydb
37 |       - POSTGRES_USER=admin
38 |       - POSTGRES_PASSWORD=password
39 |     volumes:
40 |       - db-data:/var/lib/postgresql/data
41 |     networks:
42 |       - backend
43 | 
44 | networks:
45 |   frontend:
46 |     driver: bridge
47 |   backend:
48 |     driver: bridge
49 | 
50 | volumes:
51 |   db-data:
52 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/csharp/test_repo/Program.cs:
--------------------------------------------------------------------------------

```csharp
 1 | using System;
 2 | 
 3 | namespace TestProject
 4 | {
 5 |     class Program
 6 |     {
 7 |         static void Main(string[] args)
 8 |         {
 9 |             Console.WriteLine("Hello, World!");
10 |             
11 |             var calculator = new Calculator();
12 |             int result = calculator.Add(5, 3);
13 |             Console.WriteLine($"5 + 3 = {result}");
14 |         }
15 |     }
16 |     
17 |     public class Calculator
18 |     {
19 |         public int Add(int a, int b)
20 |         {
21 |             return a + b;
22 |         }
23 |         
24 |         public int Subtract(int a, int b)
25 |         {
26 |             return a - b;
27 |         }
28 |         
29 |         public int Multiply(int a, int b)
30 |         {
31 |             return a * b;
32 |         }
33 |         
34 |         public double Divide(int a, int b)
35 |         {
36 |             if (b == 0)
37 |             {
38 |                 throw new DivideByZeroException("Cannot divide by zero");
39 |             }
40 |             return (double)a / b;
41 |         }
42 |     }
43 | }
```

--------------------------------------------------------------------------------
/docs/02-usage/070_security.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Security Considerations
 2 | 
 3 | As fundamental abilities for a coding agent, Serena contains tools for executing shell commands and modifying files.
 4 | Therefore, if the respective tool calls are not monitored or restricted (and execution takes place in a sensitive environment), 
 5 | there is a risk of unintended consequences.
 6 | 
 7 | Therefore, to reduce the risk of unintended consequences when using Serena, it is recommended to
 8 |   * back up your work regularly (e.g. use a version control system like Git),
 9 |   * monitor tool executions carefully (e.g. via your MCP client, provided that it supports it),
10 |   * consider enabling read-only mode for your project (set `read_only: True` in project.yml) if you only want to analyze code without modifying it,
11 |   * restrict the set of allowed tools via the [configuration](050_configuration),
12 |   * use a sandboxed environment for running Serena (e.g. by [using Docker](docker)).
13 | 
```

--------------------------------------------------------------------------------
/src/serena/resources/config/modes/one-shot.yml:
--------------------------------------------------------------------------------

```yaml
 1 | description: Focus on completely finishing a task without interaction
 2 | prompt: |
 3 |   You are operating in one-shot mode. Your goal is to complete the entire task autonomously without further user interaction.
 4 |   You should assume auto-approval for all tools and continue working until the task is completely finished.
 5 |   
 6 |   If the task is planning, your final result should be a comprehensive plan. If the task is coding, your final result
 7 |   should be working code with all requirements fulfilled. Try to understand what the user asks you to do
 8 |   and to assume as little as possible.
 9 | 
10 |   Only abort the task if absolutely necessary, such as when critical information is missing that cannot be inferred
11 |   from the codebase.
12 | 
13 |   It may be that you have not received a task yet. In this case, wait for the user to provide a task, this will be the 
14 |   only time you should wait for user interaction.
15 | excluded_tools: []
16 | 
```

--------------------------------------------------------------------------------
/scripts/agno_agent.py:
--------------------------------------------------------------------------------

```python
 1 | from agno.models.anthropic.claude import Claude
 2 | from agno.models.google.gemini import Gemini
 3 | from agno.os import AgentOS
 4 | from sensai.util import logging
 5 | from sensai.util.helper import mark_used
 6 | 
 7 | from serena.agno import SerenaAgnoAgentProvider
 8 | 
 9 | mark_used(Gemini, Claude)
10 | 
11 | # initialize logging
12 | if __name__ == "__main__":
13 |     logging.configure(level=logging.INFO)
14 | 
15 | # Define the model to use (see Agno documentation for supported models; these are just examples)
16 | # model = Claude(id="claude-3-7-sonnet-20250219")
17 | model = Gemini(id="gemini-2.5-pro")
18 | 
19 | # Create the Serena agent using the existing provider
20 | serena_agent = SerenaAgnoAgentProvider.get_agent(model)
21 | 
22 | # Create AgentOS app with the Serena agent
23 | agent_os = AgentOS(
24 |     description="Serena coding assistant powered by AgentOS",
25 |     id="serena-agentos",
26 |     agents=[serena_agent],
27 | )
28 | 
29 | app = agent_os.get_app()
30 | 
31 | if __name__ == "__main__":
32 |     # Start the AgentOS server
33 |     agent_os.serve(app="agno_agent:app", reload=False)
34 | 
```

--------------------------------------------------------------------------------
/scripts/demo_run_tools.py:
--------------------------------------------------------------------------------

```python
 1 | """
 2 | This script demonstrates how to use Serena's tools locally, useful
 3 | for testing or development. Here the tools will be operation the serena repo itself.
 4 | """
 5 | 
 6 | import json
 7 | from pprint import pprint
 8 | 
 9 | from serena.agent import SerenaAgent
10 | from serena.constants import REPO_ROOT
11 | from serena.tools import FindFileTool, FindReferencingSymbolsTool, GetSymbolsOverviewTool, JetBrainsFindSymbolTool, SearchForPatternTool
12 | 
13 | if __name__ == "__main__":
14 |     agent = SerenaAgent(project=REPO_ROOT)
15 | 
16 |     # apply a tool
17 |     find_symbol_tool = agent.get_tool(JetBrainsFindSymbolTool)
18 |     find_refs_tool = agent.get_tool(FindReferencingSymbolsTool)
19 |     find_file_tool = agent.get_tool(FindFileTool)
20 |     search_pattern_tool = agent.get_tool(SearchForPatternTool)
21 |     overview_tool = agent.get_tool(GetSymbolsOverviewTool)
22 | 
23 |     result = agent.execute_task(
24 |         lambda: find_symbol_tool.apply("displayBasicStats"),
25 |     )
26 |     pprint(json.loads(result))
27 |     # input("Press Enter to continue...")
28 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/ruby/test_repo/services.rb:
--------------------------------------------------------------------------------

```ruby
 1 | require './lib.rb'
 2 | require './models.rb'
 3 | 
 4 | module Services
 5 |   class UserService
 6 |     attr_reader :users
 7 | 
 8 |     def initialize
 9 |       @users = {}
10 |     end
11 | 
12 |     def create_user(id, name)
13 |       user = User.new(id, name)
14 |       @users[id] = user
15 |       user
16 |     end
17 | 
18 |     def get_user(id)
19 |       @users[id]
20 |     end
21 | 
22 |     def delete_user(id)
23 |       @users.delete(id)
24 |     end
25 | 
26 |     private
27 | 
28 |     def validate_user_data(id, name)
29 |       return false if id.nil? || name.nil?
30 |       return false if name.empty?
31 |       true
32 |     end
33 |   end
34 | 
35 |   class ItemService
36 |     def initialize
37 |       @items = []
38 |     end
39 | 
40 |     def add_item(item)
41 |       @items << item
42 |     end
43 | 
44 |     def find_item(id)
45 |       @items.find { |item| item.id == id }
46 |     end
47 |   end
48 | end
49 | 
50 | # Module-level function
51 | def create_service_container
52 |   {
53 |     user_service: Services::UserService.new,
54 |     item_service: Services::ItemService.new
55 |   }
56 | end
57 | 
58 | # Variables for testing
59 | user_service_instance = Services::UserService.new
60 | item_service_instance = Services::ItemService.new
```

--------------------------------------------------------------------------------
/src/serena/resources/config/contexts/codex.yml:
--------------------------------------------------------------------------------

```yaml
 1 | description: Codex Non-symbolic editing tools and general shell tool are excluded
 2 | prompt: |
 3 |   You are running in the Codex IDE assistant mode, where file operations, basic (line-based) edits and reads 
 4 |   as well as shell commands are handled by your own, internal tools.
 5 |   Don't attempt to use any excluded tools; instead, rely on your own internal tools for basic file or shell operations.
 6 |   
 7 |   If Serena's tools can be used to achieve your task, you should prioritize them. 
 8 |   In particular, it is important that you avoid reading entire source code files unless it is strictly necessary! 
 9 |   Instead, for exploring and reading code in a token-efficient manner, use Serena's overview and symbolic search tools. 
10 |   For non-code files or for reads where you don't know the symbol's name path, you can use the pattern search tool.
11 | 
12 | excluded_tools:
13 |   - create_text_file
14 |   - read_file
15 |   - execute_shell_command
16 |   - prepare_for_new_conversation
17 |   - replace_content
18 | 
19 | 
20 | tool_description_overrides: {}
21 | 
22 | 
```

--------------------------------------------------------------------------------
/src/serena/resources/config/contexts/desktop-app.yml:
--------------------------------------------------------------------------------

```yaml
 1 | description: Desktop application context (chat application detached from code) where Serena's full toolset is provided
 2 | prompt: |
 3 |   You are running in a desktop application context.
 4 |   Serena's tools give you access to the code base as well as some access to the file system (if enabled). 
 5 |   You interact with the user through a chat interface that is separated from the code base. 
 6 |   As a consequence, if you are in interactive mode, your communication with the user should
 7 |   involve high-level thinking and planning as well as some summarization of any code edits that you make.
 8 |   To view the code edits you make, the user will have switch to a separate application.
 9 |   To illustrate complex relationships, consider creating diagrams in addition to your text-based communication
10 |   (depending on the options for text, html, mermaid diagrams, etc. that you are provided with in your initial instructions).
11 | excluded_tools: []
12 | included_optional_tools:
13 |   - switch_modes
14 | 
15 | tool_description_overrides: {}
16 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/swift/test_repo/src/main.swift:
--------------------------------------------------------------------------------

```swift
 1 | import Foundation
 2 | 
 3 | // Main entry point
 4 | func main() {
 5 |     let calculator = Calculator()
 6 |     let result = calculator.add(5, 3)
 7 |     print("Result: \(result)")
 8 |     
 9 |     let user = User(name: "Alice", age: 30)
10 |     user.greet()
11 |     
12 |     let area = Utils.calculateArea(radius: 5.0)
13 |     print("Circle area: \(area)")
14 | }
15 | 
16 | class Calculator {
17 |     func add(_ a: Int, _ b: Int) -> Int {
18 |         return a + b
19 |     }
20 |     
21 |     func multiply(_ a: Int, _ b: Int) -> Int {
22 |         return a * b
23 |     }
24 | }
25 | 
26 | struct User {
27 |     let name: String
28 |     let age: Int
29 |     
30 |     func greet() {
31 |         print("Hello, my name is \(name) and I am \(age) years old.")
32 |     }
33 |     
34 |     func isAdult() -> Bool {
35 |         return age >= 18
36 |     }
37 | }
38 | 
39 | enum Status {
40 |     case active
41 |     case inactive
42 |     case pending
43 | }
44 | 
45 | protocol Drawable {
46 |     func draw()
47 | }
48 | 
49 | class Circle: Drawable {
50 |     let radius: Double
51 |     
52 |     init(radius: Double) {
53 |         self.radius = radius
54 |     }
55 |     
56 |     func draw() {
57 |         print("Drawing a circle with radius \(radius)")
58 |     }
59 | }
60 | 
61 | // Call main
62 | main()
```

--------------------------------------------------------------------------------
/docs/01-about/000_intro.md:
--------------------------------------------------------------------------------

```markdown
 1 | # About Serena
 2 | 
 3 | * Serena is a powerful **coding agent toolkit** capable of turning an LLM into a fully-featured agent that works
 4 |   **directly on your codebase**.
 5 |   Unlike most other tools, it is not tied to an LLM, framework or an interface, making it easy to use it in a variety of ways.
 6 | * Serena provides essential **semantic code retrieval and editing tools** that are akin to an IDE's capabilities,
 7 |   extracting code entities at the symbol level and exploiting relational structure.
 8 |   When combined with an existing coding agent, these tools greatly enhance (token) efficiency.
 9 | * Serena is **free & open-source**, enhancing the capabilities of LLMs you already have access to free of charge.
10 | 
11 | Therefore, you can think of Serena as providing IDE-like tools to your LLM/coding agent.
12 | With it, the agent no longer needs to read entire files, perform grep-like searches or string replacements to find and
13 | edit the right code.
14 | Instead, it can use code-centred tools like `find_symbol`, `find_referencing_symbols` and `insert_after_symbol`.
15 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/markdown/test_repo/guide.md:
--------------------------------------------------------------------------------

```markdown
 1 | # User Guide
 2 | 
 3 | This guide provides detailed instructions for using the test repository.
 4 | 
 5 | ## Getting Started
 6 | 
 7 | Welcome to the user guide. This document covers:
 8 | 
 9 | - Basic concepts
10 | - Advanced features
11 | - Troubleshooting
12 | 
13 | ### Basic Concepts
14 | 
15 | The fundamental concepts you need to understand:
16 | 
17 | #### Headers and Structure
18 | 
19 | Markdown documents use headers to create structure. Headers are created using `#` symbols.
20 | 
21 | #### Links and References
22 | 
23 | Internal links can reference other documents:
24 | 
25 | - [Back to README](README.md)
26 | - [See API documentation](api.md)
27 | 
28 | ### Advanced Features
29 | 
30 | For advanced users, we provide:
31 | 
32 | 1. Custom extensions
33 | 2. Plugin support
34 | 3. Theme customization
35 | 
36 | ## Configuration
37 | 
38 | Configuration options are stored in `config.yaml`:
39 | 
40 | ```yaml
41 | server:
42 |   port: 8080
43 |   host: localhost
44 | ```
45 | 
46 | ## Troubleshooting
47 | 
48 | If you encounter issues:
49 | 
50 | 1. Check the [README](README.md) first
51 | 2. Review [common issues](CONTRIBUTING.md)
52 | 3. Contact support
53 | 
54 | ## Next Steps
55 | 
56 | After reading this guide, check out:
57 | 
58 | - [API Reference](api.md)
59 | - [Contributing Guidelines](CONTRIBUTING.md)
60 | 
```

--------------------------------------------------------------------------------
/docs/01-about/030_serena-in-action.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Serena in Action
 2 | 
 3 | ## Demonstration 1: Efficient Operation in Claude Code
 4 | 
 5 | 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.
 6 | 
 7 | <video src="https://github.com/user-attachments/assets/ab78ebe0-f77d-43cc-879a-cc399efefd87"
 8 | controls
 9 | preload="metadata"
10 | style="max-width: 100%; height: auto;">
11 | Your browser does not support the video tag.
12 | </video>
13 | 
14 | ## Demonstration 2: Serena in Claude Desktop
15 | 
16 | A demonstration of Serena implementing a small feature for itself (a better log GUI) with Claude Desktop.
17 | Note how Serena's tools enable Claude to find and edit the right symbols.
18 | 
19 | <video src="https://github.com/user-attachments/assets/6eaa9aa1-610d-4723-a2d6-bf1e487ba753"
20 | controls
21 | preload="metadata"
22 | style="max-width: 100%; height: auto;">
23 | Your browser does not support the video tag.
24 | </video>
25 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/java/test_repo/pom.xml:
--------------------------------------------------------------------------------

```
 1 | <project xmlns="http://maven.apache.org/POM/4.0.0"
 2 |          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3 |          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 4 |     <modelVersion>4.0.0</modelVersion>
 5 |     <groupId>org.example</groupId>
 6 |     <artifactId>test_repo</artifactId>
 7 |     <version>1.0-SNAPSHOT</version>
 8 |     <packaging>jar</packaging>
 9 |     <name>Java Test Repo</name>
10 |     <properties>
11 |         <maven.compiler.source>21</maven.compiler.source>
12 |         <maven.compiler.target>21</maven.compiler.target>
13 |         <maven.compiler.plugin.version>3.13.0</maven.compiler.plugin.version>
14 |     </properties>
15 |     
16 |     <build>
17 |         <plugins>
18 |             <plugin>
19 |                 <groupId>org.apache.maven.plugins</groupId>
20 |                 <artifactId>maven-compiler-plugin</artifactId>
21 |                 <version>${maven.compiler.plugin.version}</version>
22 |                 <configuration>
23 |                     <source>21</source>
24 |                     <target>21</target>
25 |                 </configuration>
26 |             </plugin>
27 |         </plugins>
28 |     </build>
29 | </project>
30 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/markdown/test_repo/api.md:
--------------------------------------------------------------------------------

```markdown
 1 | # API Reference
 2 | 
 3 | Complete API documentation for the test repository.
 4 | 
 5 | ## Classes
 6 | 
 7 | ### Client
 8 | 
 9 | The main client class for interacting with the API.
10 | 
11 | #### Methods
12 | 
13 | ##### `connect()`
14 | 
15 | Establishes a connection to the server.
16 | 
17 | **Parameters:**
18 | - `host`: Server hostname
19 | - `port`: Server port number
20 | 
21 | **Returns:** Connection object
22 | 
23 | ##### `disconnect()`
24 | 
25 | Closes the connection to the server.
26 | 
27 | **Returns:** None
28 | 
29 | ### Server
30 | 
31 | Server-side implementation.
32 | 
33 | #### Configuration
34 | 
35 | ```json
36 | {
37 |   "host": "localhost",
38 |   "port": 8080,
39 |   "timeout": 30
40 | }
41 | ```
42 | 
43 | ## Functions
44 | 
45 | ### `initialize(config)`
46 | 
47 | Initializes the system with the provided configuration.
48 | 
49 | **Parameters:**
50 | - `config`: Configuration dictionary
51 | 
52 | **Example:**
53 | 
54 | ```python
55 | config = {
56 |     "host": "localhost",
57 |     "port": 8080
58 | }
59 | initialize(config)
60 | ```
61 | 
62 | ### `shutdown()`
63 | 
64 | Gracefully shuts down the system.
65 | 
66 | ## Error Handling
67 | 
68 | Common errors and their solutions:
69 | 
70 | - `ConnectionError`: Check network connectivity
71 | - `TimeoutError`: Increase timeout value
72 | - `ConfigError`: Validate configuration file
73 | 
74 | ## See Also
75 | 
76 | - [User Guide](guide.md)
77 | - [README](README.md)
78 | - [Contributing](CONTRIBUTING.md)
79 | 
```

--------------------------------------------------------------------------------
/src/serena/resources/config/contexts/context.template.yml:
--------------------------------------------------------------------------------

```yaml
 1 | # See Serena's documentation for more details on concept of contexts.
 2 | description: Description of the context, not used in the code.
 3 | prompt: Prompt that will form part of the system prompt/initial instructions for agents started in this context.
 4 | excluded_tools: []
 5 | 
 6 | # several tools are excluded by default and have to be explicitly included by the user
 7 | included_optional_tools: []
 8 | 
 9 | # mapping of tool names to an override of their descriptions (the default description is the docstring of the Tool's apply method).
10 | # Sometimes, tool descriptions are too long (e.g., for ChatGPT), or users may want to override them for another reason.
11 | tool_description_overrides: {}
12 | 
13 | # whether to assume that Serena shall only work on a single project in this context (provided that a project is given
14 | # when Serena is started).
15 | # If set to true and a project is provided at startup, the set of tools is limited to those required by the project's
16 | # concrete configuration, and other tools are excluded completely, allowing the set of tools to be minimal.
17 | # The `activate_project` tool will, therefore, be disabled in this case, as project switching is not allowed.
18 | single_project: false
```

--------------------------------------------------------------------------------
/test/resources/repos/toml/test_repo/config.toml:
--------------------------------------------------------------------------------

```toml
 1 | # Configuration file with various TOML features for testing
 2 | 
 3 | [server]
 4 | host = "localhost"
 5 | port = 8080
 6 | debug = false
 7 | timeout = 30.5
 8 | 
 9 | # Inline table example
10 | endpoint = { url = "https://api.example.com", version = "v1" }
11 | 
12 | [server.ssl]
13 | enabled = true
14 | cert_path = "/etc/ssl/cert.pem"
15 | key_path = "/etc/ssl/key.pem"
16 | 
17 | [database]
18 | connection_string = """
19 |     postgresql://user:password@localhost:5432/mydb?
20 |     sslmode=require&
21 |     pool_size=10
22 | """
23 | 
24 | [database.pool]
25 | min_connections = 5
26 | max_connections = 20
27 | idle_timeout = 300
28 | 
29 | [logging]
30 | level = "info"
31 | format = "json"
32 | outputs = ["stdout", "file"]
33 | 
34 | [logging.file]
35 | path = "/var/log/app.log"
36 | max_size = 10485760  # 10MB
37 | max_backups = 5
38 | compress = true
39 | 
40 | # Array of inline tables
41 | [[endpoints]]
42 | name = "users"
43 | path = "/api/users"
44 | methods = ["GET", "POST", "PUT", "DELETE"]
45 | auth_required = true
46 | 
47 | [[endpoints]]
48 | name = "health"
49 | path = "/health"
50 | methods = ["GET"]
51 | auth_required = false
52 | 
53 | # Datetime values
54 | [metadata]
55 | created = 1979-05-27T07:32:00Z
56 | updated = 2024-01-15T10:30:00-05:00
57 | 
58 | # Special characters in strings
59 | [messages]
60 | welcome = "Hello, World!"
61 | multiline = '''
62 | This is a
63 | multiline literal
64 | string.
65 | '''
66 | with_escapes = "Line1\nLine2\tTabbed"
67 | 
```

--------------------------------------------------------------------------------
/docs/01-about/010_llm-integration.md:
--------------------------------------------------------------------------------

```markdown
 1 | # LLM Integration
 2 | 
 3 | Serena provides the necessary [tools](035_tools) for coding workflows, but an LLM is required to do the actual work,
 4 | orchestrating tool use.
 5 | 
 6 | In general, Serena can be integrated with an LLM in several ways:
 7 | 
 8 | * by using the **model context protocol (MCP)**.
 9 |   Serena provides an MCP server which integrates with
10 |     * Claude Code and Claude Desktop,
11 |     * Terminal-based clients like Codex, Gemini-CLI, Qwen3-Coder, rovodev, OpenHands CLI and others,
12 |     * IDEs like VSCode, Cursor or IntelliJ,
13 |     * Extensions like Cline or Roo Code
14 |     * Local clients like [OpenWebUI](https://docs.openwebui.com/openapi-servers/mcp), [Jan](https://jan.ai/docs/mcp-examples/browser/browserbase#enable-mcp), [Agno](https://docs.agno.com/introduction/playground) and others
15 | * by using [mcpo to connect it to ChatGPT](../03-special-guides/serena_on_chatgpt.md) or other clients that don't support MCP but do support tool calling via OpenAPI.
16 | * by incorporating Serena's tools into an agent framework of your choice, as illustrated [here](../03-special-guides/custom_agent).
17 |   Serena's tool implementation is decoupled from the framework-specific code and can thus easily be adapted to any agent framework.
18 | 
```

--------------------------------------------------------------------------------
/.github/workflows/docs.yaml:
--------------------------------------------------------------------------------

```yaml
 1 | name: Docs Build
 2 | 
 3 | on:
 4 |   push:
 5 |     branches: [ main ]
 6 |   workflow_dispatch:
 7 | 
 8 | permissions:
 9 |   contents: read
10 |   pages: write
11 |   id-token: write
12 | 
13 | concurrency:
14 |   group: "pages"
15 |   cancel-in-progress: true
16 | 
17 | jobs:
18 |   build:
19 |     runs-on: ubuntu-latest
20 |     timeout-minutes: 10
21 | 
22 |     steps:
23 |       - name: Checkout
24 |         uses: actions/checkout@v4
25 | 
26 |       - name: Set up Python
27 |         uses: actions/setup-python@v5
28 |         with:
29 |           python-version: 3.11
30 | 
31 |       - name: Install uv
32 |         run: pip install uv
33 | 
34 |       - name: Cache dependencies
35 |         uses: actions/cache@v4
36 |         with:
37 |           path: ~/.cache/uv
38 |           key: uv-${{ hashFiles('pyproject.toml') }}
39 | 
40 |       - name: Install dependencies
41 |         run: |
42 |           uv venv
43 |           uv pip install -e ".[dev]"
44 | 
45 |       - name: Build docs
46 |         run: uv run poe doc-build
47 |         continue-on-error: false
48 | 
49 |       - name: Upload Pages artifact
50 |         uses: actions/upload-pages-artifact@v3
51 |         with:
52 |           path: docs/_build
53 | 
54 |   deploy:
55 |     environment:
56 |       name: github-pages
57 |       url: ${{ steps.deployment.outputs.page_url }}
58 |     runs-on: ubuntu-latest
59 |     needs: build
60 |     steps:
61 |       - name: Deploy to GitHub Pages
62 |         id: deployment
63 |         uses: actions/deploy-pages@v4
64 | 
```

--------------------------------------------------------------------------------
/test/solidlsp/erlang/__init__.py:
--------------------------------------------------------------------------------

```python
 1 | import platform
 2 | 
 3 | 
 4 | def _test_erlang_ls_available() -> str:
 5 |     """Test if Erlang LS is available and return error reason if not."""
 6 |     # Check if we're on Windows (Erlang LS doesn't support Windows)
 7 |     if platform.system() == "Windows":
 8 |         return "Erlang LS does not support Windows"
 9 | 
10 |     # Try to import and check Erlang availability
11 |     try:
12 |         from solidlsp.language_servers.erlang_language_server import ErlangLanguageServer
13 | 
14 |         # Check if Erlang/OTP is installed
15 |         erlang_version = ErlangLanguageServer._get_erlang_version()
16 |         if not erlang_version:
17 |             return "Erlang/OTP is not installed or not in PATH"
18 | 
19 |         # Check if rebar3 is available (commonly used build tool)
20 |         rebar3_available = ErlangLanguageServer._check_rebar3_available()
21 |         if not rebar3_available:
22 |             return "rebar3 is not installed or not in PATH (required for project compilation)"
23 | 
24 |         return ""  # No error, Erlang LS should be available
25 | 
26 |     except ImportError as e:
27 |         return f"Failed to import ErlangLanguageServer: {e}"
28 |     except Exception as e:
29 |         return f"Error checking Erlang LS availability: {e}"
30 | 
31 | 
32 | ERLANG_LS_UNAVAILABLE_REASON = _test_erlang_ls_available()
33 | ERLANG_LS_UNAVAILABLE = bool(ERLANG_LS_UNAVAILABLE_REASON)
34 | 
```

--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/issue--bug--performance-problem--question-.md:
--------------------------------------------------------------------------------

```markdown
 1 | ---
 2 | name: Issue (bug, performance problem, question)
 3 | about: General Issue
 4 | title: ''
 5 | labels: ''
 6 | assignees: ''
 7 | 
 8 | ---
 9 | 
10 | I have:
11 | 
12 | - [ ] Read the readme and verified that the issue cannot be solved by adjusting configuration
13 | - [ ] Understood that Serena's dashboard can be disabled through the config
14 | - [ ] Understood that by default a client session will start a separate instance of a Serena server. 
15 | - [ ] Understood that for multi-agent setups, the SSE mode should be used.
16 | - [ ] Verified that non-project files are ignored using either gitignore or the corresponding setting in `.serena/project.yml`
17 | - [ ] Have looked for similar issues and discussions, including closed ones
18 | - [ ] Made sure it's an actual issue and not a question - those should be opened as discussion instead.
19 | 
20 | If you have encountered a real and new issue:
21 | 
22 | - [ ] I performed `<uv invocation> serena project health-check`
23 | - [ ] I indexed the project as described in the readme
24 | - [ ] Added sufficient explanation of my setup: the MCP client, the OS, the programming language, any config adjustments or relevant project specifics
25 | - [ ] Explained how the issue arose, added instructions on how to reproduce it (if possible)
26 | - [ ] If the issue happens on an open source project, I have added the link
27 | - [ ] Wrote a meaningful title and description
28 | 
```

--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------

```yaml
 1 | name: Publish Python Package
 2 | 
 3 | on:
 4 |   release:
 5 |     types: [created]
 6 | 
 7 |   workflow_dispatch:
 8 |     inputs:
 9 |       tag:
10 |         description: 'Tag name for the release (e.g., v0.1.0)'
11 |         required: true
12 |         default: 'v0.1.0'
13 | 
14 | env:
15 |   # Set this to true manually in the GitHub workflow UI if you want to publish to PyPI
16 |   # Will always publish to testpypi
17 |   PUBLISH_TO_PYPI: true
18 | 
19 | jobs:
20 |   publish:
21 |     name: Publish the serena-agent package
22 |     runs-on: ubuntu-latest
23 | 
24 |     permissions:
25 |       id-token: write  # Required for trusted publishing
26 |       contents: write  # Required for updating artifact
27 | 
28 |     steps:
29 |       - name: Checkout code
30 |         uses: actions/checkout@v4
31 | 
32 |       - name: Install the latest version of uv
33 |         uses: astral-sh/setup-uv@v6
34 |         with:
35 |           version: "latest"
36 | 
37 |       - name: Build package
38 |         run: uv build
39 | 
40 |       - name: Upload artifacts to GitHub Release
41 |         if: env.PUBLISH_TO_PYPI == 'true'
42 |         uses: softprops/action-gh-release@v2
43 |         with:
44 |           tag_name: ${{ github.event.inputs.tag || github.ref_name }}
45 |           files: |
46 |             dist/*.tar.gz
47 |             dist/*.whl
48 | 
49 |       - name: Publish to TestPyPI
50 |         run: uv publish --index testpypi
51 | 
52 |       - name: Publish to PyPI (conditional)
53 |         if: env.PUBLISH_TO_PYPI == 'true'
54 |         run: uv publish
55 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/ruby/test_repo/models.rb:
--------------------------------------------------------------------------------

```ruby
 1 | class User
 2 |   attr_accessor :id, :name, :email
 3 | 
 4 |   def initialize(id, name, email = nil)
 5 |     @id = id
 6 |     @name = name
 7 |     @email = email
 8 |   end
 9 | 
10 |   def full_info
11 |     info = "User: #{@name} (ID: #{@id})"
12 |     info += ", Email: #{@email}" if @email
13 |     info
14 |   end
15 | 
16 |   def to_hash
17 |     {
18 |       id: @id,
19 |       name: @name,
20 |       email: @email
21 |     }
22 |   end
23 | 
24 |   def self.from_hash(hash)
25 |     new(hash[:id], hash[:name], hash[:email])
26 |   end
27 | 
28 |   class << self
29 |     def default_user
30 |       new(0, "Guest")
31 |     end
32 |   end
33 | end
34 | 
35 | class Item
36 |   attr_reader :id, :name, :price
37 | 
38 |   def initialize(id, name, price)
39 |     @id = id
40 |     @name = name
41 |     @price = price
42 |   end
43 | 
44 |   def discounted_price(discount_percent)
45 |     @price * (1 - discount_percent / 100.0)
46 |   end
47 | 
48 |   def description
49 |     "#{@name}: $#{@price}"
50 |   end
51 | end
52 | 
53 | module ItemHelpers
54 |   def format_price(price)
55 |     "$#{sprintf('%.2f', price)}"
56 |   end
57 | 
58 |   def calculate_tax(price, tax_rate = 0.08)
59 |     price * tax_rate
60 |   end
61 | end
62 | 
63 | class Order
64 |   include ItemHelpers
65 | 
66 |   def initialize
67 |     @items = []
68 |     @total = 0
69 |   end
70 | 
71 |   def add_item(item, quantity = 1)
72 |     @items << { item: item, quantity: quantity }
73 |     calculate_total
74 |   end
75 | 
76 |   def total_with_tax
77 |     tax = calculate_tax(@total)
78 |     @total + tax
79 |   end
80 | 
81 |   private
82 | 
83 |   def calculate_total
84 |     @total = @items.sum { |entry| entry[:item].price * entry[:quantity] }
85 |   end
86 | end
```

--------------------------------------------------------------------------------
/.serena/memories/suggested_commands.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Suggested Commands
 2 | 
 3 | ## Development Tasks (using uv and poe)
 4 | 
 5 | The following tasks should generally be executed using `uv run poe <task_name>`.
 6 | 
 7 | - `format`: This is the **only** allowed command for formatting. Run as `uv run poe format`.
 8 | - `type-check`: This is the **only** allowed command for type checking. Run as `uv run poe type-check`.
 9 | - `test`: This is the preferred command for running tests (`uv run poe test [args]`). You can select subsets of tests with markers,
10 |    the current markers are
11 |    ```toml
12 |     markers = [
13 |         "python: language server running for Python",
14 |         "go: language server running for Go",
15 |         "java: language server running for Java",
16 |         "rust: language server running for Rust",
17 |         "typescript: language server running for TypeScript",
18 |         "php: language server running for PHP",
19 |         "snapshot: snapshot tests for symbolic editing operations",
20 |     ]
21 |    ```
22 |   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"`.
23 |   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"`.
24 | 
25 | For finishing a task, make sure format, type-check and test pass! Run them at the end of the task
26 | and if needed fix any issues that come up and run them again until they pass.
```

--------------------------------------------------------------------------------
/src/serena/generated/generated_prompt_factory.py:
--------------------------------------------------------------------------------

```python
 1 | # ruff: noqa
 2 | # black: skip
 3 | # mypy: ignore-errors
 4 | 
 5 | # NOTE: This module is auto-generated from interprompt.autogenerate_prompt_factory_module, do not edit manually!
 6 | 
 7 | from interprompt.multilang_prompt import PromptList
 8 | from interprompt.prompt_factory import PromptFactoryBase
 9 | from typing import Any
10 | 
11 | 
12 | class PromptFactory(PromptFactoryBase):
13 |     """
14 |     A class for retrieving and rendering prompt templates and prompt lists.
15 |     """
16 | 
17 |     def create_onboarding_prompt(self, *, system: Any) -> str:
18 |         return self._render_prompt("onboarding_prompt", locals())
19 | 
20 |     def create_think_about_collected_information(self) -> str:
21 |         return self._render_prompt("think_about_collected_information", locals())
22 | 
23 |     def create_think_about_task_adherence(self) -> str:
24 |         return self._render_prompt("think_about_task_adherence", locals())
25 | 
26 |     def create_think_about_whether_you_are_done(self) -> str:
27 |         return self._render_prompt("think_about_whether_you_are_done", locals())
28 | 
29 |     def create_summarize_changes(self) -> str:
30 |         return self._render_prompt("summarize_changes", locals())
31 | 
32 |     def create_prepare_for_new_conversation(self) -> str:
33 |         return self._render_prompt("prepare_for_new_conversation", locals())
34 | 
35 |     def create_system_prompt(
36 |         self, *, available_markers: Any, available_tools: Any, context_system_prompt: Any, mode_system_prompts: Any
37 |     ) -> str:
38 |         return self._render_prompt("system_prompt", locals())
39 | 
```

--------------------------------------------------------------------------------
/.github/workflows/docker.yml:
--------------------------------------------------------------------------------

```yaml
 1 | name: Build and Push Docker Images
 2 | 
 3 | on:
 4 |   push:
 5 |     branches: [ main ]
 6 |     tags: [ 'v*' ]
 7 | 
 8 | env:
 9 |   REGISTRY: ghcr.io
10 |   IMAGE_NAME: ${{ github.repository }}
11 | 
12 | jobs:
13 |   build-and-push:
14 |     runs-on: ubuntu-latest
15 |     timeout-minutes: 15
16 |     permissions:
17 |       contents: read
18 |       packages: write
19 | 
20 |     steps:
21 |     - name: Checkout repository
22 |       uses: actions/checkout@v4
23 | 
24 |     - name: Set up Docker Buildx
25 |       uses: docker/setup-buildx-action@v3
26 | 
27 |     - name: Log in to Container Registry
28 |       if: github.event_name != 'pull_request'
29 |       uses: docker/login-action@v3
30 |       with:
31 |         registry: ${{ env.REGISTRY }}
32 |         username: ${{ github.actor }}
33 |         password: ${{ secrets.GITHUB_TOKEN }}
34 | 
35 |     - name: Extract metadata
36 |       id: meta
37 |       uses: docker/metadata-action@v5
38 |       with:
39 |         images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
40 |         tags: |
41 |           type=ref,event=branch
42 |           type=ref,event=pr
43 |           type=semver,pattern={{version}}
44 |           type=semver,pattern={{major}}.{{minor}}
45 |           type=raw,value=latest,enable={{is_default_branch}}
46 | 
47 |     - name: Build and push image from main
48 |       uses: docker/build-push-action@v5
49 |       with:
50 |         context: .
51 |         platforms: linux/amd64,linux/arm64
52 |         push: ${{ github.event_name != 'pull_request' }}
53 |         tags: ${{ steps.meta.outputs.tags }}
54 |         labels: ${{ steps.meta.outputs.labels }}
55 |         cache-from: type=gha
56 |         cache-to: type=gha,mode=max
57 | 
```

--------------------------------------------------------------------------------
/src/serena/resources/config/contexts/ide.yml:
--------------------------------------------------------------------------------

```yaml
 1 | description: Generic IDE coding agent context (basic file operations and shell operations assumed to be covered; single project mode)
 2 | prompt: |
 3 |   You are running in an IDE assistant context where file operations, basic (line-based) edits and reads, 
 4 |   and shell commands are handled by your own, internal tools.
 5 |   
 6 |   If Serena's tools can be used to achieve your task, you should prioritize them.
 7 |   In particular, it is important that you avoid reading entire source code files unless it is strictly necessary!
 8 |   Instead, for exploring and reading code in a token-efficient manner, use Serena's overview and symbolic search tools.
 9 |   For non-code files or for reads where you don't know the symbol's name path, you can use the pattern search tool.
10 | 
11 | excluded_tools:
12 |   - create_text_file
13 |   - read_file
14 |   - execute_shell_command
15 |   - prepare_for_new_conversation
16 | 
17 | tool_description_overrides: {}
18 | 
19 | # whether to assume that Serena shall only work on a single project in this context (provided that a project is given
20 | # when Serena is started).
21 | # If set to true and a project is provided at startup, the set of tools is limited to those required by the project's
22 | # concrete configuration, and other tools are excluded completely, allowing the set of tools to be minimal.
23 | # Tools explicitly disabled by the project will not be available at all.
24 | # The `activate_project` tool is always disabled in this case, as project switching cannot be allowed.
25 | single_project: true
26 | 
```

--------------------------------------------------------------------------------
/test/resources/repos/bash/test_repo/main.sh:
--------------------------------------------------------------------------------

```bash
 1 | #!/bin/bash
 2 | 
 3 | # Main script demonstrating various bash features
 4 | 
 5 | # Global variables
 6 | readonly SCRIPT_NAME="Main Script"
 7 | COUNTER=0
 8 | declare -a ITEMS=("item1" "item2" "item3")
 9 | 
10 | # Function definitions
11 | function greet_user() {
12 |     local username="$1"
13 |     local greeting_type="${2:-default}"
14 |     
15 |     case "$greeting_type" in
16 |         "formal")
17 |             echo "Good day, ${username}!"
18 |             ;;
19 |         "casual")
20 |             echo "Hey ${username}!"
21 |             ;;
22 |         *)
23 |             echo "Hello, ${username}!"
24 |             ;;
25 |     esac
26 | }
27 | 
28 | function process_items() {
29 |     local -n items_ref=$1
30 |     local operation="$2"
31 |     
32 |     for item in "${items_ref[@]}"; do
33 |         case "$operation" in
34 |             "count")
35 |                 ((COUNTER++))
36 |                 echo "Processing item $COUNTER: $item"
37 |                 ;;
38 |             "uppercase")
39 |                 echo "${item^^}"
40 |                 ;;
41 |             *)
42 |                 echo "Unknown operation: $operation"
43 |                 return 1
44 |                 ;;
45 |         esac
46 |     done
47 | }
48 | 
49 | # Main execution
50 | main() {
51 |     echo "Starting $SCRIPT_NAME"
52 |     
53 |     if [[ $# -eq 0 ]]; then
54 |         echo "Usage: $0 <username> [greeting_type]"
55 |         exit 1
56 |     fi
57 |     
58 |     local user="$1"
59 |     local greeting="${2:-default}"
60 |     
61 |     greet_user "$user" "$greeting"
62 |     
63 |     echo "Processing items..."
64 |     process_items ITEMS "count"
65 |     
66 |     echo "Script completed successfully"
67 | }
68 | 
69 | # Run main function with all arguments
70 | main "$@"
71 | 
```

--------------------------------------------------------------------------------
/src/serena/resources/config/contexts/claude-code.yml:
--------------------------------------------------------------------------------

```yaml
 1 | description: Claude Code (CLI agent where file operations, basic edits, etc. are already covered; single project mode)
 2 | prompt: |
 3 |   You are running in a CLI coding agent context where file operations, basic (line-based) edits and reads 
 4 |   as well as shell commands are handled by your own, internal tools.
 5 |   
 6 |   If Serena's tools can be used to achieve your task, you should prioritize them.
 7 |   In particular, it is important that you avoid reading entire source code files unless it is strictly necessary!
 8 |   Instead, for exploring and reading code in a token-efficient manner, use Serena's overview and symbolic search tools.
 9 |   For non-code files or for reads where you don't know the symbol's name path, you can use the pattern search tool.
10 | 
11 | excluded_tools:
12 |   - create_text_file
13 |   - read_file
14 |   - execute_shell_command
15 |   - prepare_for_new_conversation
16 |   - replace_content
17 | 
18 | tool_description_overrides: {}
19 | 
20 | # whether to assume that Serena shall only work on a single project in this context (provided that a project is given
21 | # when Serena is started).
22 | # If set to true and a project is provided at startup, the set of tools is limited to those required by the project's
23 | # concrete configuration, and other tools are excluded completely, allowing the set of tools to be minimal.
24 | # Tools explicitly disabled by the project will not be available at all.
25 | # The `activate_project` tool is always disabled in this case, as project switching cannot be allowed.
26 | single_project: true
27 | 
```

--------------------------------------------------------------------------------
/src/interprompt/jinja_template.py:
--------------------------------------------------------------------------------

```python
 1 | from typing import Any
 2 | 
 3 | import jinja2
 4 | import jinja2.meta
 5 | import jinja2.nodes
 6 | import jinja2.visitor
 7 | 
 8 | from interprompt.util.class_decorators import singleton
 9 | 
10 | 
11 | class ParameterizedTemplateInterface:
12 |     def get_parameters(self) -> list[str]: ...
13 | 
14 | 
15 | @singleton
16 | class _JinjaEnvProvider:
17 |     def __init__(self) -> None:
18 |         self._env: jinja2.Environment | None = None
19 | 
20 |     def get_env(self) -> jinja2.Environment:
21 |         if self._env is None:
22 |             self._env = jinja2.Environment()
23 |         return self._env
24 | 
25 | 
26 | class JinjaTemplate(ParameterizedTemplateInterface):
27 |     def __init__(self, template_string: str) -> None:
28 |         self._template_string = template_string
29 |         self._template = _JinjaEnvProvider().get_env().from_string(self._template_string)
30 |         parsed_content = self._template.environment.parse(self._template_string)
31 |         self._parameters = sorted(jinja2.meta.find_undeclared_variables(parsed_content))
32 | 
33 |     def render(self, **params: Any) -> str:
34 |         """Renders the template with the given kwargs. You can find out which parameters are required by calling get_parameter_names()."""
35 |         return self._template.render(**params)
36 | 
37 |     def get_parameters(self) -> list[str]:
38 |         """A sorted list of parameter names that are extracted from the template string. It is impossible to know the types of the parameter
39 |         values, they can be primitives, dicts or dict-like objects.
40 | 
41 |         :return: the list of parameter names
42 |         """
43 |         return self._parameters
44 | 
```

--------------------------------------------------------------------------------
/test/serena/test_tool_parameter_types.py:
--------------------------------------------------------------------------------

```python
 1 | import logging
 2 | 
 3 | import pytest
 4 | 
 5 | from serena.config.serena_config import SerenaConfig
 6 | from serena.mcp import SerenaMCPFactory
 7 | from serena.tools.tools_base import ToolRegistry
 8 | 
 9 | 
10 | @pytest.mark.parametrize("context", ("chatgpt", "codex", "oaicompat-agent"))
11 | def test_all_tool_parameters_have_type(context):
12 |     """
13 |     For every tool exposed by Serena, ensure that the generated
14 |     Open‑AI schema contains a ``type`` entry for each parameter.
15 |     """
16 |     cfg = SerenaConfig(gui_log_window_enabled=False, web_dashboard=False, log_level=logging.ERROR)
17 |     registry = ToolRegistry()
18 |     cfg.included_optional_tools = tuple(registry.get_tool_names_optional())
19 |     factory = SerenaMCPFactory(context=context)
20 |     # Initialize the agent so that the tools are available
21 |     factory.agent = factory._create_serena_agent(cfg, [])
22 |     tools = list(factory._iter_tools())
23 | 
24 |     for tool in tools:
25 |         mcp_tool = factory.make_mcp_tool(tool, openai_tool_compatible=True)
26 |         params = mcp_tool.parameters
27 | 
28 |         # Collect any parameter that lacks a type
29 |         issues = []
30 |         print(f"Checking tool {tool}")
31 | 
32 |         if "properties" not in params:
33 |             issues.append(f"Tool {tool.get_name()!r} missing properties section")
34 |         else:
35 |             for pname, prop in params["properties"].items():
36 |                 if "type" not in prop:
37 |                     issues.append(f"Tool {tool.get_name()!r} parameter {pname!r} missing 'type'")
38 |         if issues:
39 |             raise AssertionError("\n".join(issues))
40 | 
```

--------------------------------------------------------------------------------
/llms-install.md:
--------------------------------------------------------------------------------

```markdown
 1 | # MCP Installation instructions
 2 | 
 3 | This document is mainly used as instructions for AI-assistants like Cline and others that
 4 | try to do an automatic install based on freeform instructions.
 5 | 
 6 | 0. Make sure `uv` is installed. If not, install it using either `curl -LsSf https://astral.sh/uv/install.sh | sh` (macOS, Linux) or
 7 |    `powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"` (Windows). Find the path to the `uv` executable,
 8 |    you'll need it later.
 9 | 1. Clone the repo with `git clone [email protected]:oraios/serena.git` and change into its dir (e.g., `cd serena`)
10 | 2. Check if `serena_config.yml` exists. If not, create it  with `cp serena_config.template.yml serena_config.yml`. Read the instructions in the config.
11 | 3. In the config, check if the path to your project was added. If not, add it to the `projects` section
12 | 4. In your project, create a `.serena` if needed and check whether `project.yml` exists there.
13 | 5. If no `project.yml` was found, create it using `cp /path/to/serena/myproject.template.yml /path/to/your/project/.serena/project.yml`
14 | 6. Read the instructions in `project.yml`. Make sure the `project.yml` has the correct project language configured. 
15 |    Remove the  project_root entry there.
16 | 7. Finally, add the Serena MCP server config like this:
17 | 
18 | ```json
19 |    {
20 |        "mcpServers": {
21 |             ...
22 |            "serena": {
23 |                "command": "/abs/path/to/uv",
24 |                "args": ["run", "--directory", "/abs/path/to/serena", "serena-mcp-server", "/path/to/your/project/.serena/project.yml"]
25 |            }
26 |        }
27 |    }
28 | 
29 | ```
30 | 
```

--------------------------------------------------------------------------------
/src/serena/util/shell.py:
--------------------------------------------------------------------------------

```python
 1 | import os
 2 | import subprocess
 3 | 
 4 | from pydantic import BaseModel
 5 | 
 6 | from solidlsp.util.subprocess_util import subprocess_kwargs
 7 | 
 8 | 
 9 | class ShellCommandResult(BaseModel):
10 |     stdout: str
11 |     return_code: int
12 |     cwd: str
13 |     stderr: str | None = None
14 | 
15 | 
16 | def execute_shell_command(command: str, cwd: str | None = None, capture_stderr: bool = False) -> ShellCommandResult:
17 |     """
18 |     Execute a shell command and return the output.
19 | 
20 |     :param command: The command to execute.
21 |     :param cwd: The working directory to execute the command in. If None, the current working directory will be used.
22 |     :param capture_stderr: Whether to capture the stderr output.
23 |     :return: The output of the command.
24 |     """
25 |     if cwd is None:
26 |         cwd = os.getcwd()
27 | 
28 |     process = subprocess.Popen(
29 |         command,
30 |         shell=True,
31 |         stdin=subprocess.DEVNULL,
32 |         stdout=subprocess.PIPE,
33 |         stderr=subprocess.PIPE if capture_stderr else None,
34 |         text=True,
35 |         encoding="utf-8",
36 |         errors="replace",
37 |         cwd=cwd,
38 |         **subprocess_kwargs(),
39 |     )
40 | 
41 |     stdout, stderr = process.communicate()
42 |     return ShellCommandResult(stdout=stdout, stderr=stderr, return_code=process.returncode, cwd=cwd)
43 | 
44 | 
45 | def subprocess_check_output(args: list[str], encoding: str = "utf-8", strip: bool = True, timeout: float | None = None) -> str:
46 |     output = subprocess.check_output(args, stdin=subprocess.DEVNULL, stderr=subprocess.PIPE, timeout=timeout, env=os.environ.copy(), **subprocess_kwargs()).decode(encoding)  # type: ignore
47 |     if strip:
48 |         output = output.strip()
49 |     return output
50 | 
```

--------------------------------------------------------------------------------
/src/serena/constants.py:
--------------------------------------------------------------------------------

```python
 1 | from pathlib import Path
 2 | 
 3 | _repo_root_path = Path(__file__).parent.parent.parent.resolve()
 4 | _serena_pkg_path = Path(__file__).parent.resolve()
 5 | 
 6 | SERENA_MANAGED_DIR_NAME = ".serena"
 7 | 
 8 | # TODO: Path-related constants should be moved to SerenaPaths; don't add further constants here.
 9 | REPO_ROOT = str(_repo_root_path)
10 | PROMPT_TEMPLATES_DIR_INTERNAL = str(_serena_pkg_path / "resources" / "config" / "prompt_templates")
11 | SERENAS_OWN_CONTEXT_YAMLS_DIR = str(_serena_pkg_path / "resources" / "config" / "contexts")
12 | """The contexts that are shipped with the Serena package, i.e. the default contexts."""
13 | SERENAS_OWN_MODE_YAMLS_DIR = str(_serena_pkg_path / "resources" / "config" / "modes")
14 | """The modes that are shipped with the Serena package, i.e. the default modes."""
15 | INTERNAL_MODE_YAMLS_DIR = str(_serena_pkg_path / "resources" / "config" / "internal_modes")
16 | """Internal modes, never overridden by user modes."""
17 | SERENA_DASHBOARD_DIR = str(_serena_pkg_path / "resources" / "dashboard")
18 | SERENA_ICON_DIR = str(_serena_pkg_path / "resources" / "icons")
19 | 
20 | DEFAULT_SOURCE_FILE_ENCODING = "utf-8"
21 | """The default encoding assumed for project source files."""
22 | DEFAULT_CONTEXT = "desktop-app"
23 | DEFAULT_MODES = ("interactive", "editing")
24 | 
25 | SERENA_FILE_ENCODING = "utf-8"
26 | """The encoding used for Serena's own files, such as configuration files and memories."""
27 | 
28 | PROJECT_TEMPLATE_FILE = str(_serena_pkg_path / "resources" / "project.template.yml")
29 | SERENA_CONFIG_TEMPLATE_FILE = str(_serena_pkg_path / "resources" / "serena_config.template.yml")
30 | 
31 | SERENA_LOG_FORMAT = "%(levelname)-5s %(asctime)-15s [%(threadName)s] %(name)s:%(funcName)s:%(lineno)d - %(message)s"
32 | 
```

--------------------------------------------------------------------------------
/test/solidlsp/go/test_go_basic.py:
--------------------------------------------------------------------------------

```python
 1 | import os
 2 | 
 3 | import pytest
 4 | 
 5 | from solidlsp import SolidLanguageServer
 6 | from solidlsp.ls_config import Language
 7 | from solidlsp.ls_utils import SymbolUtils
 8 | 
 9 | 
10 | @pytest.mark.go
11 | class TestGoLanguageServer:
12 |     @pytest.mark.parametrize("language_server", [Language.GO], indirect=True)
13 |     def test_find_symbol(self, language_server: SolidLanguageServer) -> None:
14 |         symbols = language_server.request_full_symbol_tree()
15 |         assert SymbolUtils.symbol_tree_contains_name(symbols, "main"), "main function not found in symbol tree"
16 |         assert SymbolUtils.symbol_tree_contains_name(symbols, "Helper"), "Helper function not found in symbol tree"
17 |         assert SymbolUtils.symbol_tree_contains_name(symbols, "DemoStruct"), "DemoStruct not found in symbol tree"
18 | 
19 |     @pytest.mark.parametrize("language_server", [Language.GO], indirect=True)
20 |     def test_find_referencing_symbols(self, language_server: SolidLanguageServer) -> None:
21 |         file_path = os.path.join("main.go")
22 |         symbols = language_server.request_document_symbols(file_path).get_all_symbols_and_roots()
23 |         helper_symbol = None
24 |         for sym in symbols[0]:
25 |             if sym.get("name") == "Helper":
26 |                 helper_symbol = sym
27 |                 break
28 |         assert helper_symbol is not None, "Could not find 'Helper' function symbol in main.go"
29 |         sel_start = helper_symbol["selectionRange"]["start"]
30 |         refs = language_server.request_references(file_path, sel_start["line"], sel_start["character"])
31 |         assert any(
32 |             "main.go" in ref.get("relativePath", "") for ref in refs
33 |         ), "main.go should reference Helper (tried all positions in selectionRange)"
34 | 
```

--------------------------------------------------------------------------------
/scripts/profile_tool_call.py:
--------------------------------------------------------------------------------

```python
 1 | import cProfile
 2 | from pathlib import Path
 3 | from typing import Literal
 4 | 
 5 | from sensai.util import logging
 6 | from sensai.util.logging import LogTime
 7 | from sensai.util.profiling import profiled
 8 | 
 9 | from serena.agent import SerenaAgent
10 | from serena.config.serena_config import SerenaConfig
11 | from serena.tools import FindSymbolTool
12 | 
13 | log = logging.getLogger(__name__)
14 | 
15 | 
16 | if __name__ == "__main__":
17 |     logging.configure()
18 | 
19 |     # The profiler to use:
20 |     # Use pyinstrument for hierarchical profiling output
21 |     # Use cProfile to determine which functions take the most time overall (and use snakeviz to visualize)
22 |     profiler: Literal["pyinstrument", "cprofile"] = "cprofile"
23 | 
24 |     project_path = Path(__file__).parent.parent  # Serena root
25 | 
26 |     serena_config = SerenaConfig.from_config_file()
27 |     serena_config.log_level = logging.INFO
28 |     serena_config.gui_log_window_enabled = False
29 |     serena_config.web_dashboard = False
30 | 
31 |     agent = SerenaAgent(str(project_path), serena_config=serena_config)
32 | 
33 |     # wait for language server to be ready
34 |     agent.execute_task(lambda: log.info("Language server is ready."))
35 | 
36 |     def tool_call():
37 |         """This is the function we want to profile."""
38 |         # NOTE: We use apply (not apply_ex) to run the tool call directly on the main thread
39 |         with LogTime("Tool call"):
40 |             result = agent.get_tool(FindSymbolTool).apply(name_path="DQN")
41 |         log.info("Tool result:\n%s", result)
42 | 
43 |     if profiler == "pyinstrument":
44 | 
45 |         @profiled(log_to_file=True)
46 |         def profiled_tool_call():
47 |             tool_call()
48 | 
49 |         profiled_tool_call()
50 | 
51 |     elif profiler == "cprofile":
52 |         cProfile.run("tool_call()", "tool_call.pstat")
53 | 
```

--------------------------------------------------------------------------------
/test/solidlsp/typescript/test_typescript_basic.py:
--------------------------------------------------------------------------------

```python
 1 | import os
 2 | 
 3 | import pytest
 4 | 
 5 | from solidlsp import SolidLanguageServer
 6 | from solidlsp.ls_config import Language
 7 | from solidlsp.ls_utils import SymbolUtils
 8 | 
 9 | 
10 | @pytest.mark.typescript
11 | class TestTypescriptLanguageServer:
12 |     @pytest.mark.parametrize("language_server", [Language.TYPESCRIPT], indirect=True)
13 |     def test_find_symbol(self, language_server: SolidLanguageServer) -> None:
14 |         symbols = language_server.request_full_symbol_tree()
15 |         assert SymbolUtils.symbol_tree_contains_name(symbols, "DemoClass"), "DemoClass not found in symbol tree"
16 |         assert SymbolUtils.symbol_tree_contains_name(symbols, "helperFunction"), "helperFunction not found in symbol tree"
17 |         assert SymbolUtils.symbol_tree_contains_name(symbols, "printValue"), "printValue method not found in symbol tree"
18 | 
19 |     @pytest.mark.parametrize("language_server", [Language.TYPESCRIPT], indirect=True)
20 |     def test_find_referencing_symbols(self, language_server: SolidLanguageServer) -> None:
21 |         file_path = os.path.join("index.ts")
22 |         symbols = language_server.request_document_symbols(file_path).get_all_symbols_and_roots()
23 |         helper_symbol = None
24 |         for sym in symbols[0]:
25 |             if sym.get("name") == "helperFunction":
26 |                 helper_symbol = sym
27 |                 break
28 |         assert helper_symbol is not None, "Could not find 'helperFunction' symbol in index.ts"
29 |         sel_start = helper_symbol["selectionRange"]["start"]
30 |         refs = language_server.request_references(file_path, sel_start["line"], sel_start["character"])
31 |         assert any(
32 |             "index.ts" in ref.get("relativePath", "") for ref in refs
33 |         ), "index.ts should reference helperFunction (tried all positions in selectionRange)"
34 | 
```
Page 1/21FirstPrevNextLast