Language Server Protocol (LSP)
Relevant source files
The following files were used as context for generating this wiki page:
The Crucible Language Server Protocol (LSP) implementation provides advanced editor support for Crucible modeling language (.cru) files and crucible.toml manifests. It enables standard IDE features including package-wide diagnostics, code completion, semantic highlighting, and navigation, ensuring a high-quality developer experience during API modeling.
Sources: AGENTS.md, crates/crucible-lsp/Cargo.toml
Architecture and Integration
The language server is a standalone Rust binary that communicates with editors via standard input/output. It leverages the core project crates to perform its analysis:
crucible-lang: Provides the lossless lexer, parser with recovery, and name resolution logic.crucible-policy: Executes build-time API policy and compatibility checks.crucible-ir: Consumes the lowered Intermediate Representation for shared analysis.
The diagram shows the communication flow between the editor plugin, the LSP binary, and the underlying Crucible compiler crates.
Sources: AGENTS.md:65-80, crates/crucible-lsp/Cargo.toml:16-20
Core Features
The crucible-lsp implementation supports the following Language Server Protocol capabilities:
| Feature | Description |
|---|---|
| Diagnostics | Provides real-time feedback on syntax errors, unknown types, and policy violations. |
| Completion | Offers intelligent suggestions for model shapes, keywords, and identifiers. |
| Navigation | Supports "Go to Definition" and finding references across the package namespace. |
| Refactoring | Enables safe renaming of shapes and members across multiple files. |
| Formatting | Ensures consistent code style using the project's formatting rules. |
Sources: AGENTS.md:73-75, crates/crucible-lang/tests/package.rs:163-180
Workspace Management
The LSP manages Crucible projects as packages defined by a crucible.toml manifest. It tracks source files within declared directories and handles editor overlays for unsaved buffers.
Package Loading Logic
When a user opens a file, the LSP identifies the package root and loads the manifest. It handles:
- Source Selection: Tracking
.crufiles based on thesourcesarray in the manifest. - Imports: Resolving external package imports (e.g.,
crucible.errors). - Editor Overlays: Using in-memory versions of files (unsaved buffers) instead of disk contents when available.
The flow represents how the LSP transitions from opening a file to performing full semantic analysis based on project configuration.
Sources: crates/crucible-lang/tests/package.rs:43-100, AGENTS.md:73-74
Language Support Details
The LSP implementation relies on the specific spelling and naming conventions of the Crucible language to provide accurate navigation and documentation.
Doc Link Resolution
The LSP resolves model documentation links (e.g., [ShapeName]) into actionable IDE links. The resolution logic differs between server and client contexts:
- Server Context: Links typically resolve to marker types or internal re-exports.
- Client Context: Links resolve to client methods or model types exported by the SDK.
Sources: crates/crucible-codegen-rust/src/names.rs:241-286, crates/crucible-codegen-ts/src/names.rs:161-225
Diagnostic Reporting
The LSP reports diagnostics derived from the crucible-lang compiler. It identifies:
- Reserved Keywords: Prevents users from naming shapes using target language keywords (e.g.,
match,Selfin Rust). - Name Collisions: Detects when multiple members would result in the same name in generated code (e.g.,
fooBarandfoo_barboth becomingfoo_barin Rust).
Sources: crates/crucible-codegen-rust/src/names.rs:44-70, crates/crucible-codegen-ts/src/names.rs:114-130
Conclusion
The Crucible LSP is a critical component for developers, providing real-time validation and productivity tools directly within the editor. By integrating the core compiler crates, it ensures that editor feedback perfectly matches the behavior of the crucible-cli check and generation commands.