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
$ nexus-lspAdvertised 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.