diff --git a/CHANGELOG.md b/CHANGELOG.md index 3849885..e74b1ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,10 +28,39 @@ release notes. ### Tools +- None yet. + +### Measurements + +- None yet. + +## 0.2.12 (2026-08-14) + +### Programs that used to compile and no longer do + +- None yet. + +### Language + +- None yet. + +### Diagnostics + +- None yet. + +### Standard library + +- None yet. + +### Tools + - The declared minimum Rust toolchain is now 1.88, matching the let-chain syntax already used by the parser and resolver. Rust 1.87 and older failed before `deed-lang` could compile. CI now builds the workspace with 1.88 so the declaration cannot silently fall behind the source again. +- The `deed-lang` package now carries its README and the ownership marker used + by the official MCP Registry. Root `server.json` describes `deed mcp` as a + Cargo-installed stdio server. ### Measurements diff --git a/Cargo.lock b/Cargo.lock index 0d775b2..12b8207 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,14 +4,14 @@ version = 4 [[package]] name = "deed-ast" -version = "0.2.11" +version = "0.2.12" dependencies = [ "deed-diagnostics", ] [[package]] name = "deed-codegen" -version = "0.2.11" +version = "0.2.12" dependencies = [ "deed-diagnostics", "deed-mir", @@ -20,7 +20,7 @@ dependencies = [ [[package]] name = "deed-dap" -version = "0.2.11" +version = "0.2.12" dependencies = [ "deed-diagnostics", "deed-driver", @@ -31,11 +31,11 @@ dependencies = [ [[package]] name = "deed-diagnostics" -version = "0.2.11" +version = "0.2.12" [[package]] name = "deed-driver" -version = "0.2.11" +version = "0.2.12" dependencies = [ "deed-ast", "deed-codegen", @@ -54,7 +54,7 @@ dependencies = [ [[package]] name = "deed-effects" -version = "0.2.11" +version = "0.2.12" dependencies = [ "deed-ast", "deed-diagnostics", @@ -66,15 +66,15 @@ dependencies = [ [[package]] name = "deed-explain" -version = "0.2.11" +version = "0.2.12" [[package]] name = "deed-fetch" -version = "0.2.11" +version = "0.2.12" [[package]] name = "deed-fmt" -version = "0.2.11" +version = "0.2.12" dependencies = [ "deed-ast", "deed-diagnostics", @@ -84,7 +84,7 @@ dependencies = [ [[package]] name = "deed-interp" -version = "0.2.11" +version = "0.2.12" dependencies = [ "deed-ast", "deed-diagnostics", @@ -96,7 +96,7 @@ dependencies = [ [[package]] name = "deed-lang" -version = "0.2.11" +version = "0.2.12" dependencies = [ "deed-ast", "deed-codegen", @@ -118,14 +118,14 @@ dependencies = [ [[package]] name = "deed-lexer" -version = "0.2.11" +version = "0.2.12" dependencies = [ "deed-diagnostics", ] [[package]] name = "deed-lsp" -version = "0.2.11" +version = "0.2.12" dependencies = [ "deed-ast", "deed-diagnostics", @@ -139,7 +139,7 @@ dependencies = [ [[package]] name = "deed-mcp" -version = "0.2.11" +version = "0.2.12" dependencies = [ "deed-diagnostics", "deed-driver", @@ -150,7 +150,7 @@ dependencies = [ [[package]] name = "deed-mir" -version = "0.2.11" +version = "0.2.12" dependencies = [ "deed-ast", "deed-diagnostics", @@ -162,7 +162,7 @@ dependencies = [ [[package]] name = "deed-parser" -version = "0.2.11" +version = "0.2.12" dependencies = [ "deed-ast", "deed-diagnostics", @@ -171,7 +171,7 @@ dependencies = [ [[package]] name = "deed-resolve" -version = "0.2.11" +version = "0.2.12" dependencies = [ "deed-ast", "deed-diagnostics", @@ -181,11 +181,11 @@ dependencies = [ [[package]] name = "deed-rt" -version = "0.2.11" +version = "0.2.12" [[package]] name = "deed-typeck" -version = "0.2.11" +version = "0.2.12" dependencies = [ "deed-ast", "deed-diagnostics", @@ -196,7 +196,7 @@ dependencies = [ [[package]] name = "deed-wasm" -version = "0.2.11" +version = "0.2.12" dependencies = [ "deed-ast", "deed-diagnostics", diff --git a/Cargo.toml b/Cargo.toml index 960977f..f5ad5e9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ members = [ ] [workspace.package] -version = "0.2.11" +version = "0.2.12" edition = "2024" license = "Apache-2.0" repository = "https://github.com/deed-lang/deed" @@ -36,25 +36,25 @@ rust-version = "1.88" # `deed-x.workspace = true`. These have to equal the version above, and # `crates/deed-driver/tests/publishing.rs` says so rather than trusting it. [workspace.dependencies] -deed-ast = { path = "crates/deed-ast", version = "0.2.11" } -deed-codegen = { path = "crates/deed-codegen", version = "0.2.11" } -deed-dap = { path = "crates/deed-dap", version = "0.2.11" } -deed-diagnostics = { path = "crates/deed-diagnostics", version = "0.2.11" } -deed-driver = { path = "crates/deed-driver", version = "0.2.11" } -deed-effects = { path = "crates/deed-effects", version = "0.2.11" } -deed-explain = { path = "crates/deed-explain", version = "0.2.11" } -deed-fetch = { path = "crates/deed-fetch", version = "0.2.11" } -deed-fmt = { path = "crates/deed-fmt", version = "0.2.11" } -deed-interp = { path = "crates/deed-interp", version = "0.2.11" } -deed-lexer = { path = "crates/deed-lexer", version = "0.2.11" } -deed-lsp = { path = "crates/deed-lsp", version = "0.2.11" } -deed-mcp = { path = "crates/deed-mcp", version = "0.2.11" } -deed-mir = { path = "crates/deed-mir", version = "0.2.11" } -deed-parser = { path = "crates/deed-parser", version = "0.2.11" } -deed-resolve = { path = "crates/deed-resolve", version = "0.2.11" } -deed-rt = { path = "crates/deed-rt", version = "0.2.11" } -deed-typeck = { path = "crates/deed-typeck", version = "0.2.11" } -deed-wasm = { path = "crates/deed-wasm", version = "0.2.11" } +deed-ast = { path = "crates/deed-ast", version = "0.2.12" } +deed-codegen = { path = "crates/deed-codegen", version = "0.2.12" } +deed-dap = { path = "crates/deed-dap", version = "0.2.12" } +deed-diagnostics = { path = "crates/deed-diagnostics", version = "0.2.12" } +deed-driver = { path = "crates/deed-driver", version = "0.2.12" } +deed-effects = { path = "crates/deed-effects", version = "0.2.12" } +deed-explain = { path = "crates/deed-explain", version = "0.2.12" } +deed-fetch = { path = "crates/deed-fetch", version = "0.2.12" } +deed-fmt = { path = "crates/deed-fmt", version = "0.2.12" } +deed-interp = { path = "crates/deed-interp", version = "0.2.12" } +deed-lexer = { path = "crates/deed-lexer", version = "0.2.12" } +deed-lsp = { path = "crates/deed-lsp", version = "0.2.12" } +deed-mcp = { path = "crates/deed-mcp", version = "0.2.12" } +deed-mir = { path = "crates/deed-mir", version = "0.2.12" } +deed-parser = { path = "crates/deed-parser", version = "0.2.12" } +deed-resolve = { path = "crates/deed-resolve", version = "0.2.12" } +deed-rt = { path = "crates/deed-rt", version = "0.2.12" } +deed-typeck = { path = "crates/deed-typeck", version = "0.2.12" } +deed-wasm = { path = "crates/deed-wasm", version = "0.2.12" } [workspace.lints.clippy] all = "warn" diff --git a/README.md b/README.md index 12a6849..864fbaa 100644 --- a/README.md +++ b/README.md @@ -48,9 +48,9 @@ language server are all in that one file. Start with the [tutorial](TUTORIAL.md) if you want one program built up one step at a time. ``` -$ tar xzf deed-v0.2.11-x86_64-unknown-linux-gnu.tar.gz -$ ./deed-v0.2.11-x86_64-unknown-linux-gnu/deed --version -deed 0.2.11 +$ tar xzf deed-v0.2.12-x86_64-unknown-linux-gnu.tar.gz +$ ./deed-v0.2.12-x86_64-unknown-linux-gnu/deed --version +deed 0.2.12 ``` With Rust 1.88 or newer instead, from crates.io or from a clone: @@ -61,7 +61,8 @@ $ cargo install --path crates/deed-cli ``` `deed` on crates.io belongs to somebody else, so the package is `deed-lang`. -The binary it installs is `deed`. +The binary it installs is `deed`; the [package README](crates/deed-cli/README.md) +keeps the short install and MCP entry points next to the package metadata. **What the version promises.** `0.x` says the language can still move, so a file that compiles against one minor release may not compile against the next. Breaking moves are @@ -152,6 +153,7 @@ stdout, so the machine writing the code can ask the compiler the same questions an editor does rather than scraping them out of terminal output. It holds no capability: a program arrives as text, the answer leaves as text, and a program whose row reaches a file is refused before it runs. +Its official Registry name is `mcp-name: io.github.deed-lang/deed`. [how-to/let-an-agent-use-the-compiler.md](how-to/let-an-agent-use-the-compiler.md) has the tool reference and the one line worth reading. diff --git a/crates/deed-cli/Cargo.toml b/crates/deed-cli/Cargo.toml index eda7881..1c151cf 100644 --- a/crates/deed-cli/Cargo.toml +++ b/crates/deed-cli/Cargo.toml @@ -9,6 +9,7 @@ # it would rewrite sentences that were true when they were written. name = "deed-lang" description = "The deed command line tool" +readme = "README.md" version.workspace = true edition.workspace = true license.workspace = true diff --git a/crates/deed-cli/README.md b/crates/deed-cli/README.md new file mode 100644 index 0000000..692ba76 --- /dev/null +++ b/crates/deed-cli/README.md @@ -0,0 +1,23 @@ +# Deed + +Deed is a contract-first language for code that machines write and humans +review. The toolchain checks types, effect rows, capabilities, contracts, and +before-and-after patch receipts. + +```console +cargo install deed-lang +deed new greeting +deed check greeting +deed test greeting +``` + +The package is named `deed-lang`; it installs the `deed` binary. Run the local +Model Context Protocol server over stdio with: + +```console +deed mcp +``` + +- [Repository](https://github.com/deed-lang/deed) +- [Agent guide](https://deed-lang.github.io/agents/) +- MCP Registry name: `mcp-name: io.github.deed-lang/deed` \ No newline at end of file diff --git a/crates/deed-cli/tests/registry.rs b/crates/deed-cli/tests/registry.rs new file mode 100644 index 0000000..92c72f6 --- /dev/null +++ b/crates/deed-cli/tests/registry.rs @@ -0,0 +1,77 @@ +use std::path::{Path, PathBuf}; + +use deed_lsp::{Json, json}; + +const NAME: &str = "io.github.deed-lang/deed"; + +fn root() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .parent() + .and_then(Path::parent) + .expect("the workspace root should be two directories up") + .to_path_buf() +} + +fn read(path: &str) -> String { + std::fs::read_to_string(root().join(path)).unwrap_or_else(|why| panic!("{path}: {why}")) +} + +#[test] +fn official_registry_metadata_describes_the_published_mcp_command() { + let metadata = json::parse(&read("server.json")).expect("server.json should be JSON"); + assert_eq!(metadata.get("name").and_then(Json::as_str), Some(NAME)); + assert_eq!( + metadata.get("version").and_then(Json::as_str), + Some(env!("CARGO_PKG_VERSION")) + ); + assert_eq!( + metadata.at(&["repository", "url"]).and_then(Json::as_str), + Some(env!("CARGO_PKG_REPOSITORY")) + ); + + let packages = metadata + .get("packages") + .and_then(Json::as_array) + .expect("server.json should describe a package"); + assert_eq!(packages.len(), 1); + let package = &packages[0]; + assert_eq!( + package.get("registryType").and_then(Json::as_str), + Some("cargo") + ); + assert_eq!( + package.get("identifier").and_then(Json::as_str), + Some(env!("CARGO_PKG_NAME")) + ); + assert_eq!( + package.get("version").and_then(Json::as_str), + Some(env!("CARGO_PKG_VERSION")) + ); + assert_eq!( + package.at(&["transport", "type"]).and_then(Json::as_str), + Some("stdio") + ); + + let arguments = package + .get("packageArguments") + .and_then(Json::as_array) + .expect("deed needs its mcp subcommand"); + assert_eq!(arguments.len(), 1); + assert_eq!( + arguments[0].get("type").and_then(Json::as_str), + Some("positional") + ); + assert_eq!( + arguments[0].get("value").and_then(Json::as_str), + Some("mcp") + ); + + assert_eq!(env!("CARGO_PKG_README"), "README.md"); + let marker = format!("mcp-name: {NAME}"); + assert_eq!( + read("crates/deed-cli/README.md") + .matches(marker.as_str()) + .count(), + 1 + ); +} diff --git a/server.json b/server.json new file mode 100644 index 0000000..43b7127 --- /dev/null +++ b/server.json @@ -0,0 +1,30 @@ +{ + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json", + "name": "io.github.deed-lang/deed", + "title": "Deed", + "description": "Contract-first language and MCP server for capability-aware code and patch review.", + "websiteUrl": "https://deed-lang.github.io/agents/", + "repository": { + "url": "https://github.com/deed-lang/deed", + "source": "github", + "subfolder": "crates/deed-cli" + }, + "version": "0.2.12", + "packages": [ + { + "registryType": "cargo", + "registryBaseUrl": "https://crates.io", + "identifier": "deed-lang", + "version": "0.2.12", + "transport": { + "type": "stdio" + }, + "packageArguments": [ + { + "type": "positional", + "value": "mcp" + } + ] + } + ] +} \ No newline at end of file