VS Code and Cursor (Dataspine extension)
The Dataspine extension (package dataspine-vs-code-extension in the dataspine-core repo under typescript/vscode-extension) adds Spine and data product authoring to Visual Studio Code and to Cursor, which uses the same extension host. Install it from the marketplace (publisher Dataspine, display name Dataspine) or from a VSIX if your org ships internal builds.
Prerequisite for full language support: put a spinec binary on your PATH. The language server is the spinec lsp subcommand from the Spine compiler CLI (Rust parser-cli package). Without it you still get syntax and schema help in many cases, but not live diagnostics, go to definition, hovers, or semantic highlighting from the LSP.
What the extension provides
Language and manifest editing
- File association — Files use the
dataspinelanguage id for extensions.spine,.dataspine, and.ds, for syntax and LSP routing. - TextMate grammar —
syntaxes/dataspine.tmLanguage.jsonprovides baseline coloring. Richer, symbol-aware colors come from LSP semantic tokens when the server is running. - Language configuration —
language-configuration.jsonsets line and block comments (//,/* */), bracket matching, auto-closing pairs, and surrounding pairs, like other VS Code language contributions.
dataspine.json assistance
- JSON schema — The extension maps the filename
dataspine.jsonto the bundledschemas/dataspine-schema.json, so the JSON editor can validate and complete against that schema.
Command Palette and Explorer
The extension registers these commands (see package.json for exact titles):
| Command | What it does |
|---|---|
| Create Data Product Descriptor (dataspine.json) | Collects name and root namespace, writes dataspine.json, creates spine-src/. Also available from the Explorer context menu on a folder. |
| Create Data Product in Dataspine Platform | Resolves the descriptor from the active file or workspace, asks for an organization selector, then runs the control plane CLI create-data-product in a terminal with CONTROL_PLANE_CONFIG_FILE from settings. |
| Add Data Product Version to Dataspine Platform | Runs add-data-product-version with a data product selector from rootNamespace and the directory that contains dataspine.json. |
| Validate Data Product | Runs validate-data-product-version (arguments depend on the CLI build your org uses). |
| Test Data Product | Same flow as validate but adds --test to run the product test harness when your pipeline is wired for it. |
Command logging also goes to a Dataspine CLI output channel.
One workspace, multiple data products
The extension finds a data product root by walking up to dataspine.json, and scans workspace folders and one level of subfolders for additional roots. Each root gets its own language client and spinec lsp --root-dir <root> process so separate products do not share analysis state. Adding workspace folders or opening a .spine file can start a new client when a new root is discovered.
Language server (spinec)
The editor does not type-check Spine in TypeScript. It spawns spinec as an LSP server over stdio (standard input and output), which is the usual pattern for in-process IDE servers.
How it is launched
- Command —
spinec, or a custom path from Settings → Dataspine → LSP:dataspine.lsp.serverPath. - Arguments —
lsp --root-dir <absolute-data-product-root>. - Root — The directory that contains
dataspine.json. The server loads the Data Product Descriptor forrootNamespace,dataspine.sourceDirectory(or the project root if unset), anddataspine.libraries, so editor analysis matches a normaldataspine check/ compile when your Filesystem layout is consistent.
The server advertises the name spinec-lsp in the LSP initialize result. The implementation is Rust: parser-cli / the dataspine_parser_cli library, with Backend in lsp/backend.rs and the tower_lsp stack on stdio.
Synchronization and rebuild model
- Document sync is full (each change sends the whole document). That matches a recompile-on-edit strategy.
- On open, change, and close, the server merges in-memory buffers with on-disk
.spinefiles under the configured source tree (recursively), then runs the same Stage 2 path that resolves namespaces for the product. - Diagnostics are published per file; files with no issues get an empty diagnostic list so old squiggles clear after a fix.
LSP features implemented
| LSP | User-visible behavior |
|---|---|
| PublishDiagnostics | Compiler messages in the Problems view and inline in .spine editors for that data product’s language server. |
| textDocument/definition | Go to Definition jumps to the resolved declaration in Spine source. |
| textDocument/hover | Hover returns Markdown, including native method help from NativeMethodDocs for library-bound callables. |
| textDocument/semanticTokens/full | Semantic highlighting: legend includes keyword, comment, string, number, operator, namespace, type, function, variable, parameter, property, enum, enum member, and decorator (for @); tokens come from the Spine lexer and declaration / definition modifiers where the server emits them. |
Not in the current capability set: completion and code actions; the focus is diagnostics, navigation, hovers, and semantic coloring.
Control plane CLI integration
Create / version / validate / test use a separate control plane binary (not spinec). Settings:
dataspine.controlplane.binary(defaultcli) — full path or command onPATHdataspine.controlplane.configfile(defaultconfig.yaml) — sent to the child asCONTROL_PLANE_CONFIG_FILE
The binary must expose subcommands your deployment expects (for example create-data-product, add-data-product-version, validate-data-product-version).
Cursor and other compatible editors
Cursor installs VS Code–compatible extensions the same way. Other editors that can host this extension model and a Node vscode-languageclient may work in principle; Dataspine tests and documents VS Code and Cursor first.
See also — Dev tooling overview · Filesystem layout · Data Product Manifest · Dataspine CLI