Cross-service go to definition, find references, hover docs, and CodeLens jumps for Ruby microservice workspaces — the navigation a single-repo language server cannot do: from the HTTP call in one service to the route that serves it in another, from a route to the handler it's wired to, from a RabbitMQ publish to its consumer. Works in plain workspaces and in per-service dev containers, where jumps land in the window that owns the target service.
The extension is a thin client of the msnav daemon (a Ruby server over a coderag index) and manages it ruby-lsp style: it starts the daemon itself on activation and shows its state in the status bar.
Requirements
-
The
msnavgem, available onPATHin the environment where you edit (the dev container image, or your machine for local windows):gem install msnavIn a dev container, bake it into the image (
RUN gem install msnav).Note: unlike ruby-lsp, do not add msnav to your application's Gemfile. It never loads your app's code — it reads the shared index database — and a
github:-sourced Gemfile entry produces a binstub that cannot run outsidebundle exec. -
An indexed hub. The index is built once on the host with coderag:
cd /path/to/workspace # the folder containing all services coderag index . --no-embed -
Dev containers only: the shared data-dir mount — one line in
devcontainer.json, identical for every service of every hub (the SQLite index stays on the host):"mounts": [ "source=${localEnv:HOME}/.local/share/coderag,target=/root/.local/share/coderag,type=bind" ]
Ruby ≥ 2.6 for the daemon; VS Code ≥ 1.80 or Cursor.
Getting started
- Install this extension and the
msnavgem (above). - Index the hub on the host (above).
- Open a service and any Ruby file — the extension probes the daemon and,
when nothing answers, runs
msnav up(idempotent: a healthy daemon, including a Python coderag one, always short-circuits the spawn). The status bar shows the state:msnav ✓healthy,msnav ⚠serves another hub,msnav ✗down. Click it to retry; details live in the msnav output channel.
No settings are needed in the standard flows: the daemon finds its hub
through the data-dir mount (matching your folder by name, then by file
contents — anonymous mounts like /app work), and the container↔host path
mapping is derived from the daemon's reported scope.
Features
- Go to Definition / Implementation (F12) — an HTTP call site jumps to the route in the target service; a route line jumps to the handler class it routes to (through DI indirection); a publish jumps to the consumer's handler. Results merge with ruby-lsp's own.
- Find References (⇧F12) — on a route line: every call site in other services that hits this endpoint.
- Hover — the target endpoint's YARD
@returndocumentation, shown on the calling line. - CodeLens (bridge mode) —
↗ GET /users/:id [users-service]links on every cross-service call site. Clicking opens the target where it already lives: this window, another window (routed via the shared registry — works across dev containers), or a new host window opened on the service folder at the exact line. - Daemon lifecycle — autostart on activation, health in the status bar,
msnav doctorfor diagnostics.
Modes (msnav.mode)
| Mode | What it does |
|---|---|
auto (default) |
bridge in remote/container windows, provider locally |
provider |
Definition / References / Implementation providers merged into normal F12 results |
bridge |
CodeLens hints + cross-window open routing (dev containers) |
Settings
| Setting | Default | Description |
|---|---|---|
msnav.mode |
auto |
See modes above |
msnav.daemonUrl |
http://127.0.0.1:8787 |
Daemon base URL |
msnav.autoStart |
on |
Ensure a daemon on activation (probe, then run msnav.daemonCommand) |
msnav.daemonCommand |
["msnav", "up"] |
Command that ensures the daemon (cwd = hub root); set an absolute path if msnav isn't on the editor's PATH |
msnav.hubRoot |
"" |
Hub root override when the coderag.yml walk-up can't find it |
msnav.pathMappings |
[] |
Container→host path prefix mappings; usually derived automatically from the daemon's scope |
msnav.hostRoot |
"" |
The hub's HOST path, only needed when the daemon works in a non-host path space (whole-workspace mounts) |
Commands
| Command | Description |
|---|---|
msnav: Start Daemon |
Re-run the autostart probe/spawn (also bound to the status-bar item) |
msnav: open cross-service target |
Used by the CodeLens links |
Troubleshooting
- Status bar
msnav ✗/ exit code 2 — runmsnav doctorin the (container) terminal: it walks the hub-resolution ladder and prints what each step found, with fixes. msnav ⚠— the daemon on the port serves a different hub; use another port or stop it (msnav down).- The msnav output channel logs every autostart attempt, registration, and routed open.
- More (Bundler contexts, git-gem pitfalls, non-root containers): troubleshooting in the repo README.