NetStacksNetStacks

Language Support (LSP)

Python diagnostics via the bundled Pyrefly language server, YANG, XML, JSON and Network CLI highlighting, plus a pluggable LSP system for adding your own servers.

Overview

Beyond syntax highlighting, the Workspace editor (built on Monaco) adds two distinct layers of language intelligence:

  • Client-side language features — tokenizers and formatters that run inside the editor with no download and no network access. These cover YANG, XML, JSON, and a custom Network CLI grammar for device config backups.
  • Full language servers (LSP) — real diagnostics, completion, hover, and go-to-definition. These run as separate processes hosted by the local Agent and communicate with the editor over the Language Server Protocol. Python (via Pyrefly) ships as the built-in example.
Where servers run

Language servers run locally under the Agent on your own machine. Your code is never uploaded for analysis. Because they depend on the local Agent, full LSP features (including Python) are part of the standalone Terminal, not the Enterprise/Controller deployment — see the tier note in the Python section.

Supported Languages

The editor registers the following language support out of the box. "Client-side" features need no download; "LSP" features run through the Agent and offer diagnostics and completion.

LanguageExtensionsProvided byFeatures
Python.py, .pyiPyrefly (LSP, via Agent)Diagnostics, completion, hover, go-to-definition
YANG.yangNetStacks tokenizer + formatter (client-side)Highlighting, indentation-aware format
XML.xmlMonaco (built-in) + NetStacks formatterHighlighting, format document
JSON.jsonMonaco bundled json.workerHighlighting, schema validation, format
Network CLIconfig backupsNetStacks "netcli" grammar (client-side)Highlighting for Cisco & Junos configs
Jinja2.j2Template editorHighlighting + live render preview

Python (Pyrefly LSP)

Python support is provided by Pyrefly, a fast static-analysis language server. It is downloaded on demand the first time you open a Python file, so it does not bloat the installer, and it works both on a project and on loose standalone files. The download is a pinned, hash-verified release.

How the install works

  1. You open a .py or .pyi file for the first time.
  2. The Agent fetches the Pyrefly wheel pinned to version 1.0.0 from files.pythonhosted.org (PyPI) for your platform.
  3. The download is verified against a pinned SHA-256. Per-platform binaries exist for macOS (x86_64 / arm64), Linux (x86_64 / arm64), and Windows (x86_64 / arm64).
  4. A smoke test (pyrefly --version) confirms the binary runs. If verification or the smoke test fails, the plugin reports an unusable state and you can reinstall or point it at a custom command.
  5. Once installed, the Agent launches the server as pyrefly lsp and streams diagnostics back to the editor over a WebSocket.
First-file download

The first Python file you open triggers the one-time Pyrefly download. A progress banner is shown while it installs. After that, diagnostics and completion are available with no further setup.

Tier: standalone Terminal only

The Pyrefly Python LSP is available in the standalone (free, open-source) Terminal. It is not available in the Enterprise/Controller build — that deployment has no local Agent to host the server, so Python falls back to basic syntax highlighting and an in-editor notice. YANG, XML, JSON, and Network CLI highlighting work in both builds because they are client-side.

Example Python that produces diagnostics once Pyrefly is loaded:

build_acl.pypython
def build_acl(prefixes: list[str]) -> str:
    lines = []
    for i, net in enumerate(prefixes, start=10):
        lines.append(f"permit ip {net} any")
    # Pyrefly flags this: 'sequnce' is undefined (typo)
    return "\n".join(sequnce)

Network CLI, YANG, XML & JSON

These language features run entirely in the editor — no download, no Agent, no network. They are available in every build.

Network CLI (netcli)

A single vendor-agnostic grammar highlights device config backups from both Cisco-style platforms (IOS / IOS-XE / IOS-XR / NX-OS, with ! comments and indentation-scoped stanzas) and Junos-style configs ({ } braces, set/delete statements, # comments, and [ ... ] value lists). It highlights comments, stanza keywords, IP/CIDR and MAC literals, numbers, and strings. It is a readability aid for backups, not a config parser.

router1-backup.cfgtext
! Cisco IOS — highlighted as netcli
interface GigabitEthernet0/1
 description uplink-to-core
 ip address 10.0.0.1 255.255.255.0
 no shutdown
!
router bgp 65001
 neighbor 10.0.0.2 remote-as 65002
srx1-backup.conftext
# Junos — highlighted as netcli
interfaces {
    ge-0/0/0 {
        unit 0 {
            family inet {
                address 10.0.0.1/24;
            }
        }
    }
}
protocols {
    bgp {
        group core { neighbor 10.0.0.2; }
    }
}

YANG

YANG models get a dedicated tokenizer and an indentation-aware formatter (an indent-based pretty-printer). Run "Format Document" to normalize nesting.

example-system.yangtext
module example-system {
  namespace "urn:example:system";
  prefix sys;
  container system {
    leaf hostname { type string; }
  }
}

XML

XML uses Monaco's built-in highlighting; NetStacks adds a "Format Document" provider so you can pretty-print NETCONF payloads and config exports.

JSON

JSON intelligence — highlighting, schema validation, and "Format Document" — comes from Monaco's bundled json.worker. NetStacks does not add its own JSON provider; the built-in worker already covers it.

Adding Language Servers

The LSP layer is pluggable. Pyrefly ships as a built-in plugin, and you can register additional language servers through a plugin descriptor — without waiting for a NetStacks release. User-added plugins are persisted by the Agent and managed from settings: install, enable, or disable per language.

A descriptor is the same shape whether built-in or user-added. Its fields map directly to the Agent's plugin type: an id, displayName, the Monaco language id it attaches to, the fileExtensions it covers, an installation strategy, and a runtime command/args used to launch the server.

Installation strategies

  • on-demand-download — fetched from a per-platform URL and SHA-256 verified (how Pyrefly works).
  • system-path — the Agent just runs a command you already have installed (e.g. a server on your PATH).
  • bundled — reserved for servers shipped inside the installer.

Example descriptor for a server already installed on your machine (system-path), matching the Agent's plugin shape:

gopls-plugin.jsonjson
{
  "id": "gopls",
  "displayName": "gopls (Go)",
  "language": "go",
  "fileExtensions": [".go"],
  "defaultEnabled": true,
  "unavailableInEnterprise": true,
  "source": "user-added",
  "installation": {
    "kind": "system-path",
    "defaultCommand": "gopls"
  },
  "runtime": {
    "command": "gopls",
    "args": ["serve"]
  }
}

For reference, this is the built-in Pyrefly descriptor's on-demand-download shape (per-platform sources are keyed by platform string and each carries its own url, sha256, and binaryPath):

pyrefly-descriptor.jsonjson
{
  "id": "pyrefly",
  "displayName": "Pyrefly",
  "language": "python",
  "fileExtensions": [".py", ".pyi"],
  "defaultEnabled": true,
  "unavailableInEnterprise": true,
  "source": "built-in",
  "installation": {
    "kind": "on-demand-download",
    "version": "1.0.0",
    "sources": {
      "linux-x86_64": {
        "url": "https://files.pythonhosted.org/.../pyrefly-1.0.0-...whl",
        "sha256": "1382d5b1fcdb49a4de9f34d112d2bddf290a78ff93ee8149492ad5f1077ddffc",
        "binaryPath": "pyrefly"
      }
    }
  },
  "runtime": {
    "command": "pyrefly",
    "args": ["lsp"]
  }
}
Verify your runtime command

Before relying on a system-path server, confirm the command resolves and responds — the Agent runs a smoke test on install, so a binary that is missing or fails to start is reported as unusable rather than silently broken.

Q&A

Q: Why is the first Python file slow to get diagnostics?
A: Pyrefly (version 1.0.0) is fetched and SHA-256 verified on first use, with a one-time progress banner. Subsequent files are immediate.
Q: Is Python LSP available in Enterprise/Controller?
A: No. Full language servers run via the local Agent, which is not part of Enterprise deployments. Python falls back to basic syntax highlighting there; YANG, XML, JSON, and Network CLI highlighting still work because they are client-side.
Q: Does NetStacks add its own JSON formatter?
A: No. JSON highlighting, schema validation, and formatting come from Monaco's bundled json.worker. NetStacks adds the YANG tokenizer/formatter, an XML format provider, and the Network CLI grammar.
Q: Can I highlight Cisco and Junos config backups?
A: Yes — the "netcli" (Network CLI) language covers both vendor families with one vendor-agnostic grammar.
Q: Can I use my own language server?
A: Yes. Register it as an LSP plugin descriptor (for example a system-path command already on your machine) and enable it from settings.
Q: Does language analysis send my code anywhere?
A: No. Language servers run locally under the Agent; nothing is uploaded. The only network access is the one-time, hash-verified server download.