M4.6 follow-up piece 2. `Style` gains `underline_color: Color`
(Default = follow the text color) so a diagnostic squiggle can be
red/yellow/cyan/gray without clobbering the syntax color of the
text it underlines — exactly why error_style() left its 'red'
unwired until now.
The wire consequence: Style rides inside Cell / CellDelta /
Snapshot / StyleSpans, so this is the protocol's first
encoding-breaking change. PROTOCOL_VERSION 5 → 6 and
SUPPORTED_PROTOCOL_VERSIONS narrows to [6]: postcard is not
self-describing, so no per-session send gate can keep a v5 peer
decoding v6 cells — a mismatched pair now fails the handshake with
a clean VersionMismatch instead of garbling mid-session. Version
policy tests rewritten to pin the new contract.
Surface wiring:
- diag.rs: per-severity underline_color (indexed 1/3/6/8).
- frontend.rs: kitty-style CSI 4:N for Double/Curly/Dotted/Dashed
(previously flattened to plain SGR 4) + SGR 58:5/58:2 emission.
- ansi.rs: parse SGR 58/59 with the 38/48 extended-color grammar.
- overlay.rs merge_styles: non-default-wins, like fg/bg/underline.
- lua_bindings.rs: underline_color on Lua style tables.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Moves Cell, Glyph, Style, Color, UnderlineStyle, CellCoord, CellSize,
DiffSpan, Attachment to pmacs-protocol::cell. CellGrid (borrowed-slice
render surface) and fn diff() (rendering helper) stay in src/cell.rs
since they're instance-side rendering machinery, not wire shapes.
src/cell.rs gains 'pub use pmacs_protocol::{Cell, Glyph, Style, ...};'
at the top so every existing internal import (crate::cell::Cell, etc.)
keeps resolving. The cell-module tests live alongside CellGrid + diff
and reference the re-exported types via 'use super::*' — same as
before; no test changes needed.
Lib gate: still green (no regressions, 1314 passing).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>