diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 656e0bd..2a75b04 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -53,7 +53,7 @@ jobs: run: go install golang.org/x/tools/gopls@latest - name: Run Go integration tests - run: go test ./integrationtests/languages/go/... + run: go test ./integrationtests/tests/go/... python-integration-tests: name: Python Integration Tests @@ -77,7 +77,7 @@ jobs: run: npm install -g pyright - name: Run Python integration tests - run: go test ./integrationtests/languages/python/... + run: go test ./integrationtests/tests/python/... rust-integration-tests: name: Rust Integration Tests @@ -106,7 +106,7 @@ jobs: - run: rust-analyzer --version - name: Run Rust integration tests - run: go test ./integrationtests/languages/rust/... + run: go test ./integrationtests/tests/rust/... typescript-integration-tests: name: TypeScript Integration Tests @@ -130,4 +130,4 @@ jobs: run: npm install -g typescript typescript-language-server - name: Run TypeScript integration tests - run: go test ./integrationtests/languages/typescript/... + run: go test ./integrationtests/tests/typescript/... diff --git a/.gitignore b/.gitignore index 031e37d..2fdd64f 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,6 @@ test-output/ # Temporary files *~ -CLAUDE.md +CLAUDE.md* +.mcp.json +.goosehints diff --git a/README.md b/README.md index 8d2a618..2d00171 100644 --- a/README.md +++ b/README.md @@ -5,130 +5,180 @@ [![GoDoc](https://pkg.go.dev/badge/github.com/isaacphi/mcp-language-server)](https://pkg.go.dev/github.com/isaacphi/mcp-language-server) [![Go Version](https://img.shields.io/github/go-mod/go-version/isaacphi/mcp-language-server)](https://github.com/isaacphi/mcp-language-server/blob/main/go.mod) -A Model Context Protocol (MCP) server that runs a language server and provides tools for communicating with it. +This is an [MCP](https://modelcontextprotocol.io/introduction) server that runs and exposes a [language server](https://microsoft.github.io/language-server-protocol/) to LLMs. Not a language server for MCP, whatever that would be. -## Motivation +## Demo -Claude desktop with the [filesystem](https://github.com/modelcontextprotocol/servers/tree/main/src/filesystem) server feels like magic when working on small projects. This starts to fall apart after you add a few files and imports. With this project, I want to create that experience when working with large projects. +`mcp-language-server` helps MCP enabled clients navigate codebases more easily by giving them access semantic tools like get definition, references, rename, and diagnostics. -Language servers excel at tasks that LLMs often struggle with, such as precisely understanding types, understanding relationships, and providing accurate symbol references. This project aims to makes bring those tools to LLMs. LSP also seems like a clear inspiration for MCP so why not jam them together? - -## Status - -⚠️ Pre-beta Quality ⚠️ - -I have tested this server with the following language servers - -- gopls (Go) -- pyright (Python) -- typescript-language-server (TypeScript) -- rust-analyzer (Rust) - -But it should be compatible with many more. - -## Tools - -- `read_definition`: Retrieves the complete source code definition of any symbol (function, type, constant, etc.) from your codebase. -- `find_references`: Locates all usages and references of a symbol throughout the codebase. -- `get_diagnostics`: Provides diagnostic information for a specific file, including warnings and errors. -- `get_codelens`: Retrieves code lens hints for additional context and actions on your code. -- `execute_codelens`: Runs a code lens action. -- `apply_text_edit`: Allows making multiple text edits to a file programmatically. -- `hover`: Display documentation, type hints, or other hover information for a given location. -- `rename_symbol`: Rename a symbol across a project. - -Behind the scenes, this MCP server can act on `workspace/applyEdit` requests from the language server, so it can apply things like refactor requests, adding imports, formatting code, etc. - -Each tool supports various options for customizing output, such as including line numbers or additional context. See the tool documentation for detailed usage. Line numbers are necessary for `apply_text_edit` to be able to make accurate edits. - -## About - -This codebase makes use of edited code from [gopls](https://go.googlesource.com/tools/+/refs/heads/master/gopls/internal/protocol) to handle LSP communication. See ATTRIBUTION for details. - -[mcp-go](https://github.com/mark3labs/mcp-go) is used for MCP communication. - -## Prerequisites - -Install Go: Follow instructions at - -Fetch or update this server: - -```bash -go install github.com/isaacphi/mcp-language-server@latest -``` - -Install a language server for your codebase: - -- Python (pyright): `npm install -g pyright` -- TypeScript (typescript-language-server): `npm install -g typescript typescript-language-server` -- Go (gopls): `go install golang.org/x/tools/gopls@latest` -- Rust (rust-analyzer): `rustup component add rust-analyzer` -- Or use any language server +![Demo](demo.gif) ## Setup -Add something like the following configuration to your Claude Desktop settings (or similar MCP-enabled client): +1. **Install Go**: Follow instructions at +2. **Install or update this server**: `go install github.com/isaacphi/mcp-language-server@latest` +3. **Install a language server**: _follow one of the guides below_ +4. **Configure your MCP client**: _follow one of the guides below_ -```json +
+ Go (gopls) +
+

Install gopls: go install golang.org/x/tools/gopls@latest

+

Configure your MCP client: This will be different but similar for each client. For Claude Desktop, add the following to ~/Library/Application\ Support/Claude/claude_desktop_config.json

+ +
+{
+  "mcpServers": {
+    "language-server": {
+      "command": "mcp-language-server",
+      "args": ["--workspace", "/Users/you/dev/yourproject/", "--lsp", "gopls"],
+      "env": {
+        "PATH": "/opt/homebrew/bin:/Users/you/go/bin",
+        "GOPATH": "/users/you/go",
+        "GOCACHE": "/users/you/Library/Caches/go-build",
+        "GOMODCACHE": "/Users/you/go/pkg/mod"
+      }
+    }
+  }
+}
+
+ +

Note: Not all clients will need these environment variables. For Claude Desktop you will need to update the environment variables above based on your machine and username:

+
    +
  • PATH needs to contain the path to go and to gopls. Get this with echo $(which go):$(which gopls)
  • +
  • GOPATH, GOCACHE, and GOMODCACHE may be different on your machine. These are the defaults.
  • +
+ +
+
+
+ Rust (rust-analyzer) +
+

Install rust-analyzer: rustup component add rust-analyzer

+

Configure your MCP client: This will be different but similar for each client. For Claude Desktop, add the following to ~/Library/Application\ Support/Claude/claude_desktop_config.json

+ +
 {
   "mcpServers": {
     "language-server": {
       "command": "mcp-language-server",
       "args": [
         "--workspace",
-        "/Users/you/dev/yourcodebase",
+        "/Users/you/dev/yourproject/",
         "--lsp",
-        "/opt/homebrew/bin/pyright-langserver",
+        "rust-analyzer"
+      ]
+    }
+  }
+}
+
+
+
+
+ Python (pyright) +
+

Install pyright: npm install -g pyright

+

Configure your MCP client: This will be different but similar for each client. For Claude Desktop, add the following to ~/Library/Application\ Support/Claude/claude_desktop_config.json

+ +
+{
+  "mcpServers": {
+    "language-server": {
+      "command": "mcp-language-server",
+      "args": [
+        "--workspace",
+        "/Users/you/dev/yourproject/",
+        "--lsp",
+        "pyright-langserver",
         "--",
         "--stdio"
-      ],
-      "env": {
-        "LOG_LEVEL": "INFO"
-      }
+      ]
     }
   }
 }
-```
+
+
+
+
+ Typescript (typescript-language-server) +
+

Install typescript-language-server: npm install -g typescript typescript-language-server

+

Configure your MCP client: This will be different but similar for each client. For Claude Desktop, add the following to ~/Library/Application\ Support/Claude/claude_desktop_config.json

+ +
+{
+  "mcpServers": {
+    "language-server": {
+      "command": "mcp-language-server",
+      "args": [
+        "--workspace",
+        "/Users/you/dev/yourproject/",
+        "--lsp",
+        "typescript-language-server",
+        "--",
+        "--stdio"
+      ]
+    }
+  }
+}
+
+
+
+
+ Other +
+

I have only tested this repo with the servers above but it should be compatible with many more. Note:

+
    +
  • The language server must communicate over stdio.
  • +
  • Any aruments after -- are sent as arguments to the language server.
  • +
  • Any env variables are passed on to the language server.
  • +
+
+
-Replace: +## Tools -- `/Users/you/dev/yourcodebase` with the absolute path to your project -- `/opt/homebrew/bin/pyright-langserver` with the path to your language server (found using `which` command e.g. `which pyright-langserver`) -- Any aruments after `--` are sent as arguments to your language server. -- Any env variables are passed on to the language server. Some may be necessary for you language server. For example, `gopls` required `GOPATH` and `GOCACHE` in order for me to get it working properly. -- `LOG_LEVEL` is optional. See below. +- `definition`: Retrieves the complete source code definition of any symbol (function, type, constant, etc.) from your codebase. +- `references`: Locates all usages and references of a symbol throughout the codebase. +- `diagnostics`: Provides diagnostic information for a specific file, including warnings and errors. +- `hover`: Display documentation, type hints, or other hover information for a given location. +- `rename_symbol`: Rename a symbol across a project. +- `edit_file`: Allows making multiple text edits to a file based on line numbers. Provides a more reliable and context-economical way to edit files compared to search and replace based edit tools. -## Development +## About -Clone the repository: +This codebase makes use of edited code from [gopls](https://go.googlesource.com/tools/+/refs/heads/master/gopls/internal/protocol) to handle LSP communication. See ATTRIBUTION for details. Everything here is covered by a permissive BSD style license. -```bash -git clone https://github.com/isaacphi/mcp-language-server.git -cd mcp-language-server -``` +[mcp-go](https://github.com/mark3labs/mcp-go) is used for MCP communication. Thank you for your service. -Install dev dependencies: +This is beta software. Please let me know by creating an issue if you run into any problems or have suggestions of any kind. -```bash -go mod download -``` +## Contributing -Build: +Please keep PRs small and open Issues first for anything substantial. AI slop OK as long as it is tested, passes checks, and doesn't smell too bad. -```bash -go build -``` +### Setup -Run tests: +Clone the repo: ```bash -go test ./... +git clone https://github.com/isaacphi/mcp-language-server.git +cd mcp-language-server ``` -Update test snapshots: +A [justfile](https://just.systems/man/en/) is included for convenience: ```bash -UPDATE_SNAPSHOTS=true go test ./integrationtests/... +just -l +Available recipes: + build # Build + check # Run code audit checks + fmt # Format code + generate # Generate LSP types and methods + help # Help + install # Install locally + snapshot # Update snapshot tests + test # Run tests ``` Configure your Claude Desktop (or similar) to use the local binary: @@ -142,7 +192,7 @@ Configure your Claude Desktop (or similar) to use the local binary: "--workspace", "/path/to/workspace", "--lsp", - "/path/to/language/server" + "language-server-executable" ], "env": { "LOG_LEVEL": "DEBUG" @@ -154,28 +204,28 @@ Configure your Claude Desktop (or similar) to use the local binary: Rebuild after making changes. -## Feedback +### Logging + +Setting the `LOG_LEVEL` environment variable to DEBUG enables verbose logging to stderr for all components including messages to and from the language server and the language server's logs. -Include +### LSP interaction + +- `internal/lsp/methods.go` contains generated code to make calls to the connected language server. +- `internal/protocol/tsprotocol.go` contains generated code for LSP types. I borrowed this from `gopls`'s source code. Thank you for your service. +- LSP allows language servers to return different types for the same methods. Go doesn't like this so there are some ugly workarounds in `internal/protocol/interfaces.go`. + +### Local Development and Snapshot Tests + +There is a snapshot test suite that makes it a lot easier to try out changes to tools. These run actual language servers on mock workspaces and capture output and logs. + +You will need the language servers installed locally to run them. There are tests for go, rust, python, and typescript. ``` -env: { - "LOG_LEVEL": "DEBUG", -} +integrationtests/ +├── tests/ # Tests are in this folder +├── snapshots/ # Snapshots of tool outputs +├── test-output/ # Gitignored folder showing the final state of each workspace and logs after each test run +└── workspaces/ # Mock workspaces that the tools run on ``` -To get detailed LSP and application logs. Setting `LOG_LEVEL` to DEBUG enables verbose logging for all components. Adding `LOG_COMPONENT_LEVELS` with `wire:DEBUG` shows raw LSP JSON messages. Please include as much information as possible when opening issues. - -The following features are on my radar: - -- [x] Read definition -- [x] Get references -- [x] Apply edit -- [x] Get diagnostics -- [x] Code lens -- [x] Hover info -- [x] Rename symbol -- [ ] Code actions -- [ ] Better handling of context and cancellation -- [ ] Add LSP server configuration options and presets for common languages -- [ ] Create tools at a higher level of abstraction, combining diagnostics, code lens, hover, and code actions when reading definitions or references. +To update snapshots, run `UPDATE_SNAPSHOTS=true go test ./integrationtests/...` diff --git a/demo.cast b/demo.cast new file mode 100644 index 0000000..c206f3e --- /dev/null +++ b/demo.cast @@ -0,0 +1,50 @@ +{"version": 2, "width": 105, "height": 34, "timestamp": 1746219462, "env": {"SHELL": "/opt/homebrew/bin/fish", "TERM": "screen-256color"}} +[0.017427, "o", "\u001b[2 q"] +[0.01959, "o", "🐟\r\n"] +[0.019956, "o", "\u001b[2 q"] +[0.025132, "o", "\u001b[2 q"] +[0.025149, "o", "\u001b[?2004h"] +[0.057303, "o", "\u001b]0;~/d/mcp-language-server\u0007\u001b[30m\u001b[m\u000f\r\u001b[92mphil\u001b[m\u000f@\u001b[m\u000fmacbook\u001b[m\u000f:\u001b[38;2;89;194;255m~/d/mcp-language-server\u001b[m\u000f|\u001b[31mcleanup/0.1.0⚡\u001b[34m*\u001b[m\u000f\u001b[K\r\n➤ \u001b[m\u000f\u001b[38;2;179;177;173m\u001b[K\r\u001b[C\u001b[C"] +[2.922642, "o", "g\r\u001b[3C"] +[2.923062, "o", "\b\u001b[38;2;255;51;51mg\u001b[38;2;179;177;173m\r\u001b[3C"] +[2.926569, "o", "\u001b[38;2;77;85;102mit diff\u001b[38;2;179;177;173m\r\u001b[3C"] +[3.104296, "o", "\u001b[38;2;255;51;51mi\u001b[38;2;77;85;102mt diff\u001b[38;2;179;177;173m\r\u001b[4C"] +[3.44609, "o", "\u001b[38;2;255;51;51mt\u001b[38;2;77;85;102m diff\u001b[38;2;179;177;173m\r\u001b[5C"] +[3.446933, "o", "\b\b\b\u001b[38;2;57;186;230mgit\u001b[38;2;77;85;102m diff\u001b[38;2;179;177;173m\r\u001b[5C"] +[3.549148, "o", "\u001b[38;2;57;186;230m \u001b[38;2;77;85;102mdiff\u001b[38;2;179;177;173m\r\u001b[6C"] +[3.549294, "o", "\b \u001b[38;2;77;85;102mdiff\u001b[38;2;179;177;173m\r\u001b[6C"] +[3.724184, "o", "d\u001b[38;2;77;85;102miff\u001b[38;2;179;177;173m\r\u001b[7C"] +[3.724803, "o", "\b\u001b[4md\u001b[38;2;77;85;102m\u001b[24miff\u001b[38;2;179;177;173m\r\u001b[7C"] +[3.808447, "o", "\u001b[4mi\u001b[38;2;77;85;102m\u001b[24mff\u001b[38;2;179;177;173m\r\u001b[8C"] +[3.809498, "o", "\b\bdi\u001b[38;2;77;85;102mff\u001b[38;2;179;177;173m\r\u001b[8C"] +[3.938272, "o", "f\u001b[38;2;77;85;102mf\u001b[38;2;179;177;173m\r\u001b[9C"] +[4.091909, "o", "f\r\u001b[10C"] +[4.092162, "o", "\r\u001b[10C"] +[4.263005, "o", "\r\u001b[10C\r\n"] +[4.263222, "o", "\u001b[30m\u001b[m\u000f"] +[4.263308, "o", "\u001b[2 q"] +[4.263662, "o", "\u001b[?2004l\u001b[?1004l"] +[4.265037, "o", "\u001b]0;git diff ~/d/mcp-language-server\u0007\u001b[30m\u001b[m\u000f\r\u001b[30m\u001b[m\u000f"] +[4.285809, "o", "\u001b[?1h\u001b=\r\u001b[1mdiff --git i/.gitignore w/.gitignore\u001b[m\u001b[m\r\n\u001b[1mindex c263ff7..2fdd64f 100644\u001b[m\u001b[m\r\n\u001b[1m--- i/.gitignore\u001b[m\u001b[m\r\n\u001b[1m+++ w/.gitignore\u001b[m\u001b[m\r\n\u001b[36m@@ -10,3 +10,4 @@\u001b[m \u001b[mtest-output/\u001b[m\u001b[m\r\n \u001b[m\u001b[m\r\n CLAUDE.md*\u001b[m\u001b[m\r\n .mcp.json\u001b[m\u001b[m\r\n\u001b[32m+\u001b[m\u001b[32m.goosehints\u001b[m\u001b[m\r\n"] +[4.286443, "o", "\r\u001b[K\u001b[?1l\u001b>"] +[4.287838, "o", "\u001b[2 q"] +[4.287857, "o", "\u001b[?1004h"] +[4.288034, "o", "\u001b[2m⏎\u001b[m\u000f \r⏎ \r\u001b[K\u001b[?2004h"] +[4.317619, "o", "\u001b]0;~/d/mcp-language-server\u0007\u001b[30m\u001b[m\u000f\r"] +[4.317702, "o", "\u001b[92mphil\u001b[m\u000f@\u001b[m\u000fmacbook\u001b[m\u000f:\u001b[38;2;89;194;255m~/d/mcp-language-server\u001b[m\u000f|\u001b[31mcleanup/0.1.0⚡\u001b[34m*\u001b[m\u000f\u001b[33m?\u001b[m\u000f\u001b[K\r\n➤ \u001b[m\u000f\u001b[38;2;179;177;173m\u001b[K\r\u001b[C\u001b[C"] +[6.902906, "o", "g\r\u001b[3C"] +[6.90328, "o", "\u001b[38;2;77;85;102mit diff\u001b[38;2;179;177;173m\r\u001b[3C"] +[6.903393, "o", "\b\u001b[38;2;255;51;51mg\u001b[38;2;77;85;102mit diff\u001b[38;2;179;177;173m\r\u001b[3C"] +[6.986156, "o", "\u001b[38;2;255;51;51mi\u001b[38;2;77;85;102mt diff\u001b[38;2;179;177;173m\r\u001b[4C"] +[7.082253, "o", "\u001b[38;2;255;51;51mt\u001b[38;2;77;85;102m diff\u001b[38;2;179;177;173m\r\u001b[5C"] +[7.082524, "o", "\b\b\b\u001b[38;2;57;186;230mgit\u001b[38;2;77;85;102m diff\u001b[38;2;179;177;173m\r\u001b[5C"] +[7.134235, "o", "\u001b[38;2;57;186;230m \u001b[38;2;77;85;102mdiff\u001b[38;2;179;177;173m\r\u001b[6C"] +[7.134671, "o", "\b \u001b[38;2;77;85;102mdiff\u001b[38;2;179;177;173m\r\u001b[6C"] +[7.822316, "o", "\b\u001b[K\r\u001b[5C"] +[7.993558, "o", "\b\u001b[K\r\u001b[4C"] +[7.993966, "o", "\b\b\u001b[38;2;255;51;51mgi\u001b[38;2;179;177;173m\r\u001b[4C"] +[8.155405, "o", "\b\u001b[K\r\u001b[3C"] +[8.290714, "o", "\b\u001b[K\r\u001b[C\u001b[C"] +[8.636471, "o", "\r\n"] +[8.636649, "o", "\u001b[30m\u001b[m\u000f\u001b[30m\u001b[m\u000f"] +[8.636665, "o", "\u001b[?2004l"] diff --git a/demo.gif b/demo.gif new file mode 100644 index 0000000..46409b5 Binary files /dev/null and b/demo.gif differ diff --git a/integrationtests/fixtures/snapshots/rust/hover/type-alias.snap b/integrationtests/fixtures/snapshots/rust/hover/type-alias.snap deleted file mode 100644 index bf05b4e..0000000 --- a/integrationtests/fixtures/snapshots/rust/hover/type-alias.snap +++ /dev/null @@ -1,4 +0,0 @@ -test_workspace::types - -// size = 24 (0x18), align = 0x8 -pub type TestType = String \ No newline at end of file diff --git a/integrationtests/fixtures/snapshots/typescript/hover/outside-file.snap b/integrationtests/fixtures/snapshots/typescript/hover/outside-file.snap deleted file mode 100644 index f175581..0000000 --- a/integrationtests/fixtures/snapshots/typescript/hover/outside-file.snap +++ /dev/null @@ -1 +0,0 @@ -No hover information available for this position on the following line: diff --git a/integrationtests/fixtures/snapshots/go/codelens/execute.snap b/integrationtests/snapshots/go/codelens/execute.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/codelens/execute.snap rename to integrationtests/snapshots/go/codelens/execute.snap diff --git a/integrationtests/fixtures/snapshots/go/codelens/get.snap b/integrationtests/snapshots/go/codelens/get.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/codelens/get.snap rename to integrationtests/snapshots/go/codelens/get.snap diff --git a/integrationtests/fixtures/snapshots/go/definition/constant.snap b/integrationtests/snapshots/go/definition/constant.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/definition/constant.snap rename to integrationtests/snapshots/go/definition/constant.snap diff --git a/integrationtests/fixtures/snapshots/go/definition/foobar.snap b/integrationtests/snapshots/go/definition/foobar.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/definition/foobar.snap rename to integrationtests/snapshots/go/definition/foobar.snap diff --git a/integrationtests/fixtures/snapshots/go/definition/function.snap b/integrationtests/snapshots/go/definition/function.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/definition/function.snap rename to integrationtests/snapshots/go/definition/function.snap diff --git a/integrationtests/fixtures/snapshots/go/definition/interface.snap b/integrationtests/snapshots/go/definition/interface.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/definition/interface.snap rename to integrationtests/snapshots/go/definition/interface.snap diff --git a/integrationtests/fixtures/snapshots/go/definition/method.snap b/integrationtests/snapshots/go/definition/method.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/definition/method.snap rename to integrationtests/snapshots/go/definition/method.snap diff --git a/integrationtests/fixtures/snapshots/go/definition/not-found.snap b/integrationtests/snapshots/go/definition/not-found.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/definition/not-found.snap rename to integrationtests/snapshots/go/definition/not-found.snap diff --git a/integrationtests/fixtures/snapshots/go/definition/struct.snap b/integrationtests/snapshots/go/definition/struct.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/definition/struct.snap rename to integrationtests/snapshots/go/definition/struct.snap diff --git a/integrationtests/fixtures/snapshots/go/definition/type.snap b/integrationtests/snapshots/go/definition/type.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/definition/type.snap rename to integrationtests/snapshots/go/definition/type.snap diff --git a/integrationtests/fixtures/snapshots/go/definition/variable.snap b/integrationtests/snapshots/go/definition/variable.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/definition/variable.snap rename to integrationtests/snapshots/go/definition/variable.snap diff --git a/integrationtests/fixtures/snapshots/go/diagnostics/clean.snap b/integrationtests/snapshots/go/diagnostics/clean.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/diagnostics/clean.snap rename to integrationtests/snapshots/go/diagnostics/clean.snap diff --git a/integrationtests/fixtures/snapshots/go/diagnostics/dependency.snap b/integrationtests/snapshots/go/diagnostics/dependency.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/diagnostics/dependency.snap rename to integrationtests/snapshots/go/diagnostics/dependency.snap diff --git a/integrationtests/fixtures/snapshots/go/diagnostics/unreachable.snap b/integrationtests/snapshots/go/diagnostics/unreachable.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/diagnostics/unreachable.snap rename to integrationtests/snapshots/go/diagnostics/unreachable.snap diff --git a/integrationtests/fixtures/snapshots/go/hover/constant.snap b/integrationtests/snapshots/go/hover/constant.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/hover/constant.snap rename to integrationtests/snapshots/go/hover/constant.snap diff --git a/integrationtests/fixtures/snapshots/go/hover/interface-method-impl.snap b/integrationtests/snapshots/go/hover/interface-method-impl.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/hover/interface-method-impl.snap rename to integrationtests/snapshots/go/hover/interface-method-impl.snap diff --git a/integrationtests/fixtures/snapshots/go/hover/interface-type.snap b/integrationtests/snapshots/go/hover/interface-type.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/hover/interface-type.snap rename to integrationtests/snapshots/go/hover/interface-type.snap diff --git a/integrationtests/fixtures/snapshots/go/hover/no-hover-info.snap b/integrationtests/snapshots/go/hover/no-hover-info.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/hover/no-hover-info.snap rename to integrationtests/snapshots/go/hover/no-hover-info.snap diff --git a/integrationtests/fixtures/snapshots/go/hover/outside-file.snap b/integrationtests/snapshots/go/hover/outside-file.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/hover/outside-file.snap rename to integrationtests/snapshots/go/hover/outside-file.snap diff --git a/integrationtests/fixtures/snapshots/go/hover/struct-method.snap b/integrationtests/snapshots/go/hover/struct-method.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/hover/struct-method.snap rename to integrationtests/snapshots/go/hover/struct-method.snap diff --git a/integrationtests/fixtures/snapshots/go/hover/struct-type.snap b/integrationtests/snapshots/go/hover/struct-type.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/hover/struct-type.snap rename to integrationtests/snapshots/go/hover/struct-type.snap diff --git a/integrationtests/fixtures/snapshots/go/references/foobar-function.snap b/integrationtests/snapshots/go/references/foobar-function.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/references/foobar-function.snap rename to integrationtests/snapshots/go/references/foobar-function.snap diff --git a/integrationtests/fixtures/snapshots/go/references/helper-function.snap b/integrationtests/snapshots/go/references/helper-function.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/references/helper-function.snap rename to integrationtests/snapshots/go/references/helper-function.snap diff --git a/integrationtests/fixtures/snapshots/go/references/interface-method.snap b/integrationtests/snapshots/go/references/interface-method.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/references/interface-method.snap rename to integrationtests/snapshots/go/references/interface-method.snap diff --git a/integrationtests/fixtures/snapshots/go/references/not-found.snap b/integrationtests/snapshots/go/references/not-found.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/references/not-found.snap rename to integrationtests/snapshots/go/references/not-found.snap diff --git a/integrationtests/fixtures/snapshots/go/references/shared-constant.snap b/integrationtests/snapshots/go/references/shared-constant.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/references/shared-constant.snap rename to integrationtests/snapshots/go/references/shared-constant.snap diff --git a/integrationtests/fixtures/snapshots/go/references/shared-interface.snap b/integrationtests/snapshots/go/references/shared-interface.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/references/shared-interface.snap rename to integrationtests/snapshots/go/references/shared-interface.snap diff --git a/integrationtests/fixtures/snapshots/go/references/shared-struct.snap b/integrationtests/snapshots/go/references/shared-struct.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/references/shared-struct.snap rename to integrationtests/snapshots/go/references/shared-struct.snap diff --git a/integrationtests/fixtures/snapshots/go/references/shared-type.snap b/integrationtests/snapshots/go/references/shared-type.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/references/shared-type.snap rename to integrationtests/snapshots/go/references/shared-type.snap diff --git a/integrationtests/fixtures/snapshots/go/references/struct-method.snap b/integrationtests/snapshots/go/references/struct-method.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/references/struct-method.snap rename to integrationtests/snapshots/go/references/struct-method.snap diff --git a/integrationtests/fixtures/snapshots/go/rename_symbol/not_found.snap b/integrationtests/snapshots/go/rename_symbol/not_found.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/rename_symbol/not_found.snap rename to integrationtests/snapshots/go/rename_symbol/not_found.snap diff --git a/integrationtests/fixtures/snapshots/go/rename_symbol/successful.snap b/integrationtests/snapshots/go/rename_symbol/successful.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/rename_symbol/successful.snap rename to integrationtests/snapshots/go/rename_symbol/successful.snap diff --git a/integrationtests/fixtures/snapshots/go/text_edit/append_to_end_of_file.snap b/integrationtests/snapshots/go/text_edit/append_to_end_of_file.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/text_edit/append_to_end_of_file.snap rename to integrationtests/snapshots/go/text_edit/append_to_end_of_file.snap diff --git a/integrationtests/fixtures/snapshots/go/text_edit/delete_line.snap b/integrationtests/snapshots/go/text_edit/delete_line.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/text_edit/delete_line.snap rename to integrationtests/snapshots/go/text_edit/delete_line.snap diff --git a/integrationtests/fixtures/snapshots/go/text_edit/edit_empty_function.snap b/integrationtests/snapshots/go/text_edit/edit_empty_function.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/text_edit/edit_empty_function.snap rename to integrationtests/snapshots/go/text_edit/edit_empty_function.snap diff --git a/integrationtests/fixtures/snapshots/go/text_edit/edit_single_line_function.snap b/integrationtests/snapshots/go/text_edit/edit_single_line_function.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/text_edit/edit_single_line_function.snap rename to integrationtests/snapshots/go/text_edit/edit_single_line_function.snap diff --git a/integrationtests/fixtures/snapshots/go/text_edit/insert_at_a_line_(by_replacing_it_and_including_original_content).snap b/integrationtests/snapshots/go/text_edit/insert_at_a_line_(by_replacing_it_and_including_original_content).snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/text_edit/insert_at_a_line_(by_replacing_it_and_including_original_content).snap rename to integrationtests/snapshots/go/text_edit/insert_at_a_line_(by_replacing_it_and_including_original_content).snap diff --git a/integrationtests/fixtures/snapshots/go/text_edit/multiple_edits_in_same_file.snap b/integrationtests/snapshots/go/text_edit/multiple_edits_in_same_file.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/text_edit/multiple_edits_in_same_file.snap rename to integrationtests/snapshots/go/text_edit/multiple_edits_in_same_file.snap diff --git a/integrationtests/fixtures/snapshots/go/text_edit/replace_multiple_lines.snap b/integrationtests/snapshots/go/text_edit/replace_multiple_lines.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/text_edit/replace_multiple_lines.snap rename to integrationtests/snapshots/go/text_edit/replace_multiple_lines.snap diff --git a/integrationtests/fixtures/snapshots/go/text_edit/replace_single_line.snap b/integrationtests/snapshots/go/text_edit/replace_single_line.snap similarity index 100% rename from integrationtests/fixtures/snapshots/go/text_edit/replace_single_line.snap rename to integrationtests/snapshots/go/text_edit/replace_single_line.snap diff --git a/integrationtests/fixtures/snapshots/python/definition/class.snap b/integrationtests/snapshots/python/definition/class.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/definition/class.snap rename to integrationtests/snapshots/python/definition/class.snap diff --git a/integrationtests/fixtures/snapshots/python/definition/constant.snap b/integrationtests/snapshots/python/definition/constant.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/definition/constant.snap rename to integrationtests/snapshots/python/definition/constant.snap diff --git a/integrationtests/fixtures/snapshots/python/definition/derived-class.snap b/integrationtests/snapshots/python/definition/derived-class.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/definition/derived-class.snap rename to integrationtests/snapshots/python/definition/derived-class.snap diff --git a/integrationtests/fixtures/snapshots/python/definition/function.snap b/integrationtests/snapshots/python/definition/function.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/definition/function.snap rename to integrationtests/snapshots/python/definition/function.snap diff --git a/integrationtests/fixtures/snapshots/python/definition/method.snap b/integrationtests/snapshots/python/definition/method.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/definition/method.snap rename to integrationtests/snapshots/python/definition/method.snap diff --git a/integrationtests/fixtures/snapshots/python/definition/same-name.snap b/integrationtests/snapshots/python/definition/same-name.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/definition/same-name.snap rename to integrationtests/snapshots/python/definition/same-name.snap diff --git a/integrationtests/fixtures/snapshots/python/definition/static-method.snap b/integrationtests/snapshots/python/definition/static-method.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/definition/static-method.snap rename to integrationtests/snapshots/python/definition/static-method.snap diff --git a/integrationtests/fixtures/snapshots/python/definition/variable.snap b/integrationtests/snapshots/python/definition/variable.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/definition/variable.snap rename to integrationtests/snapshots/python/definition/variable.snap diff --git a/integrationtests/fixtures/snapshots/python/diagnostics/clean.snap b/integrationtests/snapshots/python/diagnostics/clean.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/diagnostics/clean.snap rename to integrationtests/snapshots/python/diagnostics/clean.snap diff --git a/integrationtests/fixtures/snapshots/python/diagnostics/dependency.snap b/integrationtests/snapshots/python/diagnostics/dependency.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/diagnostics/dependency.snap rename to integrationtests/snapshots/python/diagnostics/dependency.snap diff --git a/integrationtests/fixtures/snapshots/python/diagnostics/errors.snap b/integrationtests/snapshots/python/diagnostics/errors.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/diagnostics/errors.snap rename to integrationtests/snapshots/python/diagnostics/errors.snap diff --git a/integrationtests/fixtures/snapshots/python/hover/class-method.snap b/integrationtests/snapshots/python/hover/class-method.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/hover/class-method.snap rename to integrationtests/snapshots/python/hover/class-method.snap diff --git a/integrationtests/fixtures/snapshots/python/hover/class.snap b/integrationtests/snapshots/python/hover/class.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/hover/class.snap rename to integrationtests/snapshots/python/hover/class.snap diff --git a/integrationtests/fixtures/snapshots/python/hover/constant.snap b/integrationtests/snapshots/python/hover/constant.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/hover/constant.snap rename to integrationtests/snapshots/python/hover/constant.snap diff --git a/integrationtests/fixtures/snapshots/python/hover/derived-class.snap b/integrationtests/snapshots/python/hover/derived-class.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/hover/derived-class.snap rename to integrationtests/snapshots/python/hover/derived-class.snap diff --git a/integrationtests/fixtures/snapshots/python/hover/function.snap b/integrationtests/snapshots/python/hover/function.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/hover/function.snap rename to integrationtests/snapshots/python/hover/function.snap diff --git a/integrationtests/fixtures/snapshots/python/hover/no-hover-info.snap b/integrationtests/snapshots/python/hover/no-hover-info.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/hover/no-hover-info.snap rename to integrationtests/snapshots/python/hover/no-hover-info.snap diff --git a/integrationtests/fixtures/snapshots/python/hover/outside-file.snap b/integrationtests/snapshots/python/hover/outside-file.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/hover/outside-file.snap rename to integrationtests/snapshots/python/hover/outside-file.snap diff --git a/integrationtests/fixtures/snapshots/python/hover/static-method.snap b/integrationtests/snapshots/python/hover/static-method.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/hover/static-method.snap rename to integrationtests/snapshots/python/hover/static-method.snap diff --git a/integrationtests/fixtures/snapshots/python/hover/variable.snap b/integrationtests/snapshots/python/hover/variable.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/hover/variable.snap rename to integrationtests/snapshots/python/hover/variable.snap diff --git a/integrationtests/fixtures/snapshots/python/references/class-method.snap b/integrationtests/snapshots/python/references/class-method.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/references/class-method.snap rename to integrationtests/snapshots/python/references/class-method.snap diff --git a/integrationtests/fixtures/snapshots/python/references/color-enum.snap b/integrationtests/snapshots/python/references/color-enum.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/references/color-enum.snap rename to integrationtests/snapshots/python/references/color-enum.snap diff --git a/integrationtests/fixtures/snapshots/python/references/helper-function.snap b/integrationtests/snapshots/python/references/helper-function.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/references/helper-function.snap rename to integrationtests/snapshots/python/references/helper-function.snap diff --git a/integrationtests/fixtures/snapshots/python/references/interface-method.snap b/integrationtests/snapshots/python/references/interface-method.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/references/interface-method.snap rename to integrationtests/snapshots/python/references/interface-method.snap diff --git a/integrationtests/fixtures/snapshots/python/references/shared-class.snap b/integrationtests/snapshots/python/references/shared-class.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/references/shared-class.snap rename to integrationtests/snapshots/python/references/shared-class.snap diff --git a/integrationtests/fixtures/snapshots/python/references/shared-constant.snap b/integrationtests/snapshots/python/references/shared-constant.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/references/shared-constant.snap rename to integrationtests/snapshots/python/references/shared-constant.snap diff --git a/integrationtests/fixtures/snapshots/python/references/shared-interface.snap b/integrationtests/snapshots/python/references/shared-interface.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/references/shared-interface.snap rename to integrationtests/snapshots/python/references/shared-interface.snap diff --git a/integrationtests/fixtures/snapshots/python/rename_symbol/not_found.snap b/integrationtests/snapshots/python/rename_symbol/not_found.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/rename_symbol/not_found.snap rename to integrationtests/snapshots/python/rename_symbol/not_found.snap diff --git a/integrationtests/fixtures/snapshots/python/rename_symbol/successful.snap b/integrationtests/snapshots/python/rename_symbol/successful.snap similarity index 100% rename from integrationtests/fixtures/snapshots/python/rename_symbol/successful.snap rename to integrationtests/snapshots/python/rename_symbol/successful.snap diff --git a/integrationtests/fixtures/snapshots/rust/definition/constant.snap b/integrationtests/snapshots/rust/definition/constant.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/definition/constant.snap rename to integrationtests/snapshots/rust/definition/constant.snap diff --git a/integrationtests/fixtures/snapshots/rust/definition/foobar.snap b/integrationtests/snapshots/rust/definition/foobar.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/definition/foobar.snap rename to integrationtests/snapshots/rust/definition/foobar.snap diff --git a/integrationtests/fixtures/snapshots/rust/definition/function.snap b/integrationtests/snapshots/rust/definition/function.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/definition/function.snap rename to integrationtests/snapshots/rust/definition/function.snap diff --git a/integrationtests/fixtures/snapshots/rust/definition/interface.snap b/integrationtests/snapshots/rust/definition/interface.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/definition/interface.snap rename to integrationtests/snapshots/rust/definition/interface.snap diff --git a/integrationtests/fixtures/snapshots/rust/definition/method.snap b/integrationtests/snapshots/rust/definition/method.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/definition/method.snap rename to integrationtests/snapshots/rust/definition/method.snap diff --git a/integrationtests/fixtures/snapshots/rust/definition/struct.snap b/integrationtests/snapshots/rust/definition/struct.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/definition/struct.snap rename to integrationtests/snapshots/rust/definition/struct.snap diff --git a/integrationtests/fixtures/snapshots/rust/definition/type.snap b/integrationtests/snapshots/rust/definition/type.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/definition/type.snap rename to integrationtests/snapshots/rust/definition/type.snap diff --git a/integrationtests/fixtures/snapshots/rust/definition/variable.snap b/integrationtests/snapshots/rust/definition/variable.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/definition/variable.snap rename to integrationtests/snapshots/rust/definition/variable.snap diff --git a/integrationtests/fixtures/snapshots/rust/diagnostics/clean.snap b/integrationtests/snapshots/rust/diagnostics/clean.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/diagnostics/clean.snap rename to integrationtests/snapshots/rust/diagnostics/clean.snap diff --git a/integrationtests/fixtures/snapshots/rust/diagnostics/dependency.snap b/integrationtests/snapshots/rust/diagnostics/dependency.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/diagnostics/dependency.snap rename to integrationtests/snapshots/rust/diagnostics/dependency.snap diff --git a/integrationtests/fixtures/snapshots/rust/diagnostics/unreachable.snap b/integrationtests/snapshots/rust/diagnostics/unreachable.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/diagnostics/unreachable.snap rename to integrationtests/snapshots/rust/diagnostics/unreachable.snap diff --git a/integrationtests/fixtures/snapshots/rust/hover/constant.snap b/integrationtests/snapshots/rust/hover/constant.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/hover/constant.snap rename to integrationtests/snapshots/rust/hover/constant.snap diff --git a/integrationtests/fixtures/snapshots/rust/hover/function.snap b/integrationtests/snapshots/rust/hover/function.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/hover/function.snap rename to integrationtests/snapshots/rust/hover/function.snap diff --git a/integrationtests/fixtures/snapshots/rust/hover/no-hover-info.snap b/integrationtests/snapshots/rust/hover/no-hover-info.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/hover/no-hover-info.snap rename to integrationtests/snapshots/rust/hover/no-hover-info.snap diff --git a/integrationtests/fixtures/snapshots/rust/hover/outside-file.snap b/integrationtests/snapshots/rust/hover/outside-file.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/hover/outside-file.snap rename to integrationtests/snapshots/rust/hover/outside-file.snap diff --git a/integrationtests/fixtures/snapshots/rust/hover/struct-method.snap b/integrationtests/snapshots/rust/hover/struct-method.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/hover/struct-method.snap rename to integrationtests/snapshots/rust/hover/struct-method.snap diff --git a/integrationtests/fixtures/snapshots/rust/hover/struct-type.snap b/integrationtests/snapshots/rust/hover/struct-type.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/hover/struct-type.snap rename to integrationtests/snapshots/rust/hover/struct-type.snap diff --git a/integrationtests/fixtures/snapshots/rust/hover/trait-type.snap b/integrationtests/snapshots/rust/hover/trait-type.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/hover/trait-type.snap rename to integrationtests/snapshots/rust/hover/trait-type.snap diff --git a/integrationtests/fixtures/snapshots/rust/hover/variable.snap b/integrationtests/snapshots/rust/hover/variable.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/hover/variable.snap rename to integrationtests/snapshots/rust/hover/variable.snap diff --git a/integrationtests/fixtures/snapshots/rust/references/foobar-function.snap b/integrationtests/snapshots/rust/references/foobar-function.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/references/foobar-function.snap rename to integrationtests/snapshots/rust/references/foobar-function.snap diff --git a/integrationtests/fixtures/snapshots/rust/references/helper-function.snap b/integrationtests/snapshots/rust/references/helper-function.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/references/helper-function.snap rename to integrationtests/snapshots/rust/references/helper-function.snap diff --git a/integrationtests/fixtures/snapshots/rust/references/interface-method.snap b/integrationtests/snapshots/rust/references/interface-method.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/references/interface-method.snap rename to integrationtests/snapshots/rust/references/interface-method.snap diff --git a/integrationtests/fixtures/snapshots/rust/references/shared-constant.snap b/integrationtests/snapshots/rust/references/shared-constant.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/references/shared-constant.snap rename to integrationtests/snapshots/rust/references/shared-constant.snap diff --git a/integrationtests/fixtures/snapshots/rust/references/shared-interface.snap b/integrationtests/snapshots/rust/references/shared-interface.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/references/shared-interface.snap rename to integrationtests/snapshots/rust/references/shared-interface.snap diff --git a/integrationtests/fixtures/snapshots/rust/references/shared-struct.snap b/integrationtests/snapshots/rust/references/shared-struct.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/references/shared-struct.snap rename to integrationtests/snapshots/rust/references/shared-struct.snap diff --git a/integrationtests/fixtures/snapshots/rust/references/shared-type.snap b/integrationtests/snapshots/rust/references/shared-type.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/references/shared-type.snap rename to integrationtests/snapshots/rust/references/shared-type.snap diff --git a/integrationtests/fixtures/snapshots/rust/references/struct-method.snap b/integrationtests/snapshots/rust/references/struct-method.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/references/struct-method.snap rename to integrationtests/snapshots/rust/references/struct-method.snap diff --git a/integrationtests/fixtures/snapshots/rust/rename_symbol/not_found.snap b/integrationtests/snapshots/rust/rename_symbol/not_found.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/rename_symbol/not_found.snap rename to integrationtests/snapshots/rust/rename_symbol/not_found.snap diff --git a/integrationtests/fixtures/snapshots/rust/rename_symbol/successful.snap b/integrationtests/snapshots/rust/rename_symbol/successful.snap similarity index 100% rename from integrationtests/fixtures/snapshots/rust/rename_symbol/successful.snap rename to integrationtests/snapshots/rust/rename_symbol/successful.snap diff --git a/integrationtests/fixtures/snapshots/typescript/definition/class.snap b/integrationtests/snapshots/typescript/definition/class.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/definition/class.snap rename to integrationtests/snapshots/typescript/definition/class.snap diff --git a/integrationtests/fixtures/snapshots/typescript/definition/constant.snap b/integrationtests/snapshots/typescript/definition/constant.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/definition/constant.snap rename to integrationtests/snapshots/typescript/definition/constant.snap diff --git a/integrationtests/fixtures/snapshots/typescript/definition/function.snap b/integrationtests/snapshots/typescript/definition/function.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/definition/function.snap rename to integrationtests/snapshots/typescript/definition/function.snap diff --git a/integrationtests/fixtures/snapshots/typescript/definition/interface.snap b/integrationtests/snapshots/typescript/definition/interface.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/definition/interface.snap rename to integrationtests/snapshots/typescript/definition/interface.snap diff --git a/integrationtests/fixtures/snapshots/typescript/definition/type.snap b/integrationtests/snapshots/typescript/definition/type.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/definition/type.snap rename to integrationtests/snapshots/typescript/definition/type.snap diff --git a/integrationtests/fixtures/snapshots/typescript/definition/variable.snap b/integrationtests/snapshots/typescript/definition/variable.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/definition/variable.snap rename to integrationtests/snapshots/typescript/definition/variable.snap diff --git a/integrationtests/fixtures/snapshots/typescript/diagnostics/clean.snap b/integrationtests/snapshots/typescript/diagnostics/clean.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/diagnostics/clean.snap rename to integrationtests/snapshots/typescript/diagnostics/clean.snap diff --git a/integrationtests/fixtures/snapshots/typescript/diagnostics/dependency.snap b/integrationtests/snapshots/typescript/diagnostics/dependency.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/diagnostics/dependency.snap rename to integrationtests/snapshots/typescript/diagnostics/dependency.snap diff --git a/integrationtests/fixtures/snapshots/typescript/diagnostics/type-error.snap b/integrationtests/snapshots/typescript/diagnostics/type-error.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/diagnostics/type-error.snap rename to integrationtests/snapshots/typescript/diagnostics/type-error.snap diff --git a/integrationtests/fixtures/snapshots/typescript/hover/class-method.snap b/integrationtests/snapshots/typescript/hover/class-method.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/hover/class-method.snap rename to integrationtests/snapshots/typescript/hover/class-method.snap diff --git a/integrationtests/fixtures/snapshots/typescript/hover/class.snap b/integrationtests/snapshots/typescript/hover/class.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/hover/class.snap rename to integrationtests/snapshots/typescript/hover/class.snap diff --git a/integrationtests/fixtures/snapshots/typescript/hover/constant.snap b/integrationtests/snapshots/typescript/hover/constant.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/hover/constant.snap rename to integrationtests/snapshots/typescript/hover/constant.snap diff --git a/integrationtests/fixtures/snapshots/typescript/hover/function.snap b/integrationtests/snapshots/typescript/hover/function.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/hover/function.snap rename to integrationtests/snapshots/typescript/hover/function.snap diff --git a/integrationtests/fixtures/snapshots/typescript/hover/interface-type.snap b/integrationtests/snapshots/typescript/hover/interface-type.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/hover/interface-type.snap rename to integrationtests/snapshots/typescript/hover/interface-type.snap diff --git a/integrationtests/fixtures/snapshots/typescript/hover/no-hover-info.snap b/integrationtests/snapshots/typescript/hover/no-hover-info.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/hover/no-hover-info.snap rename to integrationtests/snapshots/typescript/hover/no-hover-info.snap diff --git a/integrationtests/fixtures/snapshots/typescript/hover/type.snap b/integrationtests/snapshots/typescript/hover/type.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/hover/type.snap rename to integrationtests/snapshots/typescript/hover/type.snap diff --git a/integrationtests/fixtures/snapshots/typescript/hover/variable.snap b/integrationtests/snapshots/typescript/hover/variable.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/hover/variable.snap rename to integrationtests/snapshots/typescript/hover/variable.snap diff --git a/integrationtests/fixtures/snapshots/typescript/references/class-method.snap b/integrationtests/snapshots/typescript/references/class-method.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/references/class-method.snap rename to integrationtests/snapshots/typescript/references/class-method.snap diff --git a/integrationtests/fixtures/snapshots/typescript/references/interface-method.snap b/integrationtests/snapshots/typescript/references/interface-method.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/references/interface-method.snap rename to integrationtests/snapshots/typescript/references/interface-method.snap diff --git a/integrationtests/fixtures/snapshots/typescript/references/shared-class.snap b/integrationtests/snapshots/typescript/references/shared-class.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/references/shared-class.snap rename to integrationtests/snapshots/typescript/references/shared-class.snap diff --git a/integrationtests/fixtures/snapshots/typescript/references/shared-constant.snap b/integrationtests/snapshots/typescript/references/shared-constant.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/references/shared-constant.snap rename to integrationtests/snapshots/typescript/references/shared-constant.snap diff --git a/integrationtests/fixtures/snapshots/typescript/references/shared-enum.snap b/integrationtests/snapshots/typescript/references/shared-enum.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/references/shared-enum.snap rename to integrationtests/snapshots/typescript/references/shared-enum.snap diff --git a/integrationtests/fixtures/snapshots/typescript/references/shared-function.snap b/integrationtests/snapshots/typescript/references/shared-function.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/references/shared-function.snap rename to integrationtests/snapshots/typescript/references/shared-function.snap diff --git a/integrationtests/fixtures/snapshots/typescript/references/shared-interface.snap b/integrationtests/snapshots/typescript/references/shared-interface.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/references/shared-interface.snap rename to integrationtests/snapshots/typescript/references/shared-interface.snap diff --git a/integrationtests/fixtures/snapshots/typescript/references/shared-type.snap b/integrationtests/snapshots/typescript/references/shared-type.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/references/shared-type.snap rename to integrationtests/snapshots/typescript/references/shared-type.snap diff --git a/integrationtests/fixtures/snapshots/typescript/references/test-function.snap b/integrationtests/snapshots/typescript/references/test-function.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/references/test-function.snap rename to integrationtests/snapshots/typescript/references/test-function.snap diff --git a/integrationtests/fixtures/snapshots/typescript/rename_symbol/not_found.snap b/integrationtests/snapshots/typescript/rename_symbol/not_found.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/rename_symbol/not_found.snap rename to integrationtests/snapshots/typescript/rename_symbol/not_found.snap diff --git a/integrationtests/fixtures/snapshots/typescript/rename_symbol/successful.snap b/integrationtests/snapshots/typescript/rename_symbol/successful.snap similarity index 100% rename from integrationtests/fixtures/snapshots/typescript/rename_symbol/successful.snap rename to integrationtests/snapshots/typescript/rename_symbol/successful.snap diff --git a/integrationtests/languages/common/framework.go b/integrationtests/tests/common/framework.go similarity index 100% rename from integrationtests/languages/common/framework.go rename to integrationtests/tests/common/framework.go diff --git a/integrationtests/languages/common/helpers.go b/integrationtests/tests/common/helpers.go similarity index 97% rename from integrationtests/languages/common/helpers.go rename to integrationtests/tests/common/helpers.go index 4c58662..76ea59a 100644 --- a/integrationtests/languages/common/helpers.go +++ b/integrationtests/tests/common/helpers.go @@ -152,7 +152,7 @@ func SnapshotTest(t *testing.T, languageName, toolName, testName, actualResult s } // Build path based on language/tool/testName hierarchy - snapshotDir := filepath.Join(repoRoot, "integrationtests", "fixtures", "snapshots", languageName, toolName) + snapshotDir := filepath.Join(repoRoot, "integrationtests", "snapshots", languageName, toolName) if err := os.MkdirAll(snapshotDir, 0755); err != nil { t.Fatalf("Failed to create snapshots directory: %v", err) } diff --git a/integrationtests/languages/go/codelens/codelens_test.go b/integrationtests/tests/go/codelens/codelens_test.go similarity index 93% rename from integrationtests/languages/go/codelens/codelens_test.go rename to integrationtests/tests/go/codelens/codelens_test.go index 57714f7..b6ef165 100644 --- a/integrationtests/languages/go/codelens/codelens_test.go +++ b/integrationtests/tests/go/codelens/codelens_test.go @@ -7,13 +7,15 @@ import ( "testing" "time" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/go/internal" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/go/internal" "github.com/isaacphi/mcp-language-server/internal/tools" ) // TestCodeLens tests the codelens functionality with the Go language server func TestCodeLens(t *testing.T) { + t.Skip("Remove this line to run codelens tool tests") + // Test GetCodeLens with a file that should have codelenses t.Run("GetCodeLens", func(t *testing.T) { suite := internal.GetTestSuite(t) diff --git a/integrationtests/languages/go/definition/definition_test.go b/integrationtests/tests/go/definition/definition_test.go similarity index 92% rename from integrationtests/languages/go/definition/definition_test.go rename to integrationtests/tests/go/definition/definition_test.go index 884d672..39ed6d8 100644 --- a/integrationtests/languages/go/definition/definition_test.go +++ b/integrationtests/tests/go/definition/definition_test.go @@ -6,8 +6,8 @@ import ( "testing" "time" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/go/internal" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/go/internal" "github.com/isaacphi/mcp-language-server/internal/tools" ) @@ -83,7 +83,7 @@ func TestReadDefinition(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { // Call the ReadDefinition tool - result, err := tools.ReadDefinition(ctx, suite.Client, tc.symbolName, true) + result, err := tools.ReadDefinition(ctx, suite.Client, tc.symbolName) if err != nil { t.Fatalf("Failed to read definition: %v", err) } diff --git a/integrationtests/languages/go/diagnostics/diagnostics_test.go b/integrationtests/tests/go/diagnostics/diagnostics_test.go similarity index 97% rename from integrationtests/languages/go/diagnostics/diagnostics_test.go rename to integrationtests/tests/go/diagnostics/diagnostics_test.go index b66b632..7b7a666 100644 --- a/integrationtests/languages/go/diagnostics/diagnostics_test.go +++ b/integrationtests/tests/go/diagnostics/diagnostics_test.go @@ -8,8 +8,8 @@ import ( "testing" "time" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/go/internal" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/go/internal" "github.com/isaacphi/mcp-language-server/internal/protocol" "github.com/isaacphi/mcp-language-server/internal/tools" ) diff --git a/integrationtests/languages/go/hover/hover_test.go b/integrationtests/tests/go/hover/hover_test.go similarity index 95% rename from integrationtests/languages/go/hover/hover_test.go rename to integrationtests/tests/go/hover/hover_test.go index d9b063e..f879631 100644 --- a/integrationtests/languages/go/hover/hover_test.go +++ b/integrationtests/tests/go/hover/hover_test.go @@ -7,8 +7,8 @@ import ( "testing" "time" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/go/internal" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/go/internal" "github.com/isaacphi/mcp-language-server/internal/tools" ) diff --git a/integrationtests/languages/go/internal/helpers.go b/integrationtests/tests/go/internal/helpers.go similarity index 91% rename from integrationtests/languages/go/internal/helpers.go rename to integrationtests/tests/go/internal/helpers.go index a0e83c3..4551fe8 100644 --- a/integrationtests/languages/go/internal/helpers.go +++ b/integrationtests/tests/go/internal/helpers.go @@ -5,7 +5,7 @@ import ( "path/filepath" "testing" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" ) // GetTestSuite returns a test suite for Go language server tests diff --git a/integrationtests/languages/go/references/references_test.go b/integrationtests/tests/go/references/references_test.go similarity index 95% rename from integrationtests/languages/go/references/references_test.go rename to integrationtests/tests/go/references/references_test.go index 8a22d71..895aaee 100644 --- a/integrationtests/languages/go/references/references_test.go +++ b/integrationtests/tests/go/references/references_test.go @@ -6,8 +6,8 @@ import ( "testing" "time" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/go/internal" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/go/internal" "github.com/isaacphi/mcp-language-server/internal/tools" ) @@ -94,7 +94,7 @@ func TestFindReferences(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { // Call the FindReferences tool - result, err := tools.FindReferences(ctx, suite.Client, tc.symbolName, true) + result, err := tools.FindReferences(ctx, suite.Client, tc.symbolName) if err != nil { t.Fatalf("Failed to find references: %v", err) } diff --git a/integrationtests/languages/go/rename_symbol/rename_symbol_test.go b/integrationtests/tests/go/rename_symbol/rename_symbol_test.go similarity index 95% rename from integrationtests/languages/go/rename_symbol/rename_symbol_test.go rename to integrationtests/tests/go/rename_symbol/rename_symbol_test.go index a6e86fb..c5ea44a 100644 --- a/integrationtests/languages/go/rename_symbol/rename_symbol_test.go +++ b/integrationtests/tests/go/rename_symbol/rename_symbol_test.go @@ -7,8 +7,8 @@ import ( "testing" "time" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/go/internal" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/go/internal" "github.com/isaacphi/mcp-language-server/internal/tools" ) diff --git a/integrationtests/languages/go/text_edit/text_edit_test.go b/integrationtests/tests/go/text_edit/text_edit_test.go similarity index 98% rename from integrationtests/languages/go/text_edit/text_edit_test.go rename to integrationtests/tests/go/text_edit/text_edit_test.go index dfab657..38f3cdc 100644 --- a/integrationtests/languages/go/text_edit/text_edit_test.go +++ b/integrationtests/tests/go/text_edit/text_edit_test.go @@ -7,8 +7,8 @@ import ( "testing" "time" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/go/internal" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/go/internal" "github.com/isaacphi/mcp-language-server/internal/tools" ) diff --git a/integrationtests/languages/python/definition/definition_test.go b/integrationtests/tests/python/definition/definition_test.go similarity index 93% rename from integrationtests/languages/python/definition/definition_test.go rename to integrationtests/tests/python/definition/definition_test.go index 48b6992..3d3d573 100644 --- a/integrationtests/languages/python/definition/definition_test.go +++ b/integrationtests/tests/python/definition/definition_test.go @@ -6,8 +6,8 @@ import ( "testing" "time" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/python/internal" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/python/internal" "github.com/isaacphi/mcp-language-server/internal/tools" ) @@ -80,7 +80,7 @@ func TestReadDefinition(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { // Call the ReadDefinition tool - result, err := tools.ReadDefinition(ctx, suite.Client, tc.symbolName, true) + result, err := tools.ReadDefinition(ctx, suite.Client, tc.symbolName) if err != nil { t.Fatalf("Failed to read definition: %v", err) } diff --git a/integrationtests/languages/python/diagnostics/diagnostics_test.go b/integrationtests/tests/python/diagnostics/diagnostics_test.go similarity index 97% rename from integrationtests/languages/python/diagnostics/diagnostics_test.go rename to integrationtests/tests/python/diagnostics/diagnostics_test.go index eb0d545..932ae87 100644 --- a/integrationtests/languages/python/diagnostics/diagnostics_test.go +++ b/integrationtests/tests/python/diagnostics/diagnostics_test.go @@ -8,8 +8,8 @@ import ( "testing" "time" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/python/internal" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/python/internal" "github.com/isaacphi/mcp-language-server/internal/protocol" "github.com/isaacphi/mcp-language-server/internal/tools" ) diff --git a/integrationtests/languages/python/hover/hover_test.go b/integrationtests/tests/python/hover/hover_test.go similarity index 86% rename from integrationtests/languages/python/hover/hover_test.go rename to integrationtests/tests/python/hover/hover_test.go index d41ca03..4554aa1 100644 --- a/integrationtests/languages/python/hover/hover_test.go +++ b/integrationtests/tests/python/hover/hover_test.go @@ -7,8 +7,8 @@ import ( "testing" "time" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/python/internal" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/python/internal" "github.com/isaacphi/mcp-language-server/internal/tools" ) @@ -119,7 +119,14 @@ func TestHover(t *testing.T) { if err != nil { // For the "OutsideFile" test, we expect an error if tt.name == "OutsideFile" { - // Create a snapshot even for error case + if tt.expectedText != "" && !strings.Contains(result, tt.expectedText) { + t.Errorf("Expected hover info to contain %q but got: %s", tt.expectedText, result) + } + + // Verify unexpected content is absent + if tt.unexpectedText != "" && strings.Contains(result, tt.unexpectedText) { + t.Errorf("Expected hover info NOT to contain %q but it was found: %s", tt.unexpectedText, result) + } common.SnapshotTest(t, "python", "hover", tt.snapshotName, err.Error()) return } diff --git a/integrationtests/languages/python/internal/helpers.go b/integrationtests/tests/python/internal/helpers.go similarity index 92% rename from integrationtests/languages/python/internal/helpers.go rename to integrationtests/tests/python/internal/helpers.go index 78806f5..8b4b97e 100644 --- a/integrationtests/languages/python/internal/helpers.go +++ b/integrationtests/tests/python/internal/helpers.go @@ -5,7 +5,7 @@ import ( "path/filepath" "testing" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" ) // GetTestSuite returns a test suite for Python language server tests diff --git a/integrationtests/languages/python/references/references_test.go b/integrationtests/tests/python/references/references_test.go similarity index 95% rename from integrationtests/languages/python/references/references_test.go rename to integrationtests/tests/python/references/references_test.go index 954969e..a3df725 100644 --- a/integrationtests/languages/python/references/references_test.go +++ b/integrationtests/tests/python/references/references_test.go @@ -6,8 +6,8 @@ import ( "testing" "time" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/python/internal" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/python/internal" "github.com/isaacphi/mcp-language-server/internal/tools" ) @@ -80,7 +80,7 @@ func TestFindReferences(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { // Call the FindReferences tool - result, err := tools.FindReferences(ctx, suite.Client, tc.symbolName, true) + result, err := tools.FindReferences(ctx, suite.Client, tc.symbolName) if err != nil { t.Fatalf("Failed to find references: %v", err) } diff --git a/integrationtests/languages/python/rename_symbol/rename_symbol_test.go b/integrationtests/tests/python/rename_symbol/rename_symbol_test.go similarity index 96% rename from integrationtests/languages/python/rename_symbol/rename_symbol_test.go rename to integrationtests/tests/python/rename_symbol/rename_symbol_test.go index 2e5f9d8..741e1fe 100644 --- a/integrationtests/languages/python/rename_symbol/rename_symbol_test.go +++ b/integrationtests/tests/python/rename_symbol/rename_symbol_test.go @@ -7,8 +7,8 @@ import ( "testing" "time" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/python/internal" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/python/internal" "github.com/isaacphi/mcp-language-server/internal/tools" ) diff --git a/integrationtests/languages/rust/definition/definition_test.go b/integrationtests/tests/rust/definition/definition_test.go similarity index 94% rename from integrationtests/languages/rust/definition/definition_test.go rename to integrationtests/tests/rust/definition/definition_test.go index 478a255..479fcb8 100644 --- a/integrationtests/languages/rust/definition/definition_test.go +++ b/integrationtests/tests/rust/definition/definition_test.go @@ -7,8 +7,8 @@ import ( "testing" "time" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/rust/internal" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/rust/internal" "github.com/isaacphi/mcp-language-server/internal/tools" ) @@ -103,7 +103,7 @@ func TestReadDefinition(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { // Call the ReadDefinition tool - result, err := tools.ReadDefinition(ctx, suite.Client, tc.symbolName, true) + result, err := tools.ReadDefinition(ctx, suite.Client, tc.symbolName) if err != nil { t.Fatalf("Failed to read definition: %v", err) } diff --git a/integrationtests/languages/rust/diagnostics/diagnostics_test.go b/integrationtests/tests/rust/diagnostics/diagnostics_test.go similarity index 97% rename from integrationtests/languages/rust/diagnostics/diagnostics_test.go rename to integrationtests/tests/rust/diagnostics/diagnostics_test.go index baf88bf..a00a05f 100644 --- a/integrationtests/languages/rust/diagnostics/diagnostics_test.go +++ b/integrationtests/tests/rust/diagnostics/diagnostics_test.go @@ -8,8 +8,8 @@ import ( "testing" "time" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/rust/internal" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/rust/internal" "github.com/isaacphi/mcp-language-server/internal/protocol" "github.com/isaacphi/mcp-language-server/internal/tools" ) diff --git a/integrationtests/languages/rust/hover/hover_test.go b/integrationtests/tests/rust/hover/hover_test.go similarity index 96% rename from integrationtests/languages/rust/hover/hover_test.go rename to integrationtests/tests/rust/hover/hover_test.go index 8d5f1fe..55488fa 100644 --- a/integrationtests/languages/rust/hover/hover_test.go +++ b/integrationtests/tests/rust/hover/hover_test.go @@ -7,8 +7,8 @@ import ( "testing" "time" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/rust/internal" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/rust/internal" "github.com/isaacphi/mcp-language-server/internal/tools" ) diff --git a/integrationtests/languages/rust/internal/helpers.go b/integrationtests/tests/rust/internal/helpers.go similarity index 92% rename from integrationtests/languages/rust/internal/helpers.go rename to integrationtests/tests/rust/internal/helpers.go index 1e075bd..ba227c1 100644 --- a/integrationtests/languages/rust/internal/helpers.go +++ b/integrationtests/tests/rust/internal/helpers.go @@ -5,7 +5,7 @@ import ( "path/filepath" "testing" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" ) // GetTestSuite returns a test suite for Rust language server tests diff --git a/integrationtests/languages/rust/references/references_test.go b/integrationtests/tests/rust/references/references_test.go similarity index 95% rename from integrationtests/languages/rust/references/references_test.go rename to integrationtests/tests/rust/references/references_test.go index 7a76a76..a4eca26 100644 --- a/integrationtests/languages/rust/references/references_test.go +++ b/integrationtests/tests/rust/references/references_test.go @@ -7,8 +7,8 @@ import ( "testing" "time" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/rust/internal" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/rust/internal" "github.com/isaacphi/mcp-language-server/internal/tools" ) @@ -113,7 +113,7 @@ func TestFindReferences(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { // Call the FindReferences tool - result, err := tools.FindReferences(ctx, suite.Client, tc.symbolName, true) + result, err := tools.FindReferences(ctx, suite.Client, tc.symbolName) if err != nil { t.Fatalf("Failed to find references: %v", err) } diff --git a/integrationtests/languages/rust/rename_symbol/rename_symbol_test.go b/integrationtests/tests/rust/rename_symbol/rename_symbol_test.go similarity index 96% rename from integrationtests/languages/rust/rename_symbol/rename_symbol_test.go rename to integrationtests/tests/rust/rename_symbol/rename_symbol_test.go index e826494..339584d 100644 --- a/integrationtests/languages/rust/rename_symbol/rename_symbol_test.go +++ b/integrationtests/tests/rust/rename_symbol/rename_symbol_test.go @@ -7,8 +7,8 @@ import ( "testing" "time" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/rust/internal" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/rust/internal" "github.com/isaacphi/mcp-language-server/internal/tools" ) diff --git a/integrationtests/languages/typescript/definition/definition_test.go b/integrationtests/tests/typescript/definition/definition_test.go similarity index 92% rename from integrationtests/languages/typescript/definition/definition_test.go rename to integrationtests/tests/typescript/definition/definition_test.go index 8f1da69..f7668f0 100644 --- a/integrationtests/languages/typescript/definition/definition_test.go +++ b/integrationtests/tests/typescript/definition/definition_test.go @@ -6,8 +6,8 @@ import ( "testing" "time" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/typescript/internal" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/typescript/internal" "github.com/isaacphi/mcp-language-server/internal/tools" ) @@ -71,7 +71,7 @@ func TestReadDefinition(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { // Call the ReadDefinition tool - result, err := tools.ReadDefinition(ctx, suite.Client, tc.symbolName, true) + result, err := tools.ReadDefinition(ctx, suite.Client, tc.symbolName) if err != nil { t.Fatalf("Failed to read definition: %v", err) } diff --git a/integrationtests/languages/typescript/diagnostics/diagnostics_test.go b/integrationtests/tests/typescript/diagnostics/diagnostics_test.go similarity index 97% rename from integrationtests/languages/typescript/diagnostics/diagnostics_test.go rename to integrationtests/tests/typescript/diagnostics/diagnostics_test.go index ba0f79a..aa7949a 100644 --- a/integrationtests/languages/typescript/diagnostics/diagnostics_test.go +++ b/integrationtests/tests/typescript/diagnostics/diagnostics_test.go @@ -8,8 +8,8 @@ import ( "testing" "time" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/typescript/internal" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/typescript/internal" "github.com/isaacphi/mcp-language-server/internal/protocol" "github.com/isaacphi/mcp-language-server/internal/tools" ) diff --git a/integrationtests/languages/typescript/hover/hover_test.go b/integrationtests/tests/typescript/hover/hover_test.go similarity index 82% rename from integrationtests/languages/typescript/hover/hover_test.go rename to integrationtests/tests/typescript/hover/hover_test.go index cc9c8cf..c061781 100644 --- a/integrationtests/languages/typescript/hover/hover_test.go +++ b/integrationtests/tests/typescript/hover/hover_test.go @@ -7,8 +7,8 @@ import ( "testing" "time" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/typescript/internal" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/typescript/internal" "github.com/isaacphi/mcp-language-server/internal/tools" ) @@ -119,8 +119,16 @@ func TestHover(t *testing.T) { if err != nil { // For the "OutsideFile" test, we expect an error if tt.name == "OutsideFile" { - // Create a snapshot even for error case - common.SnapshotTest(t, "typescript", "hover", tt.snapshotName, err.Error()) + if tt.expectedText != "" && !strings.Contains(result, tt.expectedText) { + t.Errorf("Expected hover info to contain %q but got: %s", tt.expectedText, result) + } + + // Verify unexpected content is absent + if tt.unexpectedText != "" && strings.Contains(result, tt.unexpectedText) { + t.Errorf("Expected hover info NOT to contain %q but it was found: %s", tt.unexpectedText, result) + } + // Skip snapshot because CI contains unique paths in output + //common.SnapshotTest(t, "typescript", "hover", tt.snapshotName, err.Error()) return } t.Fatalf("GetHoverInfo failed: %v", err) diff --git a/integrationtests/languages/typescript/internal/helpers.go b/integrationtests/tests/typescript/internal/helpers.go similarity index 92% rename from integrationtests/languages/typescript/internal/helpers.go rename to integrationtests/tests/typescript/internal/helpers.go index 5d15cb0..eca762a 100644 --- a/integrationtests/languages/typescript/internal/helpers.go +++ b/integrationtests/tests/typescript/internal/helpers.go @@ -5,7 +5,7 @@ import ( "path/filepath" "testing" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" ) // GetTestSuite returns a test suite for TypeScript language server tests diff --git a/integrationtests/languages/typescript/references/references_test.go b/integrationtests/tests/typescript/references/references_test.go similarity index 96% rename from integrationtests/languages/typescript/references/references_test.go rename to integrationtests/tests/typescript/references/references_test.go index cee539e..d3e3246 100644 --- a/integrationtests/languages/typescript/references/references_test.go +++ b/integrationtests/tests/typescript/references/references_test.go @@ -7,8 +7,8 @@ import ( "testing" "time" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/typescript/internal" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/typescript/internal" "github.com/isaacphi/mcp-language-server/internal/tools" ) @@ -115,7 +115,7 @@ func TestFindReferences(t *testing.T) { for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { // Call the FindReferences tool - result, err := tools.FindReferences(ctx, suite.Client, tc.symbolName, true) + result, err := tools.FindReferences(ctx, suite.Client, tc.symbolName) if err != nil { t.Fatalf("Failed to find references: %v", err) } diff --git a/integrationtests/languages/typescript/rename_symbol/rename_symbol_test.go b/integrationtests/tests/typescript/rename_symbol/rename_symbol_test.go similarity index 96% rename from integrationtests/languages/typescript/rename_symbol/rename_symbol_test.go rename to integrationtests/tests/typescript/rename_symbol/rename_symbol_test.go index e01a2f0..63ba8be 100644 --- a/integrationtests/languages/typescript/rename_symbol/rename_symbol_test.go +++ b/integrationtests/tests/typescript/rename_symbol/rename_symbol_test.go @@ -7,8 +7,8 @@ import ( "testing" "time" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/common" - "github.com/isaacphi/mcp-language-server/integrationtests/languages/typescript/internal" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/common" + "github.com/isaacphi/mcp-language-server/integrationtests/tests/typescript/internal" "github.com/isaacphi/mcp-language-server/internal/tools" ) diff --git a/internal/lsp/client.go b/internal/lsp/client.go index 72559aa..5bda716 100644 --- a/internal/lsp/client.go +++ b/internal/lsp/client.go @@ -218,10 +218,10 @@ func (c *Client) InitializeLSPClient(ctx context.Context, workspaceDir string) ( path := strings.ToLower(c.Cmd.Path) switch { case strings.Contains(path, "typescript-language-server"): - // err := initializeTypescriptLanguageServer(ctx, c, workspaceDir) - // if err != nil { - // return nil, err - // } + err := initializeTypescriptLanguageServer(ctx, c, workspaceDir) + if err != nil { + return nil, err + } } return &result, nil diff --git a/internal/lsp/typescript.go b/internal/lsp/typescript.go new file mode 100644 index 0000000..f4b5ee1 --- /dev/null +++ b/internal/lsp/typescript.go @@ -0,0 +1,65 @@ +package lsp + +import ( + "context" + "fmt" + "os" + "path/filepath" + "strings" +) + +// initializeTypescriptLanguageServer initializes the TypeScript language server +// with specific configurations and opens all TypeScript files in the workspace. +func initializeTypescriptLanguageServer(ctx context.Context, client *Client, workspaceDir string) error { + lspLogger.Info("Initializing TypeScript language server with workspace: %s", workspaceDir) + + // First, open all TypeScript files in the workspace + if err := openAllTypeScriptFiles(ctx, client, workspaceDir); err != nil { + return fmt.Errorf("failed to open TypeScript files: %w", err) + } + + return nil +} + +// openAllTypeScriptFiles finds and opens all TypeScript files in the workspace +func openAllTypeScriptFiles(ctx context.Context, client *Client, workspaceDir string) error { + lspLogger.Info("Opening all TypeScript files in workspace: %s", workspaceDir) + + // Track count of opened files for logging + fileCount := 0 + + // Walk the workspace directory + err := filepath.Walk(workspaceDir, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + // Skip directories + if info.IsDir() { + // Skip node_modules, .git, and other common directories to avoid processing too many files + basename := filepath.Base(path) + if basename == "node_modules" || basename == ".git" || strings.HasPrefix(basename, ".") { + return filepath.SkipDir + } + return nil + } + + // Check if file is a TypeScript file + if strings.HasSuffix(path, ".ts") || strings.HasSuffix(path, ".tsx") { + if err := client.OpenFile(ctx, path); err != nil { + lspLogger.Warn("Failed to open TypeScript file %s: %v", path, err) + return nil // Continue with other files even if one fails + } + fileCount++ + } + + return nil + }) + + if err != nil { + return fmt.Errorf("error walking workspace directory: %w", err) + } + + lspLogger.Info("Opened %d TypeScript files", fileCount) + return nil +} diff --git a/internal/tools/read-definition.go b/internal/tools/definition.go similarity index 94% rename from internal/tools/read-definition.go rename to internal/tools/definition.go index 004d2d3..0045a62 100644 --- a/internal/tools/read-definition.go +++ b/internal/tools/definition.go @@ -9,7 +9,7 @@ import ( "github.com/isaacphi/mcp-language-server/internal/protocol" ) -func ReadDefinition(ctx context.Context, client *lsp.Client, symbolName string, showLineNumbers bool) (string, error) { +func ReadDefinition(ctx context.Context, client *lsp.Client, symbolName string) (string, error) { symbolResult, err := client.Symbol(ctx, protocol.WorkspaceSymbolParams{ Query: symbolName, }) @@ -85,9 +85,7 @@ func ReadDefinition(ctx context.Context, client *lsp.Client, symbolName string, continue } - if showLineNumbers { - definition = addLineNumbers(definition, int(loc.Range.Start.Line)+1) - } + definition = addLineNumbers(definition, int(loc.Range.Start.Line)+1) definitions = append(definitions, banner+locationInfo+definition+"\n") } diff --git a/internal/tools/apply-text-edit.go b/internal/tools/edit_file.go similarity index 100% rename from internal/tools/apply-text-edit.go rename to internal/tools/edit_file.go diff --git a/internal/tools/find-references.go b/internal/tools/references.go similarity index 98% rename from internal/tools/find-references.go rename to internal/tools/references.go index 2e2bca1..4af25da 100644 --- a/internal/tools/find-references.go +++ b/internal/tools/references.go @@ -12,7 +12,7 @@ import ( "github.com/isaacphi/mcp-language-server/internal/protocol" ) -func FindReferences(ctx context.Context, client *lsp.Client, symbolName string, showLineNumbers bool) (string, error) { +func FindReferences(ctx context.Context, client *lsp.Client, symbolName string) (string, error) { // Get context lines from environment variable contextLines := 5 if envLines := os.Getenv("LSP_CONTEXT_LINES"); envLines != "" { diff --git a/tools.go b/tools.go index a478ec1..55898ca 100644 --- a/tools.go +++ b/tools.go @@ -11,11 +11,29 @@ import ( func (s *mcpServer) registerTools() error { coreLogger.Debug("Registering MCP tools") - applyTextEditTool := mcp.NewTool("apply_text_edit", + applyTextEditTool := mcp.NewTool("edit_file", mcp.WithDescription("Apply multiple text edits to a file."), - mcp.WithObject("edits", + mcp.WithArray("edits", mcp.Required(), mcp.Description("List of edits to apply"), + mcp.Items(map[string]any{ + "type": "object", + "properties": map[string]any{ + "startLine": map[string]any{ + "type": "number", + "description": "Start line to replace, inclusive, one-indexed", + }, + "endLine": map[string]any{ + "type": "number", + "description": "End line to replace, inclusive, one-indexed", + }, + "newText": map[string]any{ + "type": "string", + "description": "Replacement text. Replace with the new text. Leave blank to remove lines.", + }, + }, + "required": []string{"startLine", "endLine"}, + }), ), mcp.WithString("filePath", mcp.Required(), @@ -68,7 +86,7 @@ func (s *mcpServer) registerTools() error { }) } - coreLogger.Debug("Executing apply_text_edit for file: %s", filePath) + coreLogger.Debug("Executing edit_file for file: %s", filePath) response, err := tools.ApplyTextEdits(s.ctx, s.lspClient, filePath, edits) if err != nil { coreLogger.Error("Failed to apply edits: %v", err) @@ -77,16 +95,12 @@ func (s *mcpServer) registerTools() error { return mcp.NewToolResultText(response), nil }) - readDefinitionTool := mcp.NewTool("read_definition", + readDefinitionTool := mcp.NewTool("definition", mcp.WithDescription("Read the source code definition of a symbol (function, type, constant, etc.) from the codebase. Returns the complete implementation code where the symbol is defined."), mcp.WithString("symbolName", mcp.Required(), mcp.Description("The name of the symbol whose definition you want to find (e.g. 'mypackage.MyFunction', 'MyType.MyMethod')"), ), - mcp.WithBoolean("showLineNumbers", - mcp.Description("Include line numbers in the returned source code"), - mcp.DefaultBool(true), - ), ) s.mcpServer.AddTool(readDefinitionTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { @@ -96,13 +110,8 @@ func (s *mcpServer) registerTools() error { return mcp.NewToolResultError("symbolName must be a string"), nil } - showLineNumbers := true // default value - if showLineNumbersArg, ok := request.Params.Arguments["showLineNumbers"].(bool); ok { - showLineNumbers = showLineNumbersArg - } - - coreLogger.Debug("Executing read_definition for symbol: %s", symbolName) - text, err := tools.ReadDefinition(s.ctx, s.lspClient, symbolName, showLineNumbers) + coreLogger.Debug("Executing definition for symbol: %s", symbolName) + text, err := tools.ReadDefinition(s.ctx, s.lspClient, symbolName) if err != nil { coreLogger.Error("Failed to get definition: %v", err) return mcp.NewToolResultError(fmt.Sprintf("failed to get definition: %v", err)), nil @@ -110,16 +119,12 @@ func (s *mcpServer) registerTools() error { return mcp.NewToolResultText(text), nil }) - findReferencesTool := mcp.NewTool("find_references", + findReferencesTool := mcp.NewTool("references", mcp.WithDescription("Find all usages and references of a symbol throughout the codebase. Returns a list of all files and locations where the symbol appears."), mcp.WithString("symbolName", mcp.Required(), mcp.Description("The name of the symbol to search for (e.g. 'mypackage.MyFunction', 'MyType')"), ), - mcp.WithBoolean("showLineNumbers", - mcp.Description("Include line numbers when showing where the symbol is used"), - mcp.DefaultBool(true), - ), ) s.mcpServer.AddTool(findReferencesTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { @@ -129,13 +134,8 @@ func (s *mcpServer) registerTools() error { return mcp.NewToolResultError("symbolName must be a string"), nil } - showLineNumbers := true // default value - if showLineNumbersArg, ok := request.Params.Arguments["showLineNumbers"].(bool); ok { - showLineNumbers = showLineNumbersArg - } - - coreLogger.Debug("Executing find_references for symbol: %s", symbolName) - text, err := tools.FindReferences(s.ctx, s.lspClient, symbolName, showLineNumbers) + coreLogger.Debug("Executing references for symbol: %s", symbolName) + text, err := tools.FindReferences(s.ctx, s.lspClient, symbolName) if err != nil { coreLogger.Error("Failed to find references: %v", err) return mcp.NewToolResultError(fmt.Sprintf("failed to find references: %v", err)), nil @@ -143,7 +143,7 @@ func (s *mcpServer) registerTools() error { return mcp.NewToolResultText(text), nil }) - getDiagnosticsTool := mcp.NewTool("get_diagnostics", + getDiagnosticsTool := mcp.NewTool("diagnostics", mcp.WithDescription("Get diagnostic information for a specific file from the language server."), mcp.WithString("filePath", mcp.Required(), @@ -176,7 +176,7 @@ func (s *mcpServer) registerTools() error { showLineNumbers = showLineNumbersArg } - coreLogger.Debug("Executing get_diagnostics for file: %s", filePath) + coreLogger.Debug("Executing diagnostics for file: %s", filePath) text, err := tools.GetDiagnosticsForFile(s.ctx, s.lspClient, filePath, contextLines, showLineNumbers) if err != nil { coreLogger.Error("Failed to get diagnostics: %v", err) @@ -185,68 +185,70 @@ func (s *mcpServer) registerTools() error { return mcp.NewToolResultText(text), nil }) - getCodeLensTool := mcp.NewTool("get_codelens", - mcp.WithDescription("Get code lens hints for a given file from the language server."), - mcp.WithString("filePath", - mcp.Required(), - mcp.Description("The path to the file to get code lens information for"), - ), - ) - - s.mcpServer.AddTool(getCodeLensTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - // Extract arguments - filePath, ok := request.Params.Arguments["filePath"].(string) - if !ok { - return mcp.NewToolResultError("filePath must be a string"), nil - } - - coreLogger.Debug("Executing get_codelens for file: %s", filePath) - text, err := tools.GetCodeLens(s.ctx, s.lspClient, filePath) - if err != nil { - coreLogger.Error("Failed to get code lens: %v", err) - return mcp.NewToolResultError(fmt.Sprintf("failed to get code lens: %v", err)), nil - } - return mcp.NewToolResultText(text), nil - }) - - executeCodeLensTool := mcp.NewTool("execute_codelens", - mcp.WithDescription("Execute a code lens command for a given file and lens index."), - mcp.WithString("filePath", - mcp.Required(), - mcp.Description("The path to the file containing the code lens to execute"), - ), - mcp.WithNumber("index", - mcp.Required(), - mcp.Description("The index of the code lens to execute (from get_codelens output), 1 indexed"), - ), - ) - - s.mcpServer.AddTool(executeCodeLensTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - // Extract arguments - filePath, ok := request.Params.Arguments["filePath"].(string) - if !ok { - return mcp.NewToolResultError("filePath must be a string"), nil - } - - // Handle both float64 and int for index due to JSON parsing - var index int - switch v := request.Params.Arguments["index"].(type) { - case float64: - index = int(v) - case int: - index = v - default: - return mcp.NewToolResultError("index must be a number"), nil - } - - coreLogger.Debug("Executing execute_codelens for file: %s index: %d", filePath, index) - text, err := tools.ExecuteCodeLens(s.ctx, s.lspClient, filePath, index) - if err != nil { - coreLogger.Error("Failed to execute code lens: %v", err) - return mcp.NewToolResultError(fmt.Sprintf("failed to execute code lens: %v", err)), nil - } - return mcp.NewToolResultText(text), nil - }) + // Uncomment to add codelens tools + // + // getCodeLensTool := mcp.NewTool("get_codelens", + // mcp.WithDescription("Get code lens hints for a given file from the language server."), + // mcp.WithString("filePath", + // mcp.Required(), + // mcp.Description("The path to the file to get code lens information for"), + // ), + // ) + // + // s.mcpServer.AddTool(getCodeLensTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + // // Extract arguments + // filePath, ok := request.Params.Arguments["filePath"].(string) + // if !ok { + // return mcp.NewToolResultError("filePath must be a string"), nil + // } + // + // coreLogger.Debug("Executing get_codelens for file: %s", filePath) + // text, err := tools.GetCodeLens(s.ctx, s.lspClient, filePath) + // if err != nil { + // coreLogger.Error("Failed to get code lens: %v", err) + // return mcp.NewToolResultError(fmt.Sprintf("failed to get code lens: %v", err)), nil + // } + // return mcp.NewToolResultText(text), nil + // }) + // + // executeCodeLensTool := mcp.NewTool("execute_codelens", + // mcp.WithDescription("Execute a code lens command for a given file and lens index."), + // mcp.WithString("filePath", + // mcp.Required(), + // mcp.Description("The path to the file containing the code lens to execute"), + // ), + // mcp.WithNumber("index", + // mcp.Required(), + // mcp.Description("The index of the code lens to execute (from get_codelens output), 1 indexed"), + // ), + // ) + // + // s.mcpServer.AddTool(executeCodeLensTool, func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { + // // Extract arguments + // filePath, ok := request.Params.Arguments["filePath"].(string) + // if !ok { + // return mcp.NewToolResultError("filePath must be a string"), nil + // } + // + // // Handle both float64 and int for index due to JSON parsing + // var index int + // switch v := request.Params.Arguments["index"].(type) { + // case float64: + // index = int(v) + // case int: + // index = v + // default: + // return mcp.NewToolResultError("index must be a number"), nil + // } + // + // coreLogger.Debug("Executing execute_codelens for file: %s index: %d", filePath, index) + // text, err := tools.ExecuteCodeLens(s.ctx, s.lspClient, filePath, index) + // if err != nil { + // coreLogger.Error("Failed to execute code lens: %v", err) + // return mcp.NewToolResultError(fmt.Sprintf("failed to execute code lens: %v", err)), nil + // } + // return mcp.NewToolResultText(text), nil + // }) hoverTool := mcp.NewTool("hover", mcp.WithDescription("Get hover information (type, documentation) for a symbol at the specified position."),