fuzzball
Encoder and decoder for the Fuzzball terminal protocol, the DCS Fz extension
family first implemented in the Mouser terminal:
ESC P = F z <subsystem> <verb> ; <params> [: <payload>] ESC \
- Keyboard (
k): one opt-in mode of structured key events (physical key, logical key, modifiers, locks, text, IME). - Graphics (
g): image upload (chunked base64), cell-anchored placements, delete, query. - Shell actions (
s): silentcdfor shell integrations. - Plugins (
p) and the common capability query (c).
No dependencies, no I/O, no terminal library: bring your own reader and writer.
[]
= "1"
Key events
use ;
use ;
// Turn the mode on (write this to the terminal).
let enable: & = ENABLE; // ESC P = F z k s ; on=1,v=0 ESC \
// Feed input as it arrives; partial messages are held until complete.
let mut d = new;
d.push;
while let Some = d.next
keyboard::parse_event(buf, max) parses one event at the start of a buffer and reports
Incomplete, Invalid { len } or NotFuzzball, for parsers that manage their own
buffer (such as crossterm's).
Detection
Send common::detect_query(1) (capability query followed by DA1). A Fuzzball terminal
answers c r before the DA1 reply; read it with common::Capabilities::from_message and
check keyboard() or has_subsystem('g').
Specification
The protocol is specified in docs/: README (framing,
negotiation, errors), keyboard, graphics,
shell, plugins. docs/wire-format.md
records exactly what implementations emit today, where it is more specific than the
v0.1 drafts.
Stability
1.x keeps the wire format and API compatible. Golden-byte tests in tests/golden.rs
lock every message this crate writes. MSRV: Rust 1.85.
License
BSD-3-Clause, Copyright (c) 2026 Weird Brains.