feat(command): make ViewState serializable

ViewState is the wire payload of the Snapshot a newly-connected client
receives (improvise-q08), so it and its field types now derive Serialize
and Deserialize: AppMode, MinibufferConfig, MinibufColor, ViewFrame,
KeyCode, KeyModifiers. serde joins improvise-command's dependencies.

The ticket did not anticipate the actual blocker. MinibufferConfig held
`buffer_key: &'static str`, and Deserialize cannot produce a borrowed
'static value -- so every text-entry AppMode variant that carries a
MinibufferConfig failed, five "lifetime may not live long enough" errors
pointing at the variants and none naming the field.

buffer_key and TextEntry::buffer are now owned Strings. Cow<'static, str>
would keep construction allocation-free but puts container plumbing in a
public field. A BufferKey enum would close the name set, but drags the
buffers map key type, the script parser's buffer args and the
hand-written "search" buffer with it. Mode construction is per-keypress;
seven small allocations are not worth designing around.

Note this does not reopen improvise-k8h's rejection of a Buffer enum:
that was the drift argument -- each side would still name a variant --
which is about who writes the name, not what type it has. buffer_of()
still reads it off the mode. k8h doesn't forbid an enum here; scope does.

The roundtrip test populates one non-default value per field family,
including a payload-carrying mode and an armed prefix; a roundtrip of
ViewState::default() would pass while proving nothing.

Closes improvise-a2x

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V69PGQfMJuGRmtSWpfVAqn
This commit is contained in:
Edward Langley
2026-08-31 21:05:37 -07:00
parent c219bfed6a
commit 850ea584d1
8 changed files with 91 additions and 32 deletions
Generated
+1
View File
@@ -795,6 +795,7 @@ dependencies = [
"improvise-core",
"improvise-formula",
"improvise-io",
"serde",
"serde_json",
"tempfile",
"unicode-width",