Kitty Protocol Integration
Relevant source files
The following files were used as context for generating this wiki page:
The Kitty Protocol Integration in the guiltty project provides a mechanism for rendering pixel-level 2D graphics directly in compatible terminal emulators. By implementing the Kitty Graphics Protocol, the library bypasses the limitations of traditional character-cell TUI toolkits, allowing for smooth shapes, precise positioning, and real image display.
The integration is primarily housed in the guiltty-kitty crate, which serves as a specialized backend for the core rendering logic. It handles the encoding of raw pixel data into Application Program Command (APC) escape sequences, base64 encoding, and transmission over standard output or an injected writer.
Sources: README.md:3-15, crates/guiltty-kitty/src/lib.rs:1-10
Architecture and Data Flow
The integration follows a decoupled architecture where the core logic defines a Backend trait, and the Kitty-specific implementation fulfills this contract.
The diagram above illustrates the flow of pixel data from a generic Canvas through the Kitty-specific encoding process to the terminal.
Transmission Process
When KittyBackend::present is called, it performs the following steps:
- Pixel Extraction: Retrieves the raw RGBA8 byte buffer from the
Canvas. - Base64 Encoding: Encodes the entire buffer using standard base64 encoding.
- Chunking: Splits the encoded string into chunks no larger than 4096 bytes to comply with the protocol's per-APC limit.
- APC Wrapping: Wraps each chunk in escape sequences (
\x1b_G...;and\x1b\). - I/O Write: Writes the resulting bytes to the underlying writer (typically
stdout).
Sources: crates/guiltty-kitty/src/lib.rs:80-125, tasks/plan.md:37-45
Key Components
KittyBackend Struct
The KittyBackend is the central struct of the integration. It is generic over a writer W that implements std::io::Write, facilitating both real terminal output and unit testing via memory buffers.
| Field | Type | Description |
|---|---|---|
writer | W | The output target (defaulting to io::Stdout). |
image_id | u32 | A unique ID used to identify the image in the terminal's global namespace. |
Sources: crates/guiltty-kitty/src/lib.rs:32-35, crates/guiltty-kitty/src/lib.rs:49-55
Image and Placement Management
To ensure that repeated calls to present() update the same on-screen image rather than accumulating multiple images, KittyBackend manages unique IDs.
- Global Counter: A static
AtomicU32calledNEXT_IMAGE_IDensures that independent backend instances do not collide. - Id Reuse: An instance reuses its assigned
image_idandplacement_idacross every call. - Protocol Keys: The implementation uses specific protocol keys in the APC header:
a=T: Direct transmission and display.f=32: Specifies RGBA8 format.q=2: Suppresses terminal responses.C=1: Prevents cursor movement after display.
Sources: crates/guiltty-kitty/src/lib.rs:24-30, crates/guiltty-kitty/src/lib.rs:100-115
Protocol Implementation Details
Data Chunking Logic
The Kitty protocol mandates that data payloads be split if they exceed a certain length. guiltty-kitty strictly enforces a MAX_CHUNK_LEN of 4096 bytes.
The sequence above shows the iteration over data chunks and the conditional setting of the 'more' (m) flag.
Sources: crates/guiltty-kitty/src/lib.rs:21, crates/guiltty-kitty/src/lib.rs:84-123
Integration with Core Types
The integration relies on the guiltty-core definitions for canvas dimensions and pixel access.
- Width/Height: Retrieved from
canvas.width()andcanvas.height()for thesandvprotocol keys. - Error Handling: Backend errors (primarily I/O failures) are mapped to
guiltty_core::Error::Backend(String).
Sources: crates/guiltty-kitty/src/lib.rs:113-114, crates/guiltty-core/src/lib.rs:71-85
Requirements and Compatibility
| Requirement | Value | Source |
|---|---|---|
| Rust Edition | 2021 | crates/guiltty-kitty/Cargo.toml:5 |
| MSRV | 1.96.0 | crates/guiltty-kitty/Cargo.toml:6 |
| Protocol Version | 0.20.0+ | crates/guiltty-kitty/src/lib.rs:4-6 |
| Color Model | RGBA8 | crates/guiltty-core/src/lib.rs:7-14 |
The C=1 control key used to suppress cursor movement specifically requires Kitty protocol version 0.20.0 or later.
Sources: crates/guiltty-kitty/src/lib.rs:4-6, crates/guiltty-kitty/src/lib.rs:115
Summary
The Kitty Protocol Integration provides a high-performance, pure-Rust path for terminal graphics. By leveraging unique image IDs and standard base64 chunking, it enables guiltty to treat the terminal as a pixel-addressable canvas. The current implementation supports full-canvas updates with background preservation for sprites, while future iterations plan to add independent viewport regions and hardware-accelerated placement.
Sources: README.md:28-36, tasks/plan.md:46-55