Follow felis to 105b0899 #2
Loading…
Reference in a new issue
No description provided.
Delete branch "follow-felis-105b0899"
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?
Moves the four pinned felis crates from
32775067(2026-07-16) to105b089979369fd310757375af3df7900ae7e523, across the wire-baseline reset, and adapts therelay to what that wire is now.
What felis changed, and what it forced here
Hellostates aConnectionModeplus onepull_pacedbool; additions ride the protocol minor (now 10).CLIENT_CAPS/cap_namesare replaced bystream_offer() -> Offer::window(false). The attach header reportsminor(the connection's effectivemin(gateway, daemon)) where it reportedcaps.connect_carrier(Carrier::Local | Carrier::Ssh, offer, RemoteSpawn)returns oneCarrierConnection.DaemonConntwo-arm split is gone;dial()builds a felisCarrierand hands back one type. Remote dials passRemoteSpawn::Allow— a browser opening a cold host expects its daemon to come up.SpawnArgs.dimsis optional and a presentdimsnamingrows: 0is refused withGEOMETRY_OUT_OF_RANGE.dimsonly when both axes are non-zero; the broker'srows/colsfields read a0as absence (dim_field).Session::Attached/Createdcarry the wholeSessionInfo, notid+dims.Session::Attachgainedlive_only;AttachFailed's reason is typed.conn.attach(id, AttachIntent::Deliberate)andcreate_withreturn the roster row. Deliberate on purpose: the operator or the browser named this session, so a shell that already exited still hands back its final screen.SessionInfogainedexited,last_exit_code,attachments,sequence, andidle_secondsis now absent while a session is attached.listrows carryexitedandlast_exit_codeso a tab picker can tell a finished shell from a working one.ImageMsg::Header { id, target: New{…} | Frame{number} }, nototal_bytes, no chunkoffset, frames 1-based.Imageframes verbatim — but the JSON the browser decodes changed shape (below).driver.open_stream()), moves the driver toObserving, and writes the subscribe withCorrelation::stream(id); events are read back throughdriver.classify/decode.broker.rsanddocs/broker.mdsaid the daemon closes it, which is now false.The observer is the one behavior fix rather than a rename. The old spelling
(
writer.send(&NotifyMsg::Subscribe { … })) still compiles against the new crates and thedaemon answers it by ending the connection — badges would have died silently on every host
under the redial loop. Reported upstream as natsukium/felis#196.
Broker-contract facts for felis-web-component
The JSON is still the domain-serde view (
felis-grid'stranscode::body_to_json), notpbjson, and the row payload's
{"Rle": {graphemes, attr_runs, sized_cells, soft_wrap_continued}}view is byte-compatible. What moved:attach/createok):{"rows","cols","minor"}—capsis gone,minorismin(gateway, daemon)and isper-stream.
GridMsg:GridSize→Size;RowDelta{row,packed_cells}andRowDeltaBatch{rows}collapse into one
RowDelta{rows:[[u16,row]…]};RehydrateBegin{dims}→ the unit variant"RehydrateBegin";Bell/Notify→Attention{source:"Bell"|"Notification"};ClipboardSet{selection,data}→ClipboardSet{write:{selection,data}};ModeFlagsgains
reverse_videoand itsmouse_protocol/modify_other_keysare now strings(
"Off"|"ButtonEvents"|"ButtonAndDrag"|"AnyMotion","Off"|"Level1"|"Level2");KittyKbdFlags.flagsis a typed flag set; newPaletteColor{index,action}andPaletteResetAll.SearchMatch,SearchDone,ScrollbackRow,ScrollbackDoneandCaptureRegionare gone from the family.ImageMsg:Header{id,target:{"New":{width,height,format}}|{"Frame":{number}}};Chunk{id,bytes}(nooffset);ShowFrame{id,number}(1-based, wasindex); theFrameHeader/FrameChunk/FrameCompletetrio is gone.SessionMsg(the browser's"Control"bucket):Attached{info}/Created{info}where it was
{id,dims};AttachFailed{reason,detail}with a typed reason.ConnMsg(also"Control"):Welcome{build_id,identity?};Hello{mode,pull_paced};new
Refused/Cancel/End/Error;Ping/Ponggone.InputMsg(browser → gateway):Resize{dims:{rows,cols,pixel_w,pixel_h}}where it wasfour loose fields;
NextGridFrameis payload-free;Search,SearchCancel,CaptureScrollbackandCaptureRegionno longer exist.listrows:{host,session,rows,cols,title,cwd,idle_seconds,tags,last_notification, foreground,exited,last_exit_code}—idle_secondsisnullwhile attached,exitedmarks the post-exit grace.
{"ev":"notify"}is unchanged, fields and all.Verified
All under
nix develop, on this host:cargo fmt --all --check,cargo clippy --all-targets -- -D warnings,cargo test(26 passed),
cargo deny check(advisories/bans/licenses/sources ok),nix build .#gateway.felis-daemonbuilt from105b0899on a scratch socket,driven by a hand-rolled WebSocket client:
101, first message{"rows":24,"cols":80,"minor":10},Gridframesfollowing;
felis-broker.v1echoed,hosts,create({"sid":1,"host":"local", "session":"8ffb…","rows":30,"cols":100,"minor":10}), keystrokes reaching the PTY andproducing frames,
listacross the roster showingidle_seconds: nullfor the attachedsession and
6for the detached one,tag→{"tags":["probe"]},destroy→{"existed":true};OSC 9in a session arriving as{"ev":"notify","host":"local","session":"ef77…","notification":{"body": "probe-notification","urgency":"normal"},…}. Against the pre-fix binary the same rungets
Driver(Correlation { kind: Notify, expected: "a stream_id allocating the next unopened stream", found: "no correlation envelope on Notify::Subscribe" })in the daemonlog and no events at all.
afterwards.
Left open
Inputfamilyfor correlated families whose ids come from the driver the relay drops when it splits a
connection into a reader task and a writer task. Filed as #1 with the three candidate
shapes; the docs now record it as out of scope rather than implied.
NotifyMsg::Lagged(the daemon dropped events an observer was too slow to read) is readand discarded rather than surfaced — surfacing it would add an event to the browser
contract, which belongs with whoever consumes it.
felis reset its wire baseline, so the four pinned crates no longer offer the API this relay was written against: the capability bitmap and the encoding negotiation are gone (a connection now states a mode plus one pacing flag, and additions ride the protocol minor), the carrier is erased at connect time, an attach answers with the session's whole roster row, a create states its geometry by presence, and every correlated frame carries a stream or request id. The browser-visible consequences, since felis-web-component decodes what this forwards: the attach header reports `minor` where it reported `caps`; a roster row gains `exited` / `last_exit_code` and leaves `idle_seconds` out while a session is attached; `GridMsg` renames `GridSize` to `Size`, folds `RowDelta` and `RowDeltaBatch` into one `RowDelta { rows }`, replaces `Bell` / `Notify` with `Attention` and nests `ClipboardSet` under a `write`; and the search and capture verbs have left the `Input` family entirely. The notify observer is the one behavior change rather than a rename: a subscribe opens a stream now, and one carrying no correlation envelope is what the daemon ends the connection over — badges would have died silently on every host, under a redial loop that never reported why.