Skip to content

Overview

Honeymux uses a hybrid two-client architecture — a control-mode client for metadata and a PTY client for terminal I/O — layered through a Ghostty-based VT emulator and rendered with OpenTUI.

Core I/O and tmux Communication

Coding Agent Flows

Remote Server Flows

Honeymux maintains two separate connections to the tmux server:

  • Control Client (tmux -C) — a line-based protocol connection used exclusively for metadata. It queries and mutates sessions, windows, and panes, and receives %-prefixed notifications (%window-add, %layout-change, %session-changed, etc.) that drive React state updates. Its dimensions are set to an oversized 300×300 so it never constrains the session layout.

  • PTY Client (tmux attach-session) — a normal terminal-mode attachment that carries the full I/O stream for the active pane. User keystrokes flow in; raw VT output flows out through the passthrough forwarder and into the Ghostty VT emulator.

The PTY layer sits between tmux and the Ghostty renderer. It spawns a pseudo-terminal via Bun.spawn in terminal mode and handles two concerns:

  • Passthrough forwarding — OSC sequences for window titles (0, 1, 2), notifications (9, 777), clipboard (52), and Kitty graphics (99) are intercepted and forwarded directly to the outer terminal instead of being consumed by the VT parser. BEL terminators are converted to ST to avoid audible bells.

  • Environment isolation — shell-integration and terminal-specific variables (TERM_PROGRAM, ITERM_SESSION_ID, TMUX, etc.) are stripped so programs inside tmux see a clean xterm-256color environment. OPENTUI_FORCE_UNICODE=1 is injected so any OpenTUI program running in a pane uses grapheme-cluster width measurement; without this, OpenTUI’s auto-detection downgrades to wcwidth under tmux, breaking ZWJ sequences, regional-indicator flag pairs, and VS16 emoji widths.

The Ghostty VT emulator (libghostty-vt) parses the filtered output stream into a persistent terminal buffer. Honeymux enables DEC mode 2027 on this buffer at construction so it treats grapheme clusters as single wide cells, matching tmux’s internal pane representation — without this alignment, tmux’s incremental cursor-positioned writes (which assume cluster-as-one-cell) drift relative to ghostty-vt’s wider expanded layout. Rather than serializing the full scrollback on every render, ghostty-opentui patches getJson() to return only the visible screen region — sized to match the current pane dimensions. This JSON representation is then rendered by OpenTUI as a terminal view component alongside the rest of the React UI chrome, and the final ANSI output is written to the outer terminal’s stdout.

Screen captures powered by Honeyshots

Copyright © 2026 Aaron Campbell · Apache 2.0