BuildPolicynew
Editor Integrations
Use VS Code or Zed to edit Chio YAML with diagnostics, completion, hover, and go-to-definition.
What Ships
Chio includes two extensions and a shared snippet pack. The VS Code extension is a TypeScript package; the Zed extension is a Rust crate that compiles to wasm32 for the editor and to a plain rlib on host targets so the workspace build exercises its manifest contract. The snippet source is shared and each editor receives its native format.
| Editor | Package | Identity |
|---|---|---|
| Visual Studio Code | vscode-chio | Publisher backbay, display name Chio, Apache-2.0. |
| Zed | zed-chio | Extension id chio, language server Chio Language Server. |
Supported Documents
Both editors target the same three Chio document types, keyed by filename or suffix. A chio.yaml is a project's config file: it points at a HushSpec policy file or inline block, lists capabilities, and activates guards. Manifests describe tools and capabilities; guard DSL files describe guard pipelines.
| Language ID | Matches | Purpose |
|---|---|---|
chio-yaml | chio.yaml | Project config: policy reference, capabilities, guards, manifest path. |
chio-manifest | *.chio-manifest.yaml | Tool and capability manifest. |
chio-guard | *.chio-guard.yaml | Guard DSL. |
VS Code contributes the three IDs above; Zed contributes a single Chio language scoped to the same suffixes (chio.yaml, chio-manifest.yaml, chio-guard.yaml). Both reuse a YAML tree-sitter grammar for highlighting and scope it to the Chio constructs: capability, policy, and guard keys, and urn:chio:error:* references.
Install
Both extensions depend on the chio-lsp binary. Build it first and put it on your PATH, or pin an absolute path in the editor settings below.
# Build the language server binary.
$ cargo build --release -p chio-lspLoad the VS Code extension from its package directory:
$ cd integrations/editors/vscode-chio
$ npm install
$ npm run compile
# Launch via "Run Extension" (F5) inside VS Code, or package it:
$ npx @vscode/vsce packageLoad the Zed extension as a dev extension: open the command palette and run Zed: Install Dev Extension, then point it at integrations/editors/zed-chio.
The language server validates documents
chio-lsp owns the document cache, validation, and completion, hover, and definition catalogs. The client forwards diagnostic codes and completion results without interpreting them.What the language server provides
chio-lsp classifies each open document by language ID or file suffix and serves four request classes from a shared document cache. It stops at the document boundary: it does not run the kernel, evaluate policy, or read arbitrary project files.
| Feature | Documents | Behavior |
|---|---|---|
| Diagnostics | all three | Structural required-key and shape checks over parsed YAML on didOpen / didChange, one provider per language. |
| Completion | chio.yaml only | Capability scopes under scopes / tools / capabilities, guard identifiers under guards, and top-level policy keys. |
| Hover | all three | Registry help on urn:chio:scope:*, urn:chio:guard:*, and urn:chio:error:* identifiers. |
| Go to definition | all three | Resolves a urn:chio:scope:* / urn:chio:guard:* reference to a linked manifest first, then the first occurrence in the open document. |
The chio.yaml top-level keys the completion catalog offers are version, policy, capabilities, guards, and manifest. Of these, version and policy are required: a chio.yaml missing either surfaces a diagnostic carrying urn:chio:error:cli:doctor-chio-yaml-invalid, the same code the chio doctor probe emits, so the editor and the CLI agree on what counts as valid.
Configuration
By default both editors resolve chio-lsp on PATH and spawn it with no extra arguments. Override the binary path or forward flags when the server lives somewhere non-standard.
VS Code
The extension contributes three settings under the chio namespace.
| Setting | Default | Description |
|---|---|---|
chio.lsp.path | chio-lsp | Path to the server binary. Resolved on PATH when left as the default. |
chio.lsp.args | [] | Extra arguments forwarded to the server verbatim on spawn. |
chio.trace.server | off | LSP trace verbosity: off, messages, or verbose. |
{
"chio.lsp.path": "/opt/chio/bin/chio-lsp",
"chio.lsp.args": [],
"chio.trace.server": "off"
}Zed
Zed reads the standard lsp.<server>.binary block. The server id is chio-lsp. An empty or whitespace-only path falls back to the bare chio-lsp invocation, so the default PATH lookup still works.
{
"lsp": {
"chio-lsp": {
"binary": {
"path": "/opt/chio/bin/chio-lsp",
"arguments": ["--verbose"]
}
}
}
}Both editors let you override the binary path and launch arguments.
Snippets
The extensions include four snippets for common authoring patterns. Type a prefix and expand it; each snippet uses LSP-standard ${1:label} placeholders so both editors accept the same source.
| Prefix | Scaffold | Scope |
|---|---|---|
capability-allowlist | Capability allowlist with explicit scope bounds. | chio-yaml, chio-manifest |
scope-bound | Scope-bound capability fragment with TTL and tenant restriction. | chio-yaml, chio-manifest |
guard-pipeline | Guard pipeline composing input, decision, and output stages. | chio-yaml, chio-guard |
manifest-skeleton | Minimal manifest with policy, capabilities, and guard references. | chio-manifest |
Expanding manifest-skeleton drops in a complete starting manifest with the default values already filled:
version: 1
name: manifest_name
policy:
default: deny
capabilities:
- id: capability_id
scope:
- scope.action
guards:
- ref: guard.identifierSnippet sources are tool-neutral YAML at integrations/editors/snippets/*.snippet.yaml, validated against a JSON schema. A build task renders them into each editor's native format; the generated files carry a generated by cargo xtask snippets regen header and are checked for drift in CI.
$ cargo xtask snippets regen # regenerate native files
$ cargo xtask snippets regen --check # CI drift check (no writes)Diagnostics and registry codes
Every diagnostic carries a registry code in its LSP code field, formatted as urn:chio:error:<domain>:<code> — for example urn:chio:error:capability:scope-mismatch. The editors render the URN unchanged; downstream tooling matches on the code field programmatically. The source is chio-lsp, and locations are anchored to the offending token so the editor can place a squiggle.
One vocabulary of errors
Other editors
Any LSP-capable editor (Neovim, Helix, JetBrains, Emacs lsp-mode) can use chio-lsp without a first-party extension. Configure:
- Binary:
chio-lsp, resolved onPATHby default, pinnable to an absolute path. - Transport: LSP over stdio, no environment variables required.
- Selectors: map the client to
chio.yaml,*.chio-manifest.yaml, and*.chio-guard.yaml. - Diagnostics: read the
urn:chio:error:*code from each diagnostic'scodefield and render it as-is.
Next steps
- Write a Policy · author HushSpec rules that the guard pipeline enforces
- HushSpec Policy Format · the policy schema used by editor completions
- chio.yaml Configuration · the project config file the extensions validate
- Capabilities · scopes and bounds referenced by the capability snippets