rextio-lsp
Language Server for Rextio — native-promotion routes and guidance in your editor.
A Python (pygls) LSP server that consumes Rextio’s tooling-contract JSON and reports per-function execution routes (native-direct, native-plugin:<id>, native-shim, fallback-python, fallback-accelerated:numba, rejected:<RXT>) with actionable promotion guidance.
Status: 0.1.4
The current published package is 0.1.4, released on 2026-07-27 before Core 0.1.8.
What 0.1.4 adds
- Supports tooling-contract major 3, including the Core 0.1.8 contract 3.0.0 producer.
- Keep major 3 diagnostic positions on the established 0-based UTF-8 byte
mapping, including
RXT000. - Continue interpreting the bounded
promotion_assessmentsurface on major 3. - Keep malformed versions and unknown majors in degraded generic-diagnostic mode.
What 0.1.3 adds
- Exercises the released
rextio==0.1.6producer and tooling-contract 2.27.0 in a dedicated CI integration lane. - Keeps first-party plugin capability guidance provider-agnostic by using the same diagnostic-code lookup as core guidance.
What 0.1.2 added
- Reports automatic promotion eligibility for undecorated functions instead of requiring
@rextio.nativefor editor feedback. - Preserves failed automatic-probe blockers, advisories, and suggestions as non-Error LSP diagnostics.
- Shows route plus assessment state in one CodeLens, with a readable explanation when assessment was skipped.
- Uses exact source/name ranges for CodeLens and hover, including UTF-8-byte → UTF-16 conversion.
- Suppresses promotion UI noise for statically proven
@rextio.exemptfunctions while retaining unrelated analyzer diagnostics. - Trusts these additive fields only for tooling-contract
>=2.2.0,<3.0.0; contract 1.x and 2.0/2.1 retain their established legacy behavior.
The released 0.1.1 position behavior remains intact: major 1 retains the legacy
RXT000 position mapping, while majors 2 and 3 use 0-based UTF-8 byte columns.
Unsupported majors degrade to generic diagnostics.
rextio is not a package dependency of this server. The server acquires the tooling-contract JSON via in-process import or a discovered subprocess (see Features), choosing order from the configured interpreter and environment match, and no-ops silently when Rextio is absent.
Required deployment order
The tooling-contract major-3 rollout uses this strict order:
rextio-lsp0.1.4 — the tolerant consumer is released first.- core
rextio0.1.8 — the tooling-contract 3.0.0 producer follows.
Publish the LSP consumer first; only then publish core 0.1.8.
See the CHANGELOG for the full release notes and the preserved 0.1.0 history.
Designed to coexist
rextio-lsp registers only Rextio-semantic capabilities and stays out of everything else:
- Provides: diagnostics (
source: "rextio", RXT/RXTP codes only; Warning for rejection and promotion blockers, Hint for informational codes, Information otherwise — never Error), hover (route + assessment guidance), code lens (per-function route and assessment badges), code actions (promotion quick fixes) - Does not provide: completion, formatting, rename, definition, references, syntax/style linting — those remain with your existing Python LSP (Pylance/pyright, ruff, …)
- Activates only when
rextio.tomlexists in the workspace; silent no-op when Rextio isn't installed in the project environment
Features
M1
- Whole-project
rextio checkon open/save (debounced), published assource: "rextio"diagnostics - Severity is capped: rejection codes → Warning, informational codes (RXT075/080/090/091) → Hint, everything else → Information (never Error)
- Hover on a function definition line shows its route, native status, and rejection guidance (from the capability manifest)
- Acquisition supports both in-process (
import rextio) and subprocess (discoveredrextiobinary). Order is environment-aware: an explicitinitializationOptions.interpreter.pathwhose neighbouringrextioexists prefers that subprocess; a project-venvrextioin a different environment than the server also prefers subprocess; when the server and project share the same environment, in-process is used (equivalent, no spawn). The non-preferred path remains a fallback. A barePATHhit does not displace in-process. - Tooling-contract majors
{1, 2, 3}fully supported: majors 2 and 3 map every column as 0-based UTF-8 bytes; major 1 keeps legacyRXT0001-based code-point mapping. Other majors → degraded (generic) diagnostics without guidance enrichment
M2
initializationOptionscontract (see below): toggle code lens, pin the interpreter used for binary discovery- Code lens: one
Rextio: <route>lens per analyzed function, carrying the informationalrextio.showRouteInfocommand with[qualname](registered only whencodeLens.enableis true) - Code actions (quick fix): on a rejected function that carries an explicit
@rextio.nativemarker, offer "Rextio: keep on Python fallback (@rextio.exempt)" — rewrites the decorator to@rextio.exempt(indentation preserved) - Hover also surfaces an Advisory section for informational codes present on the function, not just rejections
- Watches
**/rextio.toml; on change, drops the project's cached capability manifest and re-analyzes open documents - Real diagnostic spans when the contract provides
end_line/end_column(else a zero-width range) - Latency instrumentation: each whole-project check is logged via
window/logMessage(Info when > 2.0s, else Log)
0.1.2
- Tooling-contract 2.2 promotion assessments cover undecorated eligible, ineligible, and structurally/policy-skipped functions.
- Failed automatic probes retain their blocker/advisory messages and suggestions without becoming build errors or LSP Errors.
- Assessment diagnostics map to Warning/Hint/Information and de-duplicate matching legacy diagnostics by code, span, and message.
- One CodeLens combines route and assessment status; skipped records include a readable reason, while proven exemptions emit no promotion lens.
- Hover targets the exact function-name range and includes assessment provenance, blockers, advisories, and suggested improvements.
- Contract 2.2 source/name ranges anchor editor UI precisely; older contract records retain definition-line fallback.
- Same-named additions from contract 1.x, 2.0/2.1, malformed versions, and unsupported majors are ignored safely.
initializationOptions
The server reads the following shape (all keys optional; defaults shown):
{
"codeLens": { "enable": true },
"interpreter": { "path": null }
}
codeLens.enable— whenfalse, the code lens capability is not advertised at all.interpreter.path— path to the project's Python interpreter. When set, the server looks forrextionext to that interpreter first (before project.venv/venvandPATH). If that neighbour binary exists, subprocess acquisition via it takes precedence over in-process; if it does not, discovery continues and in-process may still win.
Install
Install into the project environment so the server stays in version lock-step with the project's rextio and its plugins:
pip install rextio-lsp
To hack on the server itself, install from a source checkout (see Development).
The server speaks LSP over stdio via the rextio-lsp console script (equivalently python -m rextio_lsp).
Editor setup
Neovim (nvim-lspconfig, manual command)
rextio-lsp is not yet a built-in lspconfig server, so register it manually:
local configs = require("lspconfig.configs")
local lspconfig = require("lspconfig")
if not configs.rextio_lsp then
configs.rextio_lsp = {
default_config = {
-- run the server from the project's own environment
cmd = { ".venv/bin/rextio-lsp" },
filetypes = { "python" },
root_dir = lspconfig.util.root_pattern("rextio.toml"),
init_options = {
codeLens = { enable = true },
interpreter = { path = vim.fn.getcwd() .. "/.venv/bin/python" },
},
},
}
end
lspconfig.rextio_lsp.setup({})
Enable code lens rendering with vim.lsp.codelens.refresh() (e.g. on BufEnter/CursorHold) and :lua vim.lsp.codelens.display().
Generic stdio client
Any LSP client that launches a stdio subprocess works. The essentials:
- command:
rextio-lsp(orpython -m rextio_lsp) from the project environment - transport: stdio
- languages:
python - root: nearest directory containing
rextio.toml - initializationOptions: the shape documented above
Development
pip install -e '.[dev]'
ruff check src tests
mypy
pytest -q
Integration tests marked needs_rextio are auto-skipped when rextio is not importable.
Contributor and agent guidance lives in the repository (AGENTS.md).
Compatibility floors
| Component | Floor |
|---|---|
| Package version | 0.1.4 |
| Python | >= 3.11 |
| pygls | >= 2.1, < 3 |
| Tooling-contract majors | {1, 2, 3} supported; promotion assessments require 2.x >=2.2.0 or 3.x; other majors → degraded |
rextio package dep |
none (peer contract consumer only) |
License
MIT
Metadata
Release files for rextio-lsp 0.1.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rextio_lsp-0.1.4.tar.gz | 62.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rextio_lsp-0.1.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 99.6 kB
Release files / rextio_lsp-0.1.4.tar.gz
| Download URL | rextio_lsp-0.1.4.tar.gz |
|---|---|
| Size | 62.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2219c86c6b6d445b0ae6b67426136c6463d60310f0f2f0d8c6aebdddb5148812
|
|
BLAKE2b-256 checksum How to use checksums |
c3d00106c60db5690bd892fc4e178e6892f5b37a15a97227564da81b62a6a416
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.14
|
Release files / rextio_lsp-0.1.4-py3-none-any.whl
| Download URL | rextio_lsp-0.1.4-py3-none-any.whl |
|---|---|
| Size | 36.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a2d26e2c023ee0a9259a3f9783525501f6e3dea364e7a2043dbe697ce54b9436
|
|
BLAKE2b-256 checksum How to use checksums |
39ed0ed59b99e3c9d64c5ff85634c6fa8b52599f1e178315935e94248e307d58
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.14
|