GridMsg::ClipboardSet is read flat, but felis wraps it in a write field — every OSC 52 arrives empty #5
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found by cross-checking the
felis-broker.v1JSON contract betweenfelis-web-gateway
follow-felis-105b0899(577138be) and this repo'sfollow-felis-105b0899(edfb8dfa). Both pin felis105b089979369fd310757375af3df7900ae7e523.The mismatch
felis's wire reset moved
GridMsg::ClipboardSet's two fields into aClipboardWritestruct behind awritefield.crates/felis-protocol/src/messages/grid.rs:GridMsgis externally tagged with no serde attributes andClipboardSelectionkeeps its hand-writtenSerializethat emits the rawu8bits, so the JSON is:The gateway relays that verbatim —
src/main.rs'sdecode_framecallsfelis_grid::transcode::body_to_json, which isserde_json::to_valueon thedecoded
GridMsgfor every family but theRowDeltarow recode.This component still reads the pre-reset flat body —
web/felis-terminal.ts:2034, inrouteGrid:bodyOf(msg, "ClipboardSet")now returns{write: {...}}, sob["selection"]andb["data"]are bothundefined.Why it breaks a live session
Every OSC 52 write on a live session reaches the page as an empty one:
selectionfalls back to0, soclipboardandprimaryare bothfalse,and
datafalls back to[], sotextis"".Terminal.onClipboardsubscribers fire with{text: "", clipboard: false, primary: false}— a lie rather than a no-op.web/mobile.html:287is ashipped consumer.
clipboardMode === "write"path is gated onwrite.clipboard, which isnow permanently false, so
navigator.clipboard.writeTextis never called.An opted-in embed silently stops receiving OSC 52 writes.
Nothing surfaces:
routeGridhas no failure path, and the shadow screen's owntyped
applyhandles the frame correctly, so the grid keeps painting.Fix
Unwrap
writebefore reading the fields, e.g.Nothing changes on the gateway: it forwards the felis-typed value and
docs/broker.mdnames the current shape.Not covered by a test
routeGrid's reply/event arms are TypeScript with no fixture behind them;tests/apply.rsexercisesShadowScreen::apply, which decodesClipboardSetthrough the typed enum and therefore cannot see this.