Files
improvise/.github/workflows
Edward Langley 30c4bb6629 feat(wasm-client): the browser-side fold and key classifier (improvise-gsw)
A new crate `improvise-wasm-client`: a `ViewState` plus one widget cache
each, moved by folding the same `Command` stream the host folds, with a
wasm-bindgen surface over JSON.

The ticket's premise does not survive contact with the architecture
(`doctrine(check_the_ticket_premise)`). It asks `on_key_event` to
"resolve via the keymap and dispatch through reduce_view", but a binding
names an *intent* resolved against a `CmdContext` — a `Model`, a
`GridLayout`, an `App` — while a `Command` is the *resolved mutation*
(gotcha 38, improvise-gxi). A thin client holds none of that, so keys
travel upstream unresolved and `improvise-command` is a dev-dependency
rather than a dependency: the keymap could not be used here even if the
bundle could afford `App`, `Workbook`, persistence and the wizard.

The one exception is minibuffer text entry, whose target buffer is
`AppMode::minibuffer().buffer_key` — the same field the host's
`TextEntry` builder reads (gotcha 11), so the local rule is derived from
the same fact rather than copied. `tests/lockstep.rs` drives the
authoritative host and the client over the same keypress in all seven
text-entry modes and asserts the two `ViewState`s agree.

Rejected for local resolution, with reasons in `keys.rs`: cursor
movement (`GridCache` is viewport-indexed, so a client cannot clamp),
panel cursors (the flattening depends on `expanded_cats`), anything
modified (`AnyChar` matches under any modifier on the host), and
CommandMode's Backspace (the one `TextEntry::rebind`, which leaves the
mode).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EoW5BB87ZZdm96SvBTWawH
2026-09-19 16:35:04 -07:00
..
2026-04-11 00:06:47 -07:00
2026-04-11 00:15:42 -07:00