Shopify/ruby-lsp
63.2
Adequate · 19 September 2026
22.2k
lines of production code
Ruby
with TypeScript
1
measurement over time
What this system is
This system is the Ruby LSP, a language server protocol implementation for the Ruby programming language that provides code intelligence features such as completions, definitions, and diagnostics. It utilizes a Prism-based indexer and a listener-based architecture to efficiently process Ruby source code, supporting both standard Ruby files and ERB templates. The project includes a VS Code extension that manages Ruby version environments and offers a domain-driven design chat agent, alongside a Jekyll-based documentation site.
How it got here
2022 — Open-source release and architectural foundation
21 changes.
This period marks the initial open-source release of the Ruby LSP monorepo, establishing the core project structure and development environment. It introduces a modular architecture featuring an add-on system, a listener-based request pattern, and strict Sorbet typing to support extensibility and reliability. The work also includes comprehensive test coverage and tooling modernization to stabilize the new codebase.
2023–2025 — Indexer rewrite and LSP architecture modernization
19 changes.
This period focused on rebuilding the RubyIndexer with a Prism-based engine and refactoring the Ruby LSP core into a listener and response builder architecture for improved performance and maintainability. The VS Code extension was modernized with a new object-oriented version manager system and a domain-driven design Copilot chat agent, while documentation was consolidated into a Jekyll site.
Features
Added Sorbet RBI annotations for Minitest, Mocha, and Rainbow
This change introduces new Sorbet RBI annotation files for the Minitest, Mocha, and Rainbow libraries, enabling static type checking for code using these gems. The \minitest.rbi\ file defines signatures for assertion and refutation methods within \Minitest::Assertions\, while \mocha.rbi\ provides type signatures for mocking and stubbing APIs in \Mocha::API\, \Mocha::ClassMethods\, \Mocha::Expectation\, and \Mocha::ObjectMethods\. Additionally, \rainbow.rbi\ adds comprehensive type definitions for the Rainbow gem's color manipulation and terminal styling features, including the \Rainbow::Color\ hierarchy and presenter classes. A \.gitattributes\ file is also added to mark these generated RBI files as vendored.
sorbet/rbi/annotations · high confidence
Added Sorbet RBI shims for Bundler, Debug, URI, and RuboCop cops
New RBI shim files have been added to the \sorbet/rbi/shims\ directory to provide static type definitions for external libraries and internal RuboCop cops. These shims cover \Bundler\ (Settings, CLI, Thor::Shell), \DEBUGGER\\\, \DidYouMean::JaroWinkler\, \File\, \Pathname\, \Gem::Specification\, \URI\ (Generic, File, Source), and specific RuboCop cops (\UseLanguageServerAliases\, \UseRegisterWithHandlerMethod\). This improves type coverage for these areas, allowing Sorbet to better analyze code interacting with Bundler, debugging tools, URI handling, and the internal linting infrastructure.
sorbet/rbi/shims · high confidence
Added verification task for indexing against the top 100 RubyGems
A new Rake task, \index:topgems\, has been added to the \rakelib\ directory to verify the indexer's behavior against the top 100 RubyGems. This task downloads the source files for these gems and runs the indexer on them, reporting any errors that occur during the process. The list of gems to be tested is defined in a new \rakelib/top\_100\_gems.yml\ file.
rakelib · high confidence
Documentation site migrated to Jekyll
The project documentation has been consolidated into a new Jekyll-based static site located in the \jekyll\ directory. This change introduces a new build structure using the \just-the-docs\ theme, including configuration for navigation, external links, and callout styles. The site now serves as the single source for user-facing documentation for both the Ruby LSP and the Rails add-on, replacing previous documentation locations and providing a unified experience for editor setup guides, feature descriptions, and contributing instructions.
jekyll · high confidence
Enable Sorbet type checking with Prism parser and RBS support
Sorbet static type checking is now enabled for the project via a new configuration file. This setup configures Sorbet to analyze the root directory while ignoring vendor, tmp, test fixtures, expectations, and Jekyll directories. It activates experimental support for RBS comments and requires\_ancestor, suppresses error code 7019, enables caching to the sorbet/cache directory, and switches the underlying parser to Prism.
sorbet · high confidence
Initial Tapioca configuration and strict-typed require setup
This change introduces the initial configuration for the Tapioca tool within the Sorbet project. A new \config.yml\ file is added to manage gem type overrides (specifically disabling strict typing for \psych\) and to exclude the \rdoc\ gem, which causes failures during RBI generation. Additionally, a new \require.rb\ file is created with \\# typed: strict\ to centralize dependencies for the tooling environment, including \prism\, \syntax\_tree\, \rubocop\, \mocha\, and \test-unit\, while also handling potential load path conflicts with the \yarp\ gem.
sorbet/tapioca · high confidence
Initial open-source release of the Ruby LSP monorepo
This change introduces the complete Ruby LSP project to the repository, establishing the monorepo structure that houses the core \ruby-lsp\ gem, the VS Code extension, and the Jekyll documentation site. It sets the development environment to Ruby 4.0.5 and Node 22.21.1, switches the Node package manager from Yarn to pnpm, and configures the project with Sorbet strict typing, RuboCop linting, and a new test suite that includes indexer tests. The release also includes essential project files such as the MIT license, code of conduct, and detailed \AGENTS.md\ documentation for contributors.
(repo-wide) · high confidence
Introduce Ruby Copilot chat agent for domain-driven design
The extension now includes a new chat participant (rubyLsp.chatAgent) that acts as a Ruby on Rails and domain-driven design expert. Users can interact with this agent to model specific concepts, receiving analysis on core purpose, relationships, and attributes, along with suggested Rails generator commands. The agent reads the application's schema (db/schema.rb or db/structure.sql) to provide context-aware suggestions and offers buttons to directly generate or revert Rails files based on its output.
vscode/src · high confidence
Introduces a new add-on system and refactors core server components
The Ruby LSP now supports a plugin architecture via the new \RubyLsp::Addon\ class, allowing third-party gems to extend the server's capabilities (such as diagnostics, code lenses, and file watching) by inheriting from this base class and implementing \name\ and \activate\. This change is accompanied by a significant internal refactoring: the document handling logic has been split into specific subclasses (\RubyDocument\, \ERBDocument\, \RBSDocument\) inheriting from a new abstract \Document\ base, and the server execution model has been restructured into a \BaseServer\ with a dedicated \ClientCapabilities\ class to manage editor-specific features. These changes provide the foundation for a more modular and extensible LSP experience.
_lib/ruby\lsp · high confidence
New CLI commands and launcher mechanism for dependency management
The \ruby-lsp\ executable now supports new command-line flags: \--time-index\ to measure indexing performance, \--doctor\ to run troubleshooting steps, and \--beta\ to install pre-release server versions. A new \--use-launcher\ flag (experimental) enables a launcher mechanism that handles missing dependencies gracefully by composing a bundle in a forked process. Additionally, two new executables are introduced: \ruby-lsp-check\ to verify that all automatic LSP requests run successfully on Ruby files, and \ruby-lsp-launcher\ to manage the bundle composition and server startup process, including support for Windows compatibility and debug attachment.
exe · high confidence
New RuboCop cops for Ruby LSP code quality
Two new RuboCop cops have been added to enforce best practices within the Ruby LSP module. The \UseLanguageServerAliases\ cop encourages using local aliases (\Interface\, \Transport\, \Constant\) instead of the full \LanguageServer::Protocol\ namespace to reduce verbosity. The \UseRegisterWithHandlerMethod\ cop ensures consistency in listener registration by flagging cases where a handler method is defined without a corresponding \register\ call, or vice versa.
lib/rubocop · high confidence
New object-oriented version manager architecture with support for ASDF, Mise, and rv
The Ruby extension has been refactored to use a new object-oriented architecture for version managers, introducing dedicated classes for ASDF, Mise, and rv alongside existing support for chruby, rbenv, RVM, Shadowenv, and RubyInstaller. This change allows users to configure custom executable paths for ASDF, Mise, rbenv, and rv via settings, and adds specific installation path detection for these tools (e.g., ASDF v0.16+ executables, mise apt installations). The new structure also introduces 'None' and 'Custom' manager types, enabling manual Ruby path configuration or custom shell script activation for environments not covered by standard managers.
vscode/src/ruby · high confidence
Removals
Removal of initial ruby-lsp VS Code extension scaffold
The initial scaffold for the ruby-lsp VS Code extension has been removed, deleting the core implementation file (extension.ts), the test suite, configuration files (tsconfig, eslint, vscode settings), and documentation (README, CHANGELOG, license). This eliminates the placeholder 'Hello World' command and associated development infrastructure from the extension directory.
_features/vscode\extension · high confidence
Removal of the Ruby LSP CLI entry point
The \lib/ruby/lsp/cli.rb\ file, which previously served as the command-line interface for the Ruby LSP server, has been removed. This eliminates the \Ruby::LSP::Cli\ module and its \start\ method, meaning the LSP server can no longer be launched via this specific CLI entry point.
lib/ruby/lsp · high confidence
Architecture
Refactor Ruby LSP requests into a listener-based architecture
The Ruby LSP has migrated its core language features—including code lenses, completions, definitions, document symbols, highlights, links, folding ranges, hovers, inlay hints, and semantic highlighting—from the previous request-based implementation to a new listener pattern. This architectural change decouples request logic from the listener infrastructure, allowing the server to process AST events more efficiently and consistently across different LSP capabilities.
_lib/ruby\lsp/listeners · high confidence
Behavioural changes
Adopts new response builder pattern for LSP features
The Ruby LSP has replaced the previous Listener-based architecture with a new Response Builder pattern. This change introduces dedicated builder classes for managing hover content, document symbols, signature help, and test collections, allowing for more structured and incremental construction of LSP responses. Users benefit from a more robust internal structure that supports features like categorized hover content and improved test code lens generation.
_lib/ruby\_lsp/response\builders · high confidence
Introduce RubyIndexer as a Prism-based indexing engine
The Ruby indexer has been rebuilt from the ground up to use the Prism parser instead of the previous AST-based approach. This new engine introduces a \DeclarationListener\ to process Ruby source files, an \RBSIndexer\ to index core library signatures, and a \PrefixTree\ for fast autocomplete lookups. It also adds a new \Configuration\ class to manage which gems and file patterns are indexed, and uses \URI::Generic\ to track file locations, improving accuracy for features like go-to-definition and references.
_lib/ruby\indexer/lib · high confidence
Introduce dedicated test reporters for Minitest and Test::Unit
The test reporting infrastructure has been reorganized into a dedicated \lib/ruby\_lsp/test\_reporters\ directory, introducing new \MinitestReporter\ and \TestUnitReporter\ classes that replace previous inline implementations. These reporters now communicate with the VS Code extension via a TCP socket (with port discovery via a temporary JSON database) instead of environment variables, ensuring reliable delivery of test start, pass, fail, skip, and error events. The Minitest reporter also adds color-coded output to the terminal and prevents other gems from mutating the reporter list, while the Test::Unit reporter ensures the final summary is printed and handles coverage data exclusion for non-workspace files.
_lib/ruby\_lsp/test\reporters · high confidence
Major internal refactoring and new indexing capabilities
This release introduces significant internal changes to the Ruby LSP server, including a new \RubyIndexer::Entry\ class to manage indexed symbols with configuration and visibility tracking, and a \TypeInferrer\ to improve type resolution for receivers. The server now supports semantic token deltas for more efficient updates, delegates completion requests for ERB files, and adds support for class variables, instance variables, and constants in hover, completion, and definition features. Additionally, the codebase vendors the \PackageURL\ class, restructures the server into a dedicated \server.rb\ file, and implements lazy parsing and document handling to improve performance and stability.
ruby-lsp · high confidence
Refactor bundle environment composition into dedicated scripts
The bundle environment composition logic has been extracted into new \compose\_bundle.rb\ and \compose\_bundle\_windows.rb\ scripts. These scripts now handle parsing the initialize request, determining the workspace path, and writing the resulting environment variables to \.ruby-lsp/bundle\_env\, with the Windows variant specifically supporting a \--beta\ flag to install beta server versions.
_lib/ruby\lsp/scripts · high confidence
Refactored support layer with new helper classes and modules
The support layer for requests has been reorganized into a set of dedicated classes and modules. A new \Support::Common\ module centralizes shared helpers such as range conversion, code lens creation, and constant name extraction. RuboCop integration is now encapsulated in \RuboCopRunner\, \RuboCopFormatter\, and \RuboCopDiagnostic\, which handle offense reporting, severity mapping, and code actions. Formatting capabilities are abstracted via a \Formatter\ interface implemented by \RuboCopFormatter\ and \SyntaxTreeFormatter\. Additional support includes \Annotation\ for matching Sorbet annotations, \TestItem\ for test explorer integration, \SourceUri\ for gem source URIs, and \SelectionRange\ for selection range logic.
_lib/ruby\lsp/requests/support · high confidence
Regenerated Sorbet RBI type definitions for development gems
The Sorbet RBI files in \sorbet/rbi/gems\ have been regenerated to reflect the current state of development dependencies, including \ast\, \benchmark\, \date\, \erb\, \erubi\, \json\, \language\_server-protocol\, \lint\_roller\, \logger\, and \minitest\. This update ensures that static type checking aligns with the latest gem versions and API signatures used in the project.
sorbet/rbi/gems · high confidence
Ruby LSP requests restructured to use the Listener pattern
The Ruby LSP request handlers in lib/ruby\_lsp/requests have been refactored to delegate analysis logic to dedicated Listener classes. This change decouples request orchestration from AST traversal, allowing Addons to inject custom behavior via listener hooks and enabling more efficient, incremental processing for features like completion, hover, and code actions.
_lib/ruby\lsp/requests · high confidence
RubyIndexer module restructured with new internal components
The RubyIndexer module has been reorganized to expose a cleaner public API by requiring a specific set of internal components. This change introduces support for URI-based resource handling, visibility scopes, and a new declaration listener pattern for indexing. It also integrates RBS-based indexing for core classes, enhances search capabilities with fuzzy matching, and allows for indexing enhancements through included hooks, providing a more robust foundation for code navigation and analysis.
_lib/ruby\indexer · high confidence
Simplified library entry point and strict typing
The main library entry point (lib/ruby-lsp.rb) has been refactored to use strict typing (typed: true) and now directly defines the RubyLsp module with its version, removing the previous dependency on the internal lib/ruby/lsp.rb file which has been deleted. This change streamlines the public API surface by eliminating an intermediate require path.
lib · high confidence
Updated test runner and added CI label validation
The \bin/test\ script now supports running specific tests by name when two arguments are provided, while maintaining backward compatibility for other invocations. A new \bin/check\_labels\ script enforces that pull requests include required change-type and category labels for release notes. Additionally, binstubs for \minitest\, \rdbg\, and \tapioca\ have been added, while obsolete scripts for packaging the VS Code extension and running style checks have been removed.
bin · high confidence
VS Code extension project structure and tooling modernization
The VS Code extension project has been reorganized and its tooling updated to modern standards. The extension directory has been consolidated, moving configuration files like \.vscodeignore\ into the \vscode\ root. Development tooling now uses \pnpm\ (evidenced by \.npmrc\ and \pnpm-lock.yaml\ in ignore lists), a new \eslint.config.mjs\ (flat config), and \@vscode/test-cli\ for test execution (\.vscode-test.mjs\). The TypeScript configuration (\tsconfig.json\) has been updated to use \node16\ module resolution and ES2020 targets. Additionally, the extension now includes a \LICENSE.txt\ and an updated \README.md\ that documents new features like the GitHub Copilot chat agent and expanded version manager support.
vscode · high confidence
Fixes
Fix code block line height and anchor scroll behavior
A new custom SCSS file adjusts the line height of code blocks to 1 for tighter rendering and sets the HTML scroll behavior to 'auto' to resolve an anchor link jumping issue.
_jekyll/\sass · high confidence
Test coverage
Added comprehensive test coverage for core Ruby LSP components; Added document highlight expectation tests for various language constructs; Added expectation-based tests for LSP request handlers; Added formatting expectation tests for Ruby code; Added integration tests for VS Code extension components; Added test coverage for RubyIndexer components; Added test infrastructure and coverage for semantic tokens, expectations, and Sorbet annotations; Added tests for RuboCop cops enforcing alias usage and listener-handler alignment; Added tests for Ruby LSP test reporters; Added tests for the TestCollection response builder; Expanded test fixtures for Ruby language features and test frameworks.
Dependencies
Major dependency upgrades and toolchain modernization
The Ruby LSP has upgraded its core dependencies to modern versions: Minitest to v6, RuboCop to v1.70, and Sorbet to v0.6.13055. The project has also migrated its VS Code extension build system from Yarn to pnpm, updated the documentation site to Jekyll v4.4.1, and added new executables (ruby-lsp-check, ruby-lsp-launcher, ruby-lsp-test-exec) to the gem package.
(dependencies) · high confidence
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
How this codebase got here
Baseline
- First survey — no prior run to compare against. CAI 63.
Lenses
- Code Health 83
- Architecture 95
- Maturity 70
- Readiness 63
- Security 55
Changes since last survey
- 300 commits — 277 feature/other, 23 fixes
By area
- (repo) — 122 commits
- .github/workflows — 41 commits
- vscode/package.json — 38 commits
- test/fixtures — 30 commits
- lib/ruby_lsp — 26 commits
- vscode/src — 13 commits
- (root) — 11 commits
- jekyll/Gemfile.lock — 5 commits
- test/requests — 4 commits
- vscode/yarn.lock — 3 commits
- .claude/agents — 1 commit
- sorbet/config — 1 commit
- test/test_reporters — 1 commit
- vscode/.vscode — 1 commit
- vscode/grammars — 1 commit
- vscode/languages — 1 commit
- vscode/pnpm-lock.yaml — 1 commit
Notable commits
- fix: Add back the x64-mingw-ucrt platform to the Gemfile.lock to fix the build on Windows
- fix: Add regression test documenting numeric heredoc limitation
- fix: Fix document link gem paths when to_spec returns nil (#4060)
- fix: Fix document links for source comments above sig blocks
- fix: Fix heredoc regex to avoid matching <<10 in interpolation
- fix: Fix macOS extension tests with current VS Code builds
- fix: Fix semantic token defaultLibrary modifier casing
- fix: Fix send_log_message ignoring type parameter (#3969)
- fix: Fix yjit RUBYOPT concatenation for Ruby 3.2
- fix: Merge pull request #3961 from Shopify/prevent-update-bug-new-lockfile
- fix: Merge pull request #4005 from a-lavis/fix-semantic-default-library-modifier
- fix: Merge pull request #4040 from IgorFroehner/fix-method-not-found-error
- fix: Merge pull request #4051 from Shopify/copilot/fix-debugger-file-path-spaces-again
- fix: Merge pull request #4075 from Shopify/copilot/fix-broken-syntax-highlighting
- fix: Merge pull request #4121 from eyupcanakman/fix/debugger-localfs-schema
- fix: Merge pull request #4127 from eyupcanakman/fix/uri-invalid-scheme-crash
- fix: Merge pull request #4187 from Shopify/codex/fix-macos-vscode-test-runner
- fix: Revert "Apply lower bound ruby-lsp version constraint in composed bundle"
- fix: Revert "Fix Ruby 4.0 CI failure on ubuntu-latest (#3940)" (#3988)
- fix: Revert "Revert GlobalState caching in ExpectationsTestRunner"
- …and 280 more
Architecture
- 0 containers · 1 bounded contexts · 0 dependency edges (baseline)
Written by watchdog.canine.dev from the codebase's own history, inside the signed delivery this page is composed from.
Survey your own repository
Shopify/ruby-lsp was measured the same way every project in this corpus was: the same rubric, at a pinned commit, with the result published in full. Point a surveyor at a repository you know and see whether you agree with it.
About this page
- The score is its most recent published measurement, taken on 19 September 2026 at a pinned commit. It is not a live figure and does not change until the project is measured again.
- Measured at commit 7111db0d5d0d95c8915f3d7f7b558af0348f6fa1 — the exact code this score is about.
- Scored under rubric-2026.09.15 — the same rubric and the same method as every other entry in this index.
- Measured by watchdog.canine.dev using codehealth-analyzer preprod-13a154b7f5d1.