Skip to content

The language server

nexus-lsp speaks the Language Server Protocol over stdio, so any editor with LSP support gets live diagnostics, completion, and hover for .flow.md files — not only VS Code. It parses and compiles with the same code nexus validate does, so a file that shows no errors passes nexus validate with the same libraries.

Diagnostics

The document is checked on open, on every change and when the settings change, and three kinds of problem are reported in place.

Parse errors — the wrong fence language, a malformed step header, an unterminated front matter. The position comes from the parser’s own span, so it points at the character that failed rather than at the line. Parsing is resilient: a broken step does not suppress the diagnostics on the steps around it.

Semantic warnings on the steps that did parse, anchored on the ## Step: line:

What it catches Severity
A step with no body, no effects and no save_body:/restore_body: — a no-op, silently skipped warning
An empty ntd template or an empty xslt stylesheet — produces null at runtime warning
A route fence with no arms — always fails with NoRouteMatch error
A route arm with no call target, or a route with no otherwise fallback warning
A condition fence in a flow with no async configuration — see ADR-023 in Conditions warning
A validate fence on the input of an async flow — nothing upstream called out, so a failed validation would retry to the DLQ with the same message. A validate placed after an http_egress or grpc_egress step is reading the backend’s answer and is not flagged warning
effects: [http_egress] with no endpoint: warning

Compiler refusals — when the document parses, the server compiles it as nexus validate does and publishes every refusal the compiler gives, with the same text nexus validate prints after error:: an illegal flow or tenant name, an unknown step key, a sub-flow reference that does not resolve, a front-matter refusal, and the rest. A refusal that names a step sits on that step’s ## Step: or ## Fault: line; one that names no line of the file sits at the start of the file. Each library warning nexus validate prints as warn: is published as a warning at the start of the file. A document that does not parse shows its parse errors only, as nexus validate stops at the first of them. These diagnostics have the source nexus; the parse errors and the semantic warnings above have the source nexus-lsp.

If the parser or the compiler ever panics, the server publishes that as a diagnostic rather than dying — an editor whose language server has died shows no diagnostics at all, which looks like a clean file.

The libraries: nexusFabric.libs

A flow that uses include, call_flow or another flow by name is compiled against the libraries of one directory, as nexus validate --libs <dir> is. The server reads that directory from one setting, nexusFabric.libs:

{ "nexusFabric": { "libs": "lib" } }

An editor sends this object as initializationOptions when it starts the server, and again in workspace/didChangeConfiguration when the setting changes. A relative path is resolved against the first workspace folder, or against the document’s own directory when the editor sent none. Unset or empty means no libraries, exactly nexus validate without --libs: a flow that includes a library then shows the same refusal the command prints. A directory that cannot be read is one error at the start of the file, reading libs directory <dir>: <reason>, and nothing is compiled. The open document is left out of the libraries when the directory holds it. The directory is read again at each check, so a library edited on disk counts at the next edit of the open document.

Completion

Context-aware:

Where you are What is offered
Between the --- delimiters Front-matter keys
Just after ``` Fence languages
After a ## Step: header, before the first fence Step keys
Inside a ## Fault: section Additionally the deprecated fault_status: and fault_header_*:, offered nowhere else and labelled as deprecated with the current name

Triggered by :, space and `, as well as on request.

Hover

Hovering inside a step shows its name, its kind and the effects it declares — useful in a long file where the fence that defines a step’s behaviour has scrolled away.

What it does not catch

Only the message-limit check: a max_message_bytes: above what the installation allows is refused by nexus deploy, because the threshold it is compared against is a setting of the installation, which neither the server nor nexus validate reads.

Running it standalone

Terminal window
$ nexus-lsp

Advertised capabilities:

Capability Detail
Text document sync Full document on every change
Completion Triggered by : and space
Hover Plain support

Configure your editor to launch nexus-lsp for .flow.md files. There are no command-line options and no configuration file: the server takes the document from the client and its one setting, nexusFabric.libs, from the client’s settings object. It reads the .flow.md files of that directory and nothing else, so it does not read your registry and does not need the platform running.

The binary ships built, in the delivery bundle, next to the two .vsix files and the script that installs all three — see the VS Code extensions. It goes anywhere on your PATH.