Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 38 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,43 @@
# Changelog

## Unreleased
## 0.24 development line

- Added command-palette flows to validate LS-IDL, append the raw IDL SHA-256
commitment to a CKB executable, and fetch exact IDL bytes by deployed Script
identity.
- Added an optional Registry API setting for private or test deployments and
documented the interface-identity trust boundary.

## 0.22.0

- Aligned the extension package metadata with the CellScript 0.22 language
line and its compiler-backed type, set, flow, evidence, and protocol-role
surfaces.
- Highlight the `script::...` helpers and nested
`verifier::btc::bip340::...` runtime-verifier namespace.
- Added TextMate and snippet coverage for typed transaction views, finite
invariant quantifiers, source-aware bounded collections, type `validity`,
explicit borrow regions, and concrete payload enums.
- Kept editor diagnostics, hover, completion, formatting, metadata, ProofPlan,
and production-report commands on the canonical nested CLI tree and global
`--json` machine-output contract.
- Documented stable `E2xxx` compiler diagnostics and LSP `codeDescription`
links.

## 0.21.0-rc.1

- Aligned the extension package metadata with the CellScript 0.21 release
candidate.
- Kept the editor command surface on the compiler-backed package, registry,
builder, ABI, metadata, and production-report commands while the compiler
adds the 0.21 CLI, MCP, receipt, ProtocolGraph, TemplateLayout, and
aggregate-helper evidence surfaces.
- Switched builder assumptions, transaction template, and deploy plan commands
to the canonical nested `cellc explain assumptions`, `cellc tx solve`, and
`cellc deploy plan` forms.
- Refreshed README wording for the current 0.21 authoring surface.

## 0.20.0

- Added VS Code commands for the 0.20 action-builder workflow:
entry-witness ABI, action build plans, TypeScript builder generation,
Expand Down
22 changes: 20 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ The extension talks to the CellScript compiler through `cellc --lsp`, so editor

## How It Fits Into The Toolchain

The extension is a thin editor layer over the compiler. Syntax highlighting, snippets, and VS Code integration live in this repository, but language semantics come from `cellc`. That split keeps the editor useful without creating a second, weaker implementation of CellScript.
The extension is a compiler-backed editor surface. Syntax highlighting, snippets, and VS Code integration live in this repository, but language semantics come from `cellc`. That split keeps the editor useful without creating a second, weaker implementation of CellScript.

There are two feedback loops:

Expand Down Expand Up @@ -44,9 +44,24 @@ The command palette includes:
- `CellScript: Show Profile`
- `CellScript: Generate Audit Bundle`
- `CellScript: Show Production Report`
- `CellScript: Validate LS-IDL`
- `CellScript: Bind LS-IDL to CKB Executable`
- `CellScript: Fetch LS-IDL by CKB Script`

These commands spawn `cellc` for one-shot evidence and build tasks. They do not replace release gates, deployment checks, transaction signing, or CKB node acceptance.

The LS-IDL commands keep interface identity byte-exact: validation checks the
supported schema, binding appends `SHA-256(idl.json)` to the selected CKB
executable, and fetch saves the Registry response without parsing and
reserialising it. The commitment proves byte identity and placement; it does
not prove that a Lock Script implements the described interface correctly.

The 0.22 compiler also ships `cellscript-mcp`, compile receipts
(`cellc receipt`, `cellc sign-receipt`, `cellc verify-receipt`),
ProtocolGraph, TemplateLayout, and helper-backed aggregate evidence. Those
surfaces remain compiler/MCP commands rather than VS Code command-palette
commands in this extension release.

## Requirements

Install `cellc` and make sure it is available on `PATH`:
Expand Down Expand Up @@ -96,12 +111,13 @@ For package-based projects, run package commands from a file under the nearest `
| `cellscript.builderOutputDir` | `target/cellscript-builder/typescript` | Output directory for generated TypeScript action builders. |
| `cellscript.ckbRpcUrl` | empty | Optional CKB RPC URL for live registry verification. |
| `cellscript.deploymentNetwork` | empty | Optional deployment network filter for live registry checks and builder identity binding. |
| `cellscript.registryApiUrl` | empty | Optional Registry API base URL for LS-IDL fetch; empty uses the compiler default. |
| `cellscript.registryRequirePublisherSignature` | `false` | Adds the publisher-signature metadata gate to registry verification. |
| `cellscript.registryRequireAuditReport` | `false` | Adds the audit-report metadata gate to registry verification. |

## Authoring Model

This README documents the current 0.17 authoring surface. The extension follows the current CellScript action surface:
This README documents the current 0.22 authoring surface. This 0.25 nightly branch also previews generic value declarations, explicit `public`/`public(package)`/`private` visibility, and labeled `break`/`continue` control flow. The extension follows the current CellScript action surface, including typed transaction views, finite invariant quantifiers, bounded collections, type validity, explicit borrow regions, and concrete payload enums:

```cellscript
action fill_offer(input: Offer) -> output: Offer {
Expand Down Expand Up @@ -162,6 +178,8 @@ This extension displays compiler evidence. It does not:
- create audit signatures;
- publish packages;
- deploy code Cells;
- run `cellscript-mcp`;
- create, sign, or verify compile receipts;
- sign transactions;
- submit transactions;
- replace `cargo test`, `cargo clippy`, `cellc check --production`, or chain acceptance scripts.
Expand Down
30 changes: 30 additions & 0 deletions docs/Tutorial-07-LSP-and-Tooling.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# 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
Expand All @@ -13,6 +15,12 @@ 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 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;
Expand Down Expand Up @@ -52,6 +60,11 @@ cellc --lsp

In practice you usually let the editor start it for you.

On 0.22, qualified enum completion includes concrete payload constructors.
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 remain unsupported.

## VS Code Extension

The extension lives in:
Expand Down Expand Up @@ -83,6 +96,7 @@ Useful settings:
| `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.registryApiUrl` | Optional Registry API base URL used by LS-IDL fetch. |
| `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. |

Expand All @@ -95,11 +109,27 @@ The extension contributes commands for the local compiler and builder loop:
| `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 |
| `CellScript: Validate LS-IDL` | `cellc artifact ls-idl validate --idl <active-json>` |
| `CellScript: Bind LS-IDL to CKB Executable` | `cellc artifact ls-idl bind --idl <active-json> --executable <file>` |
| `CellScript: Fetch LS-IDL by CKB Script` | `cellc artifact ls-idl fetch --code-hash <hash> --output idl.json` |

The editor saves fetched IDL as the exact response bytes and leaves schema,
digest, and executable-suffix checks to `cellc`. This is an interface identity
check, not proof of implementation correctness or a security audit.

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.

`CellScript: Show Production Report` is useful while editing because it displays
compiler version, metadata, constraints, and release-audit boundaries.
Expand Down
155 changes: 149 additions & 6 deletions extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,24 @@ function activate(context) {
if (document) {
await runProductionReport(document, output, status);
}
}),
vscode.commands.registerCommand("cellscript.validateLsIdl", async () => {
const document = await activeLsIdlDocument();
if (document) {
await runLsIdlValidate(document, output, status);
}
}),
vscode.commands.registerCommand("cellscript.bindLsIdl", async () => {
const document = await activeLsIdlDocument();
if (document) {
await runLsIdlBind(document, output, status);
}
}),
vscode.commands.registerCommand("cellscript.fetchLsIdl", async () => {
const document = compilerContextDocument();
if (document) {
await runLsIdlFetch(document, output, status);
}
})
);
}
Expand Down Expand Up @@ -232,6 +250,32 @@ function activeCellScriptDocument() {
return editor.document;
}

async function activeLsIdlDocument() {
const editor = vscode.window.activeTextEditor;
if (!editor || editor.document.uri.scheme !== "file" || !editor.document.uri.fsPath.endsWith(".json")) {
vscode.window.showWarningMessage("Open the LS-IDL JSON file first.");
return null;
}
if (editor.document.isDirty && !(await editor.document.save())) {
vscode.window.showErrorMessage("Save the LS-IDL file before validating or binding it.");
return null;
}
return editor.document;
}

function compilerContextDocument() {
const document = vscode.window.activeTextEditor?.document;
if (document?.uri?.scheme === "file") {
return document;
}
const workspace = vscode.workspace.workspaceFolders?.[0];
if (workspace) {
return { uri: workspace.uri };
}
vscode.window.showWarningMessage("Open a workspace or file before fetching LS-IDL.");
return null;
}

async function resolveCompilerCommand(document) {
const config = vscode.workspace.getConfiguration("cellscript", document.uri);
const compilerPath = config.get("compilerPath", "cellc");
Expand Down Expand Up @@ -496,6 +540,105 @@ async function runRegistryVerify(document, output, status, live) {
});
}

async function runLsIdlValidate(document, output, status) {
await runSingleCellcCommand(document, output, status, {
source: "cellc artifact ls-idl validate",
args: ["artifact", "ls-idl", "validate", "--idl", document.uri.fsPath, "--json"],
cwd: path.dirname(document.uri.fsPath),
input: document.uri.fsPath,
successMessage: "LS-IDL schema is valid.",
errorMessage: "LS-IDL validation"
});
}

async function runLsIdlBind(document, output, status) {
const executable = await vscode.window.showOpenDialog({
canSelectFiles: true,
canSelectFolders: false,
canSelectMany: false,
title: "Select the CKB executable to bind",
filters: { "CKB executable": ["elf", "bin", "*"], "All files": ["*"] }
});
if (!executable?.[0]) return;
const sourcePath = executable[0].fsPath;
const outputUri = await vscode.window.showSaveDialog({
title: "Save the LS-IDL-bound executable",
defaultUri: vscode.Uri.file(`${sourcePath}.ls-idl`)
});
if (!outputUri) return;
await runSingleCellcCommand(document, output, status, {
source: "cellc artifact ls-idl bind",
args: [
"artifact", "ls-idl", "bind",
"--idl", document.uri.fsPath,
"--executable", sourcePath,
"--output", outputUri.fsPath,
"--json"
],
cwd: path.dirname(document.uri.fsPath),
input: document.uri.fsPath,
outputPath: outputUri.fsPath,
successMessage: `LS-IDL digest appended to ${outputUri.fsPath}`,
errorMessage: "LS-IDL executable binding"
});
}

async function runLsIdlFetch(document, output, status) {
const codeHash = await vscode.window.showInputBox({
title: "Fetch LS-IDL",
prompt: "CKB Script code hash",
placeHolder: "0x followed by 64 hexadecimal characters",
validateInput: (value) => /^0x[0-9a-fA-F]{64}$/.test(value.trim()) ? null : "Enter a 32-byte 0x-prefixed code hash."
});
if (!codeHash) return;
const hashType = await vscode.window.showQuickPick(["data1", "data2", "data", "type"], {
title: "Select the Script hash type"
});
if (!hashType) return;
let dataHash = "";
if (hashType === "type") {
const selected = await vscode.window.showInputBox({
title: "Disambiguate type-hash deployment",
prompt: "Code Cell data hash",
placeHolder: "0x followed by 64 hexadecimal characters",
validateInput: (value) => /^0x[0-9a-fA-F]{64}$/.test(value.trim()) ? null : "Enter a 32-byte 0x-prefixed data hash."
});
if (!selected) return;
dataHash = selected.trim();
}
const configuredNetwork = vscode.workspace.getConfiguration("cellscript", document.uri).get("deploymentNetwork", "");
const network = configuredNetwork || await vscode.window.showQuickPick(["mainnet", "testnet"], {
title: "Select the Registry network"
});
if (!network) return;
const workspace = vscode.workspace.getWorkspaceFolder(document.uri)?.uri;
const outputUri = await vscode.window.showSaveDialog({
title: "Save exact LS-IDL bytes",
defaultUri: workspace ? vscode.Uri.joinPath(workspace, "idl.json") : vscode.Uri.file(path.join(os.tmpdir(), "idl.json")),
filters: { "JSON": ["json"] }
});
if (!outputUri) return;
const args = [
"artifact", "ls-idl", "fetch",
"--code-hash", codeHash.trim(),
"--hash-type", hashType,
"--network", network,
"--output", outputUri.fsPath,
"--json"
];
if (dataHash) args.push("--data-hash", dataHash);
const apiUrl = vscode.workspace.getConfiguration("cellscript", document.uri).get("registryApiUrl", "").trim();
if (apiUrl) args.push("--api-url", apiUrl);
await runSingleCellcCommand(document, output, status, {
source: "cellc artifact ls-idl fetch",
args,
cwd: workspace?.fsPath,
outputPath: outputUri.fsPath,
successMessage: `Exact LS-IDL bytes saved to ${outputUri.fsPath}`,
errorMessage: "LS-IDL fetch"
});
}

async function selectMetadataEntry(document, output, status, input, options) {
const metadata = await loadMetadataForSelection(document, output, status, input, options.source);
if (!metadata) {
Expand Down Expand Up @@ -649,25 +792,25 @@ function buildReportPlan(document, kind, cwd) {

if (kind === "builder-assumptions") {
return {
args: ["explain-assumptions", document.uri.fsPath, ...targetProfileArgs(document), "--json"],
args: ["explain", "assumptions", document.uri.fsPath, ...targetProfileArgs(document), "--json"],
outputPath: null,
source: "cellc explain-assumptions"
source: "cellc explain assumptions"
};
}

if (kind === "tx-template") {
return {
args: ["solve-tx", document.uri.fsPath, ...targetProfileArgs(document), "--json"],
args: ["tx", "solve", document.uri.fsPath, ...targetProfileArgs(document), "--json"],
outputPath: null,
source: "cellc solve-tx"
source: "cellc tx solve"
};
}

if (kind === "deploy-plan") {
return {
args: ["deploy-plan", document.uri.fsPath, ...targetProfileArgs(document), "--json"],
args: ["deploy", "plan", document.uri.fsPath, ...targetProfileArgs(document), "--json"],
outputPath: null,
source: "cellc deploy-plan"
source: "cellc deploy plan"
};
}

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading