diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 72f786d6..00c7fcd0 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -123,6 +123,27 @@ jobs:
python -m pip install build
python -m build
+ web:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-node@v4
+ with:
+ node-version: 22
+ cache: npm
+ cache-dependency-path: web/package-lock.json
+ - run: npm ci
+ working-directory: web
+ - run: npm test
+ working-directory: web
+ - run: npm run build
+ working-directory: web
+ - name: Check static Pages artifact
+ working-directory: web
+ run: |
+ test -s dist/index.html
+ test "$(find dist -type f | wc -l)" -eq 1
+
test-embedded:
runs-on: ubuntu-latest
timeout-minutes: 45
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 956209f7..c51d205e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -31,8 +31,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* `miniconf_mqtt` is now async-first on `minimq::Session`. The old `update()` loop was replaced by
`Miniconf::poll().await`, which returns `Changed`, `Connected`, `Reconnected`, or `Other`.
* `miniconf_mqtt` MM2 now publishes retained manifest, paged schema, and authoritative retained
- settings. Compatibility with request/response-only settings writes is retained behind the
- `compat-settings-ingress` feature.
+ settings. Compatibility with direct `settings/#` writes is available when applications
+ explicitly subscribe to and route those publications through `Service`.
* MM2 manifests now publish `epoch` and `schema_rev`. Long-lived Python clients use `schema_rev`
to invalidate cached schema.
* The Python package was restructured from `py/miniconf-mqtt` to `py/` and now targets the MM2
diff --git a/miniconf/README.md b/miniconf/README.md
index 46c71ca1..fe8d7d2d 100644
--- a/miniconf/README.md
+++ b/miniconf/README.md
@@ -72,7 +72,7 @@ boundary needs something more specific:
[`macro@TreeDeserialize`], and [`macro@TreeAny`]. Derive attributes live under
`#[tree(...)]`:
-- `rename = "name"` changes a field or variant path segment.
+- `rename = ident` changes a field or variant path segment to a Rust identifier.
- `skip` removes a field or variant from the tree.
- `flatten` splices a single unambiguous child tree into its parent.
- `with = module` delegates access to a custom implementation module.
diff --git a/miniconf_coap/Cargo.toml b/miniconf_coap/Cargo.toml
index cae80fa6..d62a1484 100644
--- a/miniconf_coap/Cargo.toml
+++ b/miniconf_coap/Cargo.toml
@@ -9,6 +9,7 @@ license.workspace = true
categories.workspace = true
keywords.workspace = true
repository.workspace = true
+readme = "README.md"
[lints]
workspace = true
diff --git a/miniconf_coap/src/lib.rs b/miniconf_coap/src/lib.rs
index 3df065b6..feef5959 100644
--- a/miniconf_coap/src/lib.rs
+++ b/miniconf_coap/src/lib.rs
@@ -1,15 +1,7 @@
#![no_std]
+#![doc = include_str!("../README.md")]
#![warn(missing_docs)]
-//! Serve selected `miniconf` trees as CoAP resources.
-//!
-//! The crate is deliberately sessionless. Applications pass caller-owned settings into value
-//! routes, and keep ownership of CoAP sockets, message IDs, tokens, routing, retransmission, and
-//! unrelated resources.
-//!
-//! The schema route serves a JSON manifest at `/schema` and compact text schema pages at
-//! `/schema/{page}`.
-
use miniconf::Indices;
/// Maximum Miniconf tree depth supported by `miniconf_coap`.
diff --git a/miniconf_derive/src/lib.rs b/miniconf_derive/src/lib.rs
index 77767cd4..3ae67fd3 100644
--- a/miniconf_derive/src/lib.rs
+++ b/miniconf_derive/src/lib.rs
@@ -34,7 +34,7 @@
//!
//! `#[tree(...)]` is accepted on containers, fields, and variants:
//!
-//! - `rename = "name"` exposes a different path segment.
+//! - `rename = ident` exposes a different Rust identifier as the path segment.
//! - `skip` removes the field or variant from the tree.
//! - `flatten` splices one child tree into the parent when lookup is unambiguous.
//! - `with = module` delegates schema, serialization, deserialization, and `Any`
diff --git a/web/src/TreeView.svelte b/web/src/TreeView.svelte
new file mode 100644
index 00000000..849887c6
--- /dev/null
+++ b/web/src/TreeView.svelte
@@ -0,0 +1,68 @@
+