850ea584d1
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