CellScript Wiki
Tutorial 07: LSP and Tooling
Tutorial 07: LSP and Tooling
You can write CellScript with any text editor and the cellc CLI. The LSP and
VS Code extension make that loop shorter. Parse errors, type errors,
flow mistakes, symbols, hovers, formatting, and compiler-backed reports
can show up while you work instead of after a long command sequence.
The useful thing to remember is that editor feedback is not a separate language
implementation. It is tied to the same parser, type checker, state-transition checks,
and lowering metadata used by cellc.
Compiler diagnostics now carry typed severity. Current hard failures still
surface as error; future review notes can be reported as warning without
making ErrorReporter::has_errors() true. Release gates and production
commands remain error-gated, so a warning is a review signal rather than a
deployment certificate.
Backend diagnostics use stable E2xxx codes. LSP clients receive the code in
the standard diagnostic code field and a codeDescription link to the
compiler registry, so hover or diagnostic-detail UI can show the exact rule
instead of only the message. The same record is available through
cellc explain E2202 --json.
What You Will Learn
- what the LSP server supports;
- how the CLI, LSP, WASM, and playground share Edition 2026;
- how the VS Code extension starts the server;
- which settings matter for local development;
- where editor tooling helps;
- where release gates still need CLI and CKB evidence.
LSP Capabilities
The LSP implementation supports the editor features you expect while writing a contract:
- diagnostics for parse, type, flow, and lowering errors, with compiler-backed severity;
- hover information for actions, receipts, fields, local variables, flow states, and lowering metadata;
- keyword, type, symbol, field, local, enum variant, and qualified flow
state completions such as
Ticket::Active; - go-to-definition;
- find-references;
- workspace rename with identifier-boundary checks;
- document symbols;
- document highlight;
- signature help;
- folding ranges;
- selection ranges;
- formatting;
- code actions for lowering diagnostics;
- incremental document sync using LSP UTF-16 positions.
Run the server over stdio:
cellc --lspIn practice you usually let the editor start it for you.
One Edition Across Tooling
The editor is not an edition compatibility layer. Package-backed LSP documents
take edition = "2026" from Cell.toml and carry it into the same compiler
path as cellc. A missing or non-2026 value is a package error; the LSP does
not infer or migrate it.
The browser boundary is equally explicit. The WASM metadata exports take an edition argument:
compile_metadata_json(source, edition, target?)
compile_metadata_json_diagnostics(source, edition, target?)
compile_metadata_json_sources(sources_json, entry_path, edition, target?)The only accepted value is "2026". The playground worker passes that value
and records it in compiler-output provenance, so browser metadata cannot
silently use a different compatibility contract from native builds.
On nightly-0.22, qualified enum completion includes concrete payload
constructors: after Limit::, Some advertises Some(u64) and inserts
Some(value1), while None remains a bare variant. Enum hover reads the same
compiler metadata as cellc metadata and shows the tagged-union layout, ABI,
storage class, encoded width, and linear-payload flag. Generic or
variable-width payload ADTs are intentionally not advertised as supported.
VS Code Extension
The extension lives in:
editors/vscode-cellscriptIt is a pinned Git submodule. Initialize it before local validation or packaging:
git submodule update --init editors/vscode-cellscriptIf that command cannot fetch the recorded commit, the parent repository points at an unavailable extension revision and the release must update its gitlink; do not silently substitute an arbitrary branch tip.
Validate and package it locally:
cd editors/vscode-cellscript
npm install
npm run validate
npm run packageInstall the generated .vsix in VS Code. If cellc is not on PATH, set
cellscript.compilerPath.
Useful settings:
| Setting | Purpose |
|---|---|
cellscript.compilerPath |
Path to the cellc binary used for LSP and CLI-backed commands. |
cellscript.useCargoRunFallback |
Use cargo run -q -p cellscript -- from a trusted workspace when cellc is unavailable. |
cellscript.target |
Compiler target for command-backed reports: riscv64-asm or riscv64-elf. |
cellscript.commandTimeoutMs |
Timeout for compiler-backed commands. |
cellscript.builderOutputDir |
Output directory for generated TypeScript action-builder packages. Relative paths resolve from the nearest package Cell.toml. |
cellscript.ckbRpcUrl |
Optional CKB RPC URL for live registry verification. |
cellscript.deploymentNetwork |
Optional network filter for live registry verification and generated builder deployment binding. |
cellscript.registryRequirePublisherSignature |
Add --require-publisher-signature to registry verification commands. This is a metadata-presence gate, not cryptographic signature verification. |
cellscript.registryRequireAuditReport |
Add --require-audit-report to registry verification commands. |
The extension contributes commands for the local compiler and builder loop:
| Command | CLI boundary |
|---|---|
CellScript: Compile Current File |
cellc <file> |
CellScript: Show Metadata |
cellc metadata |
CellScript: Show Constraints |
cellc constraints |
CellScript: Show Entry Witness ABI |
selects an action/lock, then runs cellc abi |
CellScript: Show Action Build Plan |
selects an action, then runs cellc action build --json |
CellScript: Show Builder Assumptions |
cellc explain assumptions --json |
CellScript: Show Transaction Template |
cellc tx solve --json |
CellScript: Show Deploy Plan |
cellc deploy plan --json |
CellScript: Show Profile |
cellc profile --json |
CellScript: Generate Audit Bundle |
cellc audit-bundle --output <scratch> --json |
CellScript: Generate TypeScript Action Builder |
cellc gen-builder --target typescript |
CellScript: Verify Package |
cellc package verify --json |
CellScript: Verify Registry |
cellc registry verify --json |
CellScript: Verify Live Registry |
cellc registry verify --live --json |
CellScript: Show Production Report |
compiler version + metadata + constraints + release-audit boundary |
Entry-witness commands report placement ABI
cellscript-witnessargs-input-type-v2 within the resolved compatibility profile:
CSARGv1 is stored in Molecule WitnessArgs.input_type on the selected
script-group witness. Tooling must preserve lock and output_type; it must
not emit the entry payload as raw witness bytes. Edition 2026 independently
identifies how the source was understood.
CellScript: Show Production Report is useful while editing because it displays
compiler version, metadata, constraints, and release-audit boundaries.
The 0.21 compiler also ships cellscript-mcp, compile receipts, ProtocolGraph,
TemplateLayout, and helper-backed aggregate evidence. Those remain compiler/MCP
surfaces in this extension release rather than command-palette entries.
On the 0.22 nightly line, cellc explain graph --json attributes participant
roles on each edge. Prefer role_source = verification-predicate; binding
sources are secondary and field-name is weak metadata. Always display
role_warnings and authorization_proven alongside the role. Mermaid output
includes the selected role and source in the edge label, while summary output
reports the deduplicated role-lint count. These labels explain the protocol;
they do not prove that an Address signed or that a lock authorized the action.
That report is a guide, not a deployment certificate. Chain acceptance still requires CLI evidence and builder-backed CKB transactions.
Generated builder packages are local artifacts. After using
CellScript: Generate TypeScript Action Builder, run the generated package's
own checks before treating it as usable transaction-building evidence. This is
the generated package's npm test boundary:
npm --prefix target/cellscript-builder/typescript install --ignore-scripts
npm --prefix target/cellscript-builder/typescript testThe generated tests prove the TypeScript package compiles, plans actions, delegates live-cell resolution/build/dry-run/submit to the runtime adapter, and fails closed on mismatched lockfile or deployment identity. They do not prove wallet signing, CKB node acceptance, or committed stateful flows.
A Comfortable Local Loop
While editing, let the LSP catch small mistakes quickly. Before committing, run the CLI checks explicitly:
cellc fmt --check
cellc check --all-targets --json
cellc metadata . --target riscv64-elf --target-profile ckb -o /tmp/metadata.json
cellc build --target riscv64-elf --target-profile ckb --json
cellc verify-artifact build/main.elf --verify-sources --expect-target-profile ckb
cellc package verify --json
cellc registry verify --jsonFor trust metadata review, add the explicit presence gate:
cellc registry verify --require-publisher-signature --require-audit-report --jsonRun these from a package directory that contains Cell.toml. The . argument
refers to the current package; for a single file, pass the file path instead.
For CKB admission, keep the profile visible:
cellc check --target-profile ckb --json
cellc build --target riscv64-elf --target-profile ckb --json
cellc verify-artifact build/main.elf --expect-target-profile ckb
cellc registry verify --live --rpc-url "$CELLSCRIPT_CKB_RPC_URL" --json
cellc action build . --action mint --target-profile ckb --fabric-intent --json
cellc gen-builder . --target typescript --output target/cellscript-builder/typescript --target-profile ckb --json
npm --prefix target/cellscript-builder/typescript install --ignore-scripts
npm --prefix target/cellscript-builder/typescript testThis loop gives fast feedback first, then more formal evidence as the contract gets closer to review.
Formatting
Apply formatting:
cellc fmtCheck formatting without changing files:
cellc fmt --checkThe formatter is especially useful after applying field shorthand or cleaning up example code. It keeps the source style consistent without turning style into a manual review topic.
Generated Documentation
Generate package docs:
cellc docWith JSON summary:
cellc doc --jsonDocumentation output includes the public contract surface and metadata-derived lowering information.
Local Package Workflow
The package manager supports:
cellc initcellc buildcellc checkcellc fmtcellc doccellc add --pathcellc removecellc infocellc package verifycellc registry verify- lockfile consistency checks for local dependencies
Use the top-level cellc path/to/file.cell form for one-off file compilation.
Use cellc build for package builds.
Local cellc install --path, registry source-package cellc install, and
cellc update are supported lockfile workflows for packages that can be
resolved and source-hash verified. Public cellc publish is an authenticated
registry write authorised by a JoyID-rooted capability; cellc registry add
remains the local/offline discovery metadata path. Treat run, registry proxy
use, cryptographic publisher signature verification, and non-CellScript artifact
profiles as future-facing or fail-closed.
Next
With the tooling loop in place, continue with Bundled Example Contracts.