README.md

zed-extension

Reference Zed extension for Strata, per proposal/14-toolchain.md §18 (D-066): "Zed is the reference client ... its extension surface is small (extension.toml pinning the grammar rev, config.toml, .scm queries, one WASM shim wiring language_server_command)."

This is intentionally minimal — a reference extension proving the tree-sitter grammar and strata-ls are consumable by a real editor extension surface, not a polished package. It provides syntax highlighting, bracket matching, indentation, and outline/symbol navigation from tree-sitter-strata, and it now wires up strata-ls (crates/strata-ls) as the language server for .strata files, so Zed will launch it on open and show its diagnostics (textDocument/publishDiagnostics, sourced from strata-check/strata-lint) inline.

Layout

  • extension.toml — extension manifest; [grammars.strata] pins the grammar repository and revision (see the caveat below), [languages.strata] registers the language, and [language_servers.strata-ls] registers strata-ls for the Strata language.
  • languages/strata/config.toml — language config: comment syntax, bracket auto-close, tab size.
  • languages/strata/highlights.scm — syntax highlighting queries, kept in sync with tree-sitter-strata/queries/highlights.scm.
  • languages/strata/brackets.scm, outline.scm, indents.scm — minimal bracket-matching, symbol-outline, and indent queries.
  • Cargo.toml / src/lib.rs — the WASM shim Zed loads to run this extension. It's a standalone crate (its own [workspace], not a member of the root workspace) implementing zed::Extension::language_server_command, which is the only piece of extension logic needed: everything else is declarative TOML/.scm.

Language server (strata-ls)

Zed extensions that run a language server need compiled WASM code (not just TOML) to tell Zed how to launch it. src/lib.rs implements language_server_command by calling Worktree::which("strata-ls") — i.e. it looks for a strata-ls binary already on the user's $PATH. This extension does not download or bundle a strata-ls binary: there is no released build to fetch yet, and doing so is out of scope for a workspace- local reference extension. If strata-ls isn't found on $PATH, language_server_command returns an error and Zed will surface it (visible in Zed's language server logs) instead of silently failing to start:

1strata-ls not found on PATH — run `cargo install --path crates/strata-ls`
2(or build it with `cargo build -p strata-ls` and add the resulting
3target/debug or target/release directory to PATH), then restart Zed.

To make strata-ls available on $PATH:

sh
1# from the repo root
2cargo install --path crates/strata-ls
3# or, for local iteration without installing:
4cargo build -p strata-ls
5export PATH="$PWD/target/debug:$PATH"

Building and installing the extension itself

Zed extensions that run a language server must ship compiled WASM (wasm32-wasip2), not just TOML:

sh
1cd zed-extension
2rustup target add wasm32-wasip2 # once
3cargo build --target wasm32-wasip2

Then, in Zed: zed: install dev extension (from the command palette), pointing at this zed-extension/ directory. Zed builds the WASM extension itself from Cargo.toml/src/lib.rs as part of dev-extension install, so the manual cargo build above is primarily a local sanity check — but it's worth running it first since a broken extension crate will otherwise only surface as an opaque failure inside Zed.

Grammar repository caveat

D-066 calls for "one tree-sitter-strata repo under the project org." Today tree-sitter-strata/ is a subdirectory of this monorepo. Zed clones a grammar's repository/rev and expects grammar.js/src/parser.c at that repository's root, so extension.toml's [grammars.strata] currently points at the monorepo as a placeholder — installing this extension in a real Zed build will not resolve the grammar until tree-sitter-strata is split into its own top-level repository (or Zed's extension format grows a subpath option). This extension is otherwise structurally complete and its queries are validated against the grammar directly (see tree-sitter-strata/'s test suite), so the split is a packaging step, not a rewrite.

Validating the queries without a Zed install

sh
1cd tree-sitter-strata
2npm install
3npm run generate
4node_modules/.bin/tree-sitter query ../zed-extension/languages/strata/highlights.scm \
5 crates/strata-syntax/tests/fixtures/arbiter.strata

(or any other .scm file / fixture under crates/strata-syntax/tests/fixtures/).