Skip to Content
Krad ADE
Architecture

Terminal pipeline

How a terminal pairs a PTY with libghostty-vt, pumps output through a bounded channel and paints only what is on screen.

A terminal is a PTY paired with an emulator. A dedicated thread pumps its output through a bounded channel, the emulator turns bytes into snapshots and the UI paints only what is on screen.

The path of a byte

From the shell to the screen
shell process
  └── krad-pty: Unix PTY, ConPTY or wsl.exe over ConPTY
        └── a dedicated thread pumps the output
              └── bounded channel, 256 messages
                    └── krad-term: libghostty-vt parses the bytes
                          └── snapshot of the visible cells
                                └── krad-ui: paints the visible rows

Input flows the other way: krad-term encodes keys and mouse events with Ghostty's encoding, including the kitty keyboard protocol, and the session writes the bytes to the PTY.

Crates

CrateRole
krad-ptySpawns processes and does PTY I/O over portable-pty, with platform shells in unix.rs, windows.rs and wsl.rs
krad-termEmulation over libghostty-vt: bytes in, renderable snapshots out, key and mouse input encoded
krad-sessionOwns one PTY and one terminal, with their threads, and emits session events to the UI

krad-term does not depend on krad-pty, so it is tested by feeding raw bytes. krad-session re-exports what the UI needs, so krad-ui never depends on either directly.

libghostty-vt

The emulator is libghostty-vt, the terminal core of Ghostty packaged as a library. The app uses it through the libghostty-vt crate from libghostty-rs, fixed to one git commit. With it come images over the kitty graphics protocol, the kitty keyboard protocol, and Ghostty's own encoding of keys and mouse events.

libghostty-vt is written in Zig. It is built once per platform when the app moves to a new Ghostty commit, and the static libraries are published as release assets. The build links them through pkg-config, so nobody needs Zig to build the app. The crate comes from a fork, joordih/libghostty-rs, which pins Ghostty 1.4.0; its changes go upstream as pull requests.

The terminal is not Send; the engine lives on the UI thread.

Windows

On Windows, both local and WSL shells run over ConPTY, and a WSL shell is started through wsl.exe with its working directory and environment converted for the distro. The copy of ConPTY built into Windows redraws the screen itself and discards escape sequences it does not recognise, which breaks kitty graphics. The installer therefore places conpty.dll and OpenConsole.exe, version 1.25 or newer of Microsoft's ConPTY package, beside krad-ade.exe, and portable-pty uses those files instead of the system ones. All Windows terminals use this bundled copy.

Panes and cost

A session shows up to four panes at once, and every pane's terminal is sized for its own area. Each visible terminal has its own pumping and painting cost. Panes stop at four because terminals soon become too small to read.

Restore

No process outlives the app. The layout keeps each terminal's working directory, initial command and bounded scrollback; on reopen, inert shells are relaunched there with their scrollback, and agents resume by their resume id. The app never reattaches to live processes.

Agents in terminals

Every terminal the app opens gets the agents bus address, a token and its own handle as environment variables, with the app's folder first on PATH. An agent in any terminal can run krad-ade-agents from its shell.

On this page