Skip to content

feat: wasm Session, palette, and 4-3-4-3-5 --bands - #29

Open
csfh wants to merge 24 commits into
omacom:masterfrom
csfh:feature/wasm-palette
Open

csfh wants to merge 24 commits into
omacom:masterfrom
csfh:feature/wasm-palette

Conversation

@csfh

@csfh csfh commented Sep 8, 2026

Copy link
Copy Markdown
Member

Summary

Adds a wasm Session, hex --palette, and --bands so WTE, omarchy.org, and the Omarchy screensaver can share one engine.

  • Wasm Session: packed frames into caller-owned buffers, optional palette string, terminal background, ninth bands argument
  • CLI --palette HEX[,HEX...] replaces each effect's default colors
  • CLI --bands colors the input word in five field stripes: crest, hover, lit, mid, dim at 4, 3, 4, 3, 5 (19 units, one per wordmark bitmap row). Layout uses dense body rows so a FIGlet peak does not steal the crest. Requires --palette. Sets existing-color handling to always so every effect settles on those stripes
  • 19-line input stays 4-3-4-3-5; other heights use a Hamilton split of that ratio (10 lines become 2-2-2-1-3)
  • Per-effect cargo features (--no-default-features --features decrypt) and wasm-only skips so a browser build stays small

v0.3.2 has none of --palette / --bands.

Test plan

  • cargo test --lib bands
  • ttfx --help shows --palette and --bands
  • ttfx -i logo.txt --palette '#daecc6,#bbdd97,#9ece6a,#678549,#39482e' --terminal-background-color '#0e0e14' --bands decrypt

csfh added 21 commits August 26, 2026 11:11
Browser frontends pack each frame as parallel cell arrays. wasm32
stubs the tty signal helpers and fills TerminalConfig.terminal_size
instead of probing a console.
Pack symbols as Unicode scalars and copy the packed frame into
caller-owned slices. Session.fill writes into JS typed arrays instead
of allocating a new String and Vec on every getter.
Browser frames read packed cells. ctx.frame() still advances the clock
but returns an empty string so get_formatted_output_string does not
allocate ANSI or paint cells a second time before pack_display_frame.
Default remains all 37. A single-effect binary or wasm is
`--no-default-features --features decrypt`, or `./bin/build --effect decrypt`.
The CLI, completions, and wasm catalog only list what was compiled in.
Wasm Session and effect_catalog now build default configs through
build_named_effect instead of parsing CLI args. A single-effect wasm
drops clap, which was most of that binary.

ColorArg parsing moved next to Color so those defaults share it with
the CLI. Default impls are checked against clap's subcommand defaults.
Debug-printing EventAction pulled flt2dec into every wasm via
CallbackValue::Float. Path speed errors now use a static message too.
Browser frames read packed cells. Skip SGR assembly, cursor sequences,
and the tty run loop so those writers stay out of the wasm.
Wasm Session never sets xterm_colors and packed frames emit 24-bit
RGB, so hex_to_xterm and its palette scan stay native-only.
Color::from_xterm now uses the 6³ cube formula instead of a 256-entry
hex string table, so that table stays out of the wasm.
Packed frames already store 24-bit RGB on Color, so wasm Session
stops building SGR ColorCode strings just to parse them back.
Gradient and brightness shifts skip format!/from_hex and write the
hex string from the RGB bytes already on Color.
Display no longer Debug-prints the offending sequence, so Session
error paths do not pull that formatter. CLI still prints {seq:?}.
Packed frames read Color RGB, so wasm no longer rebuilds the input's
SGR text while preprocessing.
Unseeded Session fills eight bytes from crypto.getRandomValues instead
of linking getrandom's unused-target error paths.
`--palette HEX[,HEX...]` replaces each effect's default colors with the
given list. Repeat the flag or split on commas and whitespace. Color
flags passed on the effect keep their values.

The wasm Session constructor takes the same list as an optional string
so a host can pass theme hex colors without a file.
Light themes need a white paper behind the glyphs. Session takes an
optional background hex so fades and empty cells match that paper
instead of always using black.
`--bands` and the wasm Session ninth argument paint input characters
from a five-color palette: crest, hover, lit, mid, dim. Units follow
the wordmark spec drawing, so t=0 is the top of the word and t=1 is
the bottom, independent of how many bitmap rows the glyph has.
Screensaver and WTE logos encode the 19-row wordmark as ▄▀█, so a full
block is two spec pixels. Coloring by terminal row made the M peak steal
the crest and turned the 1-unit hover into a whole character cell.
Measuring t in half-pixels let the 1-unit hover fall between two █
centers, so the screensaver showed three fat stripes. Lay 3-1-3-2-4
out on whole rows with largest remainder so all five stay visible.
The FIGlet peak is a sparse extra row. Counting it in the span left
O/A/R with a one-row crest. Map the field across dense rows; the peak
stays crest and the Y tail stays dim.
The crest is four units, then one hover, four lit, three mid, five dim.
The field is 17 units tall.
Crest, hover, lit, mid, dim. Nineteen units, one per wordmark row.
@csfh csfh changed the title feat: wasm Session, palette, and 4-1-4-3-5 --bands feat: wasm Session, palette, and 4-3-4-3-5 --bands Sep 8, 2026
Crest, hover, lit, mid, dim. Spread that ratio across however many
lines the input has (19 lines stay 5-2-4-3-5). Every ink row counts.
@csfh csfh changed the title feat: wasm Session, palette, and 4-3-4-3-5 --bands feat: wasm Session, palette, and 5-2-4-3-5 --bands Sep 8, 2026
Crest, hover, lit, mid, dim. Spread that ratio across however many
lines the input has (19 lines stay 4-3-4-3-5). Every ink row counts.
@csfh csfh changed the title feat: wasm Session, palette, and 5-2-4-3-5 --bands feat: wasm Session, palette, and 4-3-4-3-5 --bands Sep 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant