- client.go: track last output oldNum, replace instead of append when same base
- transport.go: reject diffs that do not chain from latest acknowledged state
(oldNum != ackNum), preventing stale ANSI sequences from corrupting output
- Transport: expose LastRecvOldNum/LastRecvNewNum for state tracking
- WASM: stateTracker with shadow VT emulator and received states map
- Each diff applied to base state copy, stored by newNum
- Display diffing: only changed cells sent to terminal
- Eliminates garbled output from missed diffs and state transitions
- Build with -tags osusergo for WASM os/user compatibility
- Replace charmbracelet/x/vt with unixshells/vt-go (IRM support)
- Remove ultraviolet import from framebuffer.go (use local attr constants)
- Framebuffer compiles for all platforms including js/wasm
- WASM build requires -tags osusergo for os/user compatibility
The Dart mosh client only calls sendNew() when hasPendingState is false.
The Go client was calling SetPending on every tick with dirty=true, which
reset diffSent and caused new sequence numbers for the same cumulative
payload. Now tick() checks AckedByRemote >= SentNum before calling
SetPending — at most one unacked state in flight, matching the Dart
client's behavior.
Add AckedByRemote/SentNum accessors, diffOldNum locking, and
received state list for proper old_num validation. Required for
server framebuffer diffing to track which state the client has.
Replace raw PTY passthrough with proper VT emulator processing.
PTY output feeds into charmbracelet/x/vt, snapshots are diffed
against the last-acked framebuffer using CUP-based positioning.
Fixes character doubling during fast typing.
Wire-compatible with C mosh. AES-128-OCB3, SSP transport, fragmentation,
protobuf state sync, latch extension fields.
Includes ServeRW bridge mode for embedding.