Skip to main content

max / quasi

Say the initial caret, a screen's feed, and a header band Three vocabulary members answered together, because all three land in quasi-router and three separate breaking bumps would forward-fix the same consumers three times. `Screen::opens_at` names the field the caret starts in, as a screen-level statement beside `place` and `selection` rather than a flag on a field: a fact that cannot be said twice beats one that can. The webview emits `autofocus` and only in a whole document, because a browser answers most interactions with a fragment and a swap that moves the caret takes it out of whatever is being typed into. A terminal places its caret on arrival, and egui is asked for focus on the first frame of a screen. `Discovery::feed` says a screen offers a syndication feed, singular and enum-typed: `application/rss+xml` written by hand at three sites is three chances to write `application/rss` and have a reader skip it. A renderer with no autodiscovery ignores it, said in the doc rather than left to each renderer's author to guess. `Chrome::band` says the header is one element. The nav stays where it is and the band contains it, because an app with places and no band still has places. Named slots rather than a body of nodes, so a renderer can tell a brand from a heading; `Brand` says a name and which run of it is the mark, which is what `Makenot.work` needed and nothing could say. Two corrections fell out of building it. `action_attrs` named its `href` shortcut by exclusion, so every gesture that was not a click got an `href` and, because that branch returns, no transport at all -- a band's search box is exactly that shape and did nothing. It names the one gesture now. And `Outcome`'s `large_enum_variant` expectation came off: `Screen` grew, the spread closed to 184 bytes, and an unfulfilled expectation is itself a warning. `Place::key` rides out as `data-place`, so a host script can find a place without keying off its label.
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session
https://claude.ai/code/session_01MptwXZ8k65v19rFmdGAyki
Author: Max Johnson <me@maxj.phd> · 2026-09-02 12:57 UTC
Signed with PGP, not checked
Commit: 62671f1c7ad35025b78c43e8ae8a9747d3ec6c88
Parent: 0866136
33 files changed, +1650 insertions, -231 deletions
M Cargo.lock +25 -23
@@ -2657,6 +2657,8 @@
2657 2657 [[package]]
2658 2658 name = "makeover-immediate"
2659 2659 version = "0.44.0"
2660 + source = "registry+https://github.com/rust-lang/crates.io-index"
2661 + checksum = "d34f96a7b5b7c26c79ea94b243e911b006e4899270bac418d215ff39f111cda9"
2660 2662 dependencies = [
2661 2663 "egui",
2662 2664 "egui_extras",
@@ -2667,6 +2669,8 @@
2667 2669 [[package]]
2668 2670 name = "makeover-layout"
2669 2671 version = "0.43.0"
2672 + source = "registry+https://github.com/rust-lang/crates.io-index"
2673 + checksum = "c0a9124f65373683ae4320b00bf4a6198b2554ef3ad3af2806b413ac164545fa"
2670 2674
2671 2675 [[package]]
2672 2676 name = "makeover-timing"
@@ -2680,6 +2684,8 @@
2680 2684 [[package]]
2681 2685 name = "makeover-touch"
2682 2686 version = "0.33.0"
2687 + source = "registry+https://github.com/rust-lang/crates.io-index"
2688 + checksum = "6281006f62d84f15c8c88662056e32f2027717bdd61f29d36f7917b9a694d64a"
2683 2689 dependencies = [
2684 2690 "makeover-geometry",
2685 2691 "makeover-layout",
@@ -2688,6 +2694,8 @@
2688 2694 [[package]]
2689 2695 name = "makeover-tui"
2690 2696 version = "0.43.0"
2697 + source = "registry+https://github.com/rust-lang/crates.io-index"
2698 + checksum = "39fc9343435bdcbaef8a5f5e2910254b841b08171919c19795dc50be7b1910ba"
2691 2699 dependencies = [
2692 2700 "makeover",
2693 2701 "makeover-layout",
@@ -2698,6 +2706,8 @@
2698 2706 [[package]]
2699 2707 name = "makeover-webview"
2700 2708 version = "0.72.0"
2709 + source = "registry+https://github.com/rust-lang/crates.io-index"
2710 + checksum = "ae1993234ce8b39b26b326b40cf92f455dfe0656b79d96cbe012c09c982df96d"
2701 2711 dependencies = [
2702 2712 "makeover-geometry",
2703 2713 "makeover-layout",
@@ -3466,11 +3476,11 @@
3466 3476
3467 3477 [[package]]
3468 3478 name = "quasi"
3469 - version = "0.97.0"
3479 + version = "0.98.0"
3470 3480
3471 3481 [[package]]
3472 3482 name = "quasi-axum"
3473 - version = "0.97.0"
3483 + version = "0.98.0"
3474 3484 dependencies = [
3475 3485 "axum",
3476 3486 "http",
@@ -3484,7 +3494,7 @@
3484 3494
3485 3495 [[package]]
3486 3496 name = "quasi-basics"
3487 - version = "0.97.0"
3497 + version = "0.98.0"
3488 3498 dependencies = [
3489 3499 "makeover-layout",
3490 3500 "quasi-http",
@@ -3494,7 +3504,7 @@
3494 3504
3495 3505 [[package]]
3496 3506 name = "quasi-bench"
3497 - version = "0.97.0"
3507 + version = "0.98.0"
3498 3508 dependencies = [
3499 3509 "askama",
3500 3510 "dhat",
@@ -3511,7 +3521,7 @@
3511 3521
3512 3522 [[package]]
3513 3523 name = "quasi-http"
3514 - version = "0.97.0"
3524 + version = "0.98.0"
3515 3525 dependencies = [
3516 3526 "form_urlencoded",
3517 3527 "http",
@@ -3520,7 +3530,7 @@
3520 3530
3521 3531 [[package]]
3522 3532 name = "quasi-immediate"
3523 - version = "0.97.0"
3533 + version = "0.98.0"
3524 3534 dependencies = [
3525 3535 "docengine",
3526 3536 "egui",
@@ -3531,7 +3541,7 @@
3531 3541
3532 3542 [[package]]
3533 3543 name = "quasi-notifs"
3534 - version = "0.97.0"
3544 + version = "0.98.0"
3535 3545 dependencies = [
3536 3546 "quasi-router",
3537 3547 "synckit-config",
@@ -3541,7 +3551,7 @@
3541 3551
3542 3552 [[package]]
3543 3553 name = "quasi-router"
3544 - version = "0.97.0"
3554 + version = "0.98.0"
3545 3555 dependencies = [
3546 3556 "makeover-layout",
3547 3557 ]
@@ -3558,7 +3568,7 @@
3558 3568
3559 3569 [[package]]
3560 3570 name = "quasi-tauri"
3561 - version = "0.97.0"
3571 + version = "0.98.0"
3562 3572 dependencies = [
3563 3573 "http",
3564 3574 "quasi-http",
@@ -3569,7 +3579,7 @@
3569 3579
3570 3580 [[package]]
3571 3581 name = "quasi-tui"
3572 - version = "0.97.0"
3582 + version = "0.98.0"
3573 3583 dependencies = [
3574 3584 "docengine",
3575 3585 "makeover",
@@ -3582,7 +3592,7 @@
3582 3592
3583 3593 [[package]]
3584 3594 name = "quasi-webview"
3585 - version = "0.97.0"
3595 + version = "0.98.0"
3586 3596 dependencies = [
3587 3597 "docengine",
3588 3598 "makeover-layout",
@@ -6257,22 +6267,14 @@
6257 6267 "winnow 1.0.4",
6258 6268 ]
6259 6269
6260 - [[patch.unused]]
6261 - name = "synckit-client"
6262 - version = "0.10.0"
6263 -
6264 - [[patch.unused]]
6265 - name = "alloy_tui"
6266 - version = "14.0.0"
6267 -
6268 - [[patch.unused]]
6269 - name = "makeover-build"
6270 - version = "0.65.0"
6271 -
6272 6270 [[patch.unused]]
6273 6271 name = "quasi-type"
6274 6272 version = "0.1.3"
6275 6273
6274 + [[patch.unused]]
6275 + name = "synckit-client"
6276 + version = "0.10.0"
6277 +
6276 6278 [[patch.unused]]
6277 6279 name = "kberg"
6278 6280 version = "0.1.0"
@@ -1,6 +1,6 @@
1 1 [package]
2 2 name = "quasi-axum"
3 - version = "0.97.0"
3 + version = "0.98.0"
4 4 description = "The axum host adapter for quasi-router: an HTTP request in, a rendered description out"
5 5 edition.workspace = true
6 6 rust-version.workspace = true
@@ -13,14 +13,14 @@
13 13 workspace = true
14 14
15 15 [dependencies]
16 - quasi-router = { path = "../quasi-router", version = "0.97.0" }
17 - quasi-http = { path = "../quasi-http", version = "0.97.0" }
16 + quasi-router = { path = "../quasi-router", version = "0.98.0" }
17 + quasi-http = { path = "../quasi-http", version = "0.98.0" }
18 18 axum = "0.8.8"
19 19 http = "1.3.1"
20 20 tokio = { version = "1.50.0", features = ["rt"] }
21 21
22 22 [dev-dependencies]
23 - quasi-webview = { path = "../quasi-webview", version = "0.97.0" }
23 + quasi-webview = { path = "../quasi-webview", version = "0.98.0" }
24 24 tokio = { version = "1.50.0", features = ["macros", "rt-multi-thread"] }
25 25 tower = { version = "0.5.3", features = ["util"] }
26 26 http-body-util = "0.1.3"
@@ -1,6 +1,6 @@
1 1 [package]
2 2 name = "quasi-basics"
3 - version = "0.97.0"
3 + version = "0.98.0"
4 4 description = "The first-party widget set: named assemblies of primitives, shared across our apps"
5 5 edition.workspace = true
6 6 rust-version.workspace = true
@@ -13,12 +13,12 @@
13 13 workspace = true
14 14
15 15 [dependencies]
16 - quasi-router = { path = "../quasi-router", version = "0.97.0" }
16 + quasi-router = { path = "../quasi-router", version = "0.98.0" }
17 17 makeover-layout = "0.43"
18 18
19 19 [dev-dependencies]
20 20 # A widget's guarantees are claims about what a renderer draws, so they are
21 21 # tested against a real one rather than by walking the tree the assembly just
22 22 # built. The webview is the renderer that recognises names today.
23 - quasi-webview = { path = "../quasi-webview", version = "0.97.0" }
24 - quasi-http = { path = "../quasi-http", version = "0.97.0" }
23 + quasi-webview = { path = "../quasi-webview", version = "0.98.0" }
24 + quasi-http = { path = "../quasi-http", version = "0.98.0" }
@@ -1,6 +1,6 @@
1 1 [package]
2 2 name = "quasi-bench"
3 - version = "0.97.0"
3 + version = "0.98.0"
4 4 description = "What a described screen costs to render, in time and in allocations"
5 5 edition.workspace = true
6 6 rust-version.workspace = true
@@ -26,13 +26,13 @@
26 26 askama = ["dep:askama"]
27 27
28 28 [dependencies]
29 - quasi-router = { path = "../quasi-router", version = "0.97.0" }
30 - quasi-webview = { path = "../quasi-webview", version = "0.97.0" }
31 - quasi-tui = { path = "../quasi-tui", version = "0.97.0" }
29 + quasi-router = { path = "../quasi-router", version = "0.98.0" }
30 + quasi-webview = { path = "../quasi-webview", version = "0.98.0" }
31 + quasi-tui = { path = "../quasi-tui", version = "0.98.0" }
32 32 # `Serves` is the trait carrying `screen` and `fragment`, which is what the
33 33 # webview is measured through. Taken directly rather than through quasi-webview
34 34 # because a bench calling a trait method should name the trait it calls.
35 - quasi-http = { path = "../quasi-http", version = "0.97.0" }
35 + quasi-http = { path = "../quasi-http", version = "0.98.0" }
36 36 makeover-layout = "0.43"
37 37 # The renderer's own escaper, so the staged path fills a hole exactly the way
38 38 # `Node::Text` does and the guarantee is not quietly reimplemented.
@@ -1,6 +1,6 @@
1 1 [package]
2 2 name = "quasi-http"
3 - version = "0.97.0"
3 + version = "0.98.0"
4 4 description = "The http-shaped seam quasi's webview host adapters share: decoding in, a rendered description out"
5 5 edition.workspace = true
6 6 rust-version.workspace = true
@@ -13,6 +13,6 @@
13 13 workspace = true
14 14
15 15 [dependencies]
16 - quasi-router = { path = "../quasi-router", version = "0.97.0" }
16 + quasi-router = { path = "../quasi-router", version = "0.98.0" }
17 17 http = "1.3.1"
18 18 form_urlencoded = "1.2.2"
@@ -1,6 +1,6 @@
1 1 [package]
2 2 name = "quasi-immediate"
3 - version = "0.97.0"
3 + version = "0.98.0"
4 4 edition = "2024"
5 5 description = "The immediate-mode renderer for quasi-router: a described screen in, an egui frame out. Immediate mode is the constraint that matters, not the library."
6 6 license = "MIT"
@@ -12,7 +12,7 @@
12 12 categories = ["gui"]
13 13
14 14 [dependencies]
15 - quasi-router = { path = "../quasi-router", version = "0.97.0" }
15 + quasi-router = { path = "../quasi-router", version = "0.98.0" }
16 16 # The node drawing, which is the makeover layer's and not this crate's. Every
17 17 # widget here that is not a container comes from it: a screen walk that painted
18 18 # its own meter would be the divergence the suite exists to end, one copy per
@@ -1,6 +1,6 @@
1 1 [package]
2 2 name = "quasi-notifs"
3 - version = "0.97.0"
3 + version = "0.98.0"
4 4 description = "Declared notification kinds and the registry that holds them: what a notification says and what it is for, apart from how it reaches a person"
5 5 edition.workspace = true
6 6 rust-version.workspace = true
@@ -28,7 +28,7 @@
28 28 tauri = ["dep:tauri", "dep:tauri-plugin-notification"]
29 29
30 30 [dependencies]
31 - quasi-router = { path = "../quasi-router", version = "0.97.0", optional = true }
31 + quasi-router = { path = "../quasi-router", version = "0.98.0", optional = true }
32 32 synckit-config = { git = "https://makenot.work/git/max/synckit.git", version = "0.2", optional = true }
33 33 tauri-plugin-notification = { version = "2.3.3", optional = true }
34 34 # Default features off, for `quasi-tauri`'s reason: this takes an `AppHandle`