Prior Art & Design Rationale
Research on modern terminals revealed why a new approach was needed.Research Scope
Copy
┌────────────────────────────────────────────────────────────────────────┐
│ TERMINALS STUDIED │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┬────────────┬───────────────────────────────────┐ │
│ │ Terminal │ Language │ Focus Area │ │
│ ├─────────────┼────────────┼───────────────────────────────────┤ │
│ │ Alacritty │ Rust │ VTE parsing, GPU rendering │ │
│ │ Ghostty │ Zig │ Performance, sync mechanisms │ │
│ │ Hyper │ TS/Electron│ IPC boundaries, batching │ │
│ │ WezTerm │ Rust │ Multiplexing, configuration │ │
│ │ xterm.js │ TypeScript│ Browser rendering, buffer mgmt │ │
│ └─────────────┴────────────┴───────────────────────────────────┘ │
│ │
└────────────────────────────────────────────────────────────────────────┘
What We Learned
Ghostty (Zig)
Copy
┌────────────────────────────────────────────────────────────────────────┐
│ GHOSTTY: PERFORMANCE BOUNDARIES │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ Key Insights: │
│ ───────────── │
│ - BSU/ESU Mode 2026 with 1-second timeout safety │
│ - Page-based mmap architecture for zero-copy operations │
│ - Triple buffering (SwapChain) for GPU sync │
│ │
│ What we learned: │
│ ──────────────── │
│ --> Timeout safety is essential (apps can hang) │
│ --> Memory architecture matters for performance │
│ --> Type safety at compile time prevents bugs │
│ │
└────────────────────────────────────────────────────────────────────────┘
Hyper (Electron/TypeScript)
Copy
┌────────────────────────────────────────────────────────────────────────┐
│ HYPER: ARCHITECTURE LESSONS │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ Key Insights: │
│ ───────────── │
│ - NO native BSU/ESU - delegates entirely to xterm.js │
│ - DataBatcher: 16ms timeout / 200KB max batch │
│ - Electron IPC overhead is significant │
│ - React bypassed for terminal writes (performance) │
│ │
│ What we learned: │
│ ──────────────── │
│ --> 16ms batching aligns with 60 FPS │
│ --> Delegating to xterm.js means inheriting its limitations │
│ --> IPC boundary is where optimization matters │
│ │
└────────────────────────────────────────────────────────────────────────┘
BSU/ESU Support Matrix
Copy
┌────────────────────────────────────────────────────────────────────────┐
│ BSU/ESU MODE 2026 SUPPORT │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ MODERN TERMINALS SUPPORT BSU/ESU │
│ ════════════════════════════════ │
│ │
│ ┌─────────────┬───────────┬─────────────────────────────────────┐ │
│ │ Terminal │ Support │ Notes │ │
│ ├─────────────┼───────────┼─────────────────────────────────────┤ │
│ │ Alacritty │ YES │ Lock-based event loop │ │
│ │ Ghostty │ YES │ 1s timeout safety │ │
│ │ WezTerm │ YES │ Sequence number tracking │ │
│ │ xterm.js │ YES │ SynchronizedOutputHandler class │ │
│ │ Hyper │ VIA │ Delegates to xterm.js │ │
│ └─────────────┴───────────┴─────────────────────────────────────┘ │
│ │
└────────────────────────────────────────────────────────────────────────┘
The Unsolved Problem
Copy
┌────────────────────────────────────────────────────────────────────────┐
│ WHY AI CLI STILL FLICKERS │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ OBSERVATION │
│ ═══════════ │
│ │
│ - All modern terminals support BSU/ESU Mode 2026 │
│ - AI CLIs (Claude Code, Aider, etc.) still flicker │
│ - Even in native GPU-accelerated terminals │
│ │
│ ─────────────────────────────────────────────────────────────── │
│ │
│ ROOT CAUSE ANALYSIS │
│ ═══════════════════ │
│ │
│ 1. BSU/ESU requires APPLICATION to emit sequences │
│ │
│ Application must send: begin-sync ... end-sync │
│ Most AI CLIs do NOT send these sequences │
│ │
│ 2. AI CLIs use different patterns │
│ │
│ Common pattern: cursor hide --> update --> cursor show │
│ This is NOT BSU/ESU, but achieves similar intent │
│ │
│ 3. Producer-driven architecture │
│ │
│ PTY --> Parser --> Renderer --> Display │
│ │ │ │
│ └── Producer └── No feedback (open loop) │
│ │
│ ─────────────────────────────────────────────────────────────── │
│ │
│ THE GAP │
│ ═══════ │
│ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Terminal has BSU/ESU support YES │ │
│ │ AI CLI sends BSU/ESU sequences NO │ │
│ │ AI CLI sends cursor hide/show pattern YES │ │
│ │ Terminal recognizes this as frame boundary NO <── GAP │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │
└────────────────────────────────────────────────────────────────────────┘
MonoTerm’s Approach
Pseudo-BSU/ESU: Recognizing Cursor Patterns
Copy
┌────────────────────────────────────────────────────────────────────────┐
│ PSEUDO-BSU/ESU: THE BRIDGE │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ Traditional BSU/ESU (Mode 2026): │
│ ──────────────────────────────── │
│ │
│ begin-sync --> [content] --> end-sync │
│ (begin) (buffered) (end + flush) │
│ │
│ ─────────────────────────────────────────────────────────────── │
│ │
│ Pseudo-BSU/ESU (MonoTerm): │
│ ────────────────────────── │
│ │
│ cursor-hide --> [content] --> cursor-show │
│ (hide cursor) (buffered) (show cursor + flush) │
│ │
│ ─────────────────────────────────────────────────────────────── │
│ │
│ Why this works: │
│ ─────────────── │
│ │
│ - AI CLIs already send cursor hide/show │
│ - Intent is identical: "don't show partial updates" │
│ - MonoTerm recognizes this pattern as frame boundary │
│ - No changes needed in AI CLI applications │
│ │
└────────────────────────────────────────────────────────────────────────┘
Consumer-Driven ACK: Closing the Loop
Copy
┌────────────────────────────────────────────────────────────────────────┐
│ ACK HANDSHAKE: FROM OPEN TO CLOSED LOOP │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ Traditional (Open Loop): │
│ ───────────────────────── │
│ │
│ PTY --> Parser --> Renderer --> Display │
│ │ │ │
│ │ └── No feedback │
│ └── "I'll send as fast as I can" │
│ │
│ ─────────────────────────────────────────────────────────────── │
│ │
│ MonoTerm (Closed Loop): │
│ ─────────────────────── │
│ │
│ PTY --> Parser --> [ACK Gate] --> Renderer --> Display │
│ │ ^ │ │
│ │ │ │ │
│ │ └────── ACK ────┘ │
│ │ │
│ └── "I'll wait for consumer readiness" │
│ │
│ Why this matters: │
│ ───────────────── │
│ │
│ - Producer can't overwhelm consumer │
│ - Frame sync happens at IPC boundary │
│ │
└────────────────────────────────────────────────────────────────────────┘
Why Prior Art Wasn’t Enough
Copy
┌────────────────────────────────────────────────────────────────────────┐
│ DESIGN RATIONALE │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ PRIOR ART │ WHY NOT SUFFICIENT │
│ ══════════ │ ══════════════════ │
│ │ │
│ BSU/ESU Mode 2026 │ Requires app to emit sequences │
│ (Modern terminals) │ AI CLIs don't emit them │
│ │ │
│ ────────────────────────────────────────────────────────────────── │
│ │ │
│ Ghostty timeout safety │ Great pattern, adopted it │
│ │ But still producer-driven │
│ │ │
│ ────────────────────────────────────────────────────────────────── │
│ │ │
│ Hyper 16ms batching │ Good for 60 FPS alignment │
│ │ But no frame boundary detection │
│ │ │
│ ════════════════════════════════════════════════════════════════ │
│ │
│ MONOTERM'S CONTRIBUTION │
│ ═══════════════════════ │
│ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ 1. Pseudo-BSU/ESU │ │
│ │ --> Recognize cursor hide/show AS frame boundary │ │
│ │ --> Works with existing AI CLIs (no changes needed) │ │
│ │ │ │
│ │ 2. Consumer-driven ACK │ │
│ │ --> Close the loop at IPC boundary │ │
│ │ --> Renderer controls the pace │ │
│ │ │ │
│ │ 3. AtomicState at IPC boundary │ │
│ │ --> Frame sync between Rust backend and TS frontend │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │
└────────────────────────────────────────────────────────────────────────┘
Acknowledgments
Copy
┌────────────────────────────────────────────────────────────────────────┐
│ THANKS TO THE TERMINAL ECOSYSTEM │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ Ghostty (Mitchell Hashimoto) │
│ --> Pushed performance boundaries with Zig │
│ --> Timeout safety pattern we adopted │
│ │
│ Hyper (Vercel) │
│ --> Demonstrated Electron terminal architecture │
│ --> 16ms batching for 60 FPS alignment │
│ --> Lessons on IPC boundary importance │
│ │
│ Collective wisdom from the open source terminal community │
│ │
└────────────────────────────────────────────────────────────────────────┘
Conclusion
Copy
┌────────────────────────────────────────────────────────────────────────┐
│ PRIOR ART --> RECOGNITION │
├────────────────────────────────────────────────────────────────────────┤
│ │
│ We studied modern terminals. We learned from all of them. │
│ │
│ What we found: │
│ - BSU/ESU Mode 2026 is widely supported │
│ - AI CLI flickering persists despite this support │
│ - The gap: app must emit sequences, but AI CLIs don't │
│ │
│ What we recognized: │
│ - AI CLIs already send cursor hide/show │
│ - This pattern has the SAME INTENT as BSU/ESU │
│ - No one was treating it as a frame boundary │
│ │
│ What we implemented: │
│ - Pseudo-BSU/ESU: cursor pattern as frame boundary │
│ - Consumer-driven ACK: closed loop architecture │
│ - AtomicState: frame sync at IPC boundary │
│ │
│ ─────────────────────────────────────────────────────────────── │
│ │
│ This is not innovation. This is recognition. │
│ The pattern was always there. We just saw it. │
│ │
└────────────────────────────────────────────────────────────────────────┘
Related Research
- Terminal Analysis - Architecture comparison