Files
improvise/.github
Edward Langley d25f3187d3 feat(protocol): extract improvise-protocol crate
The crate the browser epic hangs off: Command (the wire format),
ViewState, RenderCache/CellDisplay/Snapshot, and reduce_view. It depends
on improvise-core and serde and nothing else -- no IO, no command layer,
no terminal -- and improvise-command now depends on it.

ViewState, ViewCursor, ViewFrame, AppMode, Panel, MinibufferConfig,
MinibufColor, HELP_PAGE_COUNT and the key types move here. Everything
that moved is re-exported from ui::app and command::key, so no existing
path changed. The three tickets before this one are what made the move
mechanical: h0b evicted the unportable fields, a2x added the derives,
8uz took the cursor out of the shared View.

Command's client->server half is not invented. It is exactly the set of
EffectKind::ViewOnly effects whose target is the portable slice -- h0b
had already sorted the portable state from the host-local, so the
enumeration was done. Effects touching the wizard, staged drill edits,
storage or the layout cache are absent by construction. The other half
carries projections: already-formatted display values and their labels.

One thing had to be added rather than moved. reduce_view runs on a client
that holds no Workbook, and ViewState::cursors is keyed by view name, so
ViewState needs its own active_view. That makes two copies of "which view
is active"; App::switch_to_view and App::install_workbook are the only
writers, and the_two_active_view_names_never_diverge guards it. The 8uz
characterization test caught the desync the moment it appeared, because
it was calling workbook.switch_view directly.

Whether the two are *allowed* to diverge -- two clients on different
views -- is improvise-g0f, deliberately left open. It changes the shape
of improvise-cqq, and nothing here forecloses either answer.

reduce_view has 12 tests including a determinism check: folding the same
stream twice gives the same state, which is what stops the server's
mirror drifting from the client it mirrors. Every Command round-trips
through JSON. The crate is in the CI wasm job.

Closes improvise-cqi

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V69PGQfMJuGRmtSWpfVAqn
2026-09-01 02:03:45 -07:00
..