Skip to main content

max / quasi

Say four crates, because there are four The scaffolder's own report, its usage text and the generated README all still described the two webview hosts. Also fixes the theme load in the terminal host: `makeover::bundled_themes_dir` answers an Option, which the in-tree build never checked because nothing in the tree builds the template.
Author: Max Johnson <me@maxj.phd> · 2026-08-12 17:22 UTC
Signed with PGP, not checked
Commit: 9d176f1717c693fbd5116c591d46007288e7e3d6
Parent: f6d9e09
3 files changed, +21 insertions, -11 deletions
@@ -85,9 +85,9 @@
85 85
86 86 [directory] defaults to ./<name>. It must not already exist.
87 87
88 - What you get is a workspace of three crates — <name>-core, <name>-desktop and
89 - <name>-server — the same screens served by both hosts, and no auth, which the
90 - generated README explains rather than leaves silent.";
88 + What you get is a workspace of four crates — <name>-core, <name>-desktop,
89 + <name>-server and <name>-tui — the same screens served by all three hosts, and
90 + no auth, which the generated README explains rather than leaves silent.";
91 91
92 92 /// Generate an app. Answers with where it landed, and under what name.
93 93 ///
@@ -179,10 +179,10 @@
179 179 let dir = root.display();
180 180 let app = &name.kebab;
181 181
182 - println!("Created {dir} — {} files, three crates.", FILES.len());
182 + println!("Created {dir} — {} files, four crates.", FILES.len());
183 183 println!();
184 - // Padded against the longest of the three, so the notes line up whatever
185 - // the name's length.
184 + // Padded against the longest of them, so the notes line up whatever the
185 + // name's length.
186 186 let width = format!("cargo run -p {app}-desktop").len();
187 187 println!(" cd {dir}");
188 188 println!(" {:width$} the screens, with no host", "cargo test");
@@ -194,6 +194,10 @@
194 194 " {:width$} a window",
195 195 format!("cargo run -p {app}-desktop")
196 196 );
197 + println!(
198 + " {:width$} a terminal",
199 + format!("cargo run -p {app}-tui")
200 + );
197 201 println!();
198 202 println!("The first build generates the design system's stylesheets and");
199 203 println!("materialises the themes, so it is slower than the ones after it.");
@@ -8,11 +8,18 @@
8 8 ```
9 9 cargo run -p {{name}}-server # http://127.0.0.1:3000
10 10 cargo run -p {{name}}-desktop # a window
11 + cargo run -p {{name}}-tui # a terminal
11 12 cargo test # the screens, with no host at all
12 13 ```
13 14
14 - Both binaries serve the same screens from the same router. Neither knows the
15 - other exists.
15 + All three binaries serve the same screens from the same router, and none of
16 + them knows the others exist. Delete any one of them and nothing else changes:
17 + a host is a renderer and a loop, and the router names neither.
18 +
19 + The terminal one is worth keeping even if the app is not for terminals. A
20 + webview can express anything, so it never pushes back on a description; a
21 + terminal draws cells, and every place a screen says something it cannot honour
22 + is a gap worth knowing about.
16 23
17 24 ## The shape
18 25
@@ -20,8 +27,8 @@
20 27 request (path + params)
21 28 -> router {{name}}-core, imports no host crate
22 29 -> description makeover-layout
23 - -> renderer quasi-webview
24 - -> host adapter axum route | Tauri custom protocol
30 + -> renderer quasi-webview | quasi-tui
31 + -> host adapter axum route | Tauri custom protocol | a terminal loop
25 32 ```
26 33
27 34 | Crate | What it is |
@@ -187,7 +187,6 @@
187 187 let wanted = std::env::var("{{SCREAM}}_THEME").unwrap_or_else(|_| DEFAULT_THEME.to_owned());
188 188
189 189 let theme = makeover::bundled_themes_dir()
190 - .ok()
191 190 .and_then(|dir| makeover::load_theme(&[(dir, false)], &wanted).ok())
192 191 .and_then(|colours| makeover_tui::Theme::from_theme(&colours).ok());
193 192