pi-tui: Terminal UI Framework
Relevant source files
The following files were used as context for generating this wiki page:
pi-tui (exported as @oh-my-pi/pi-tui) is a minimal terminal user interface library designed for creating efficient, flicker-free interactive CLI applications. It is used primarily as the interface for the omp coding agent, providing a sophisticated text-based environment that supports complex components like multi-line editors, markdown rendering, and inline graphics.
The framework is built around a differential rendering system that optimizes screen updates by only pushing changes to the terminal. It leverages modern terminal capabilities, such as the Kitty keyboard protocol and DEC 2026 synchronized output, to ensure a high-quality user experience similar to graphical applications while remaining entirely within the terminal buffer.
Sources: packages/tui/package.json:3-5, packages/tui/README.md:1-15, packages/coding-agent/DEVELOPMENT.md:86-87
Architecture & Rendering Engine
The framework employs a three-strategy differential rendering system to maintain performance and prevent flickering. This system is managed by the TUI class, which acts as the central coordinator for component lifecycles and terminal I/O.
Rendering Strategies
- First Render: The framework outputs all lines of all components without clearing the scrollback.
- Full Re-render: Triggered by terminal resizing or content changes above the current viewport. The screen is cleared before a complete redraw.
- Normal Update: The engine moves the cursor to the first changed line, clears from that point to the end of the screen, and renders only the modified lines.
Sources: packages/tui/README.md:275-280
Atomic Updates
To eliminate flickering, pi-tui uses Synchronized Output (CSI 2026). This wraps rendering updates in a "begin/end" marker (\x1b[?2026h ... \x1b[?2026l), instructing the terminal to buffer the writes and display them as a single atomic frame.
Sources: [packages/tui/README.md:282-286](https://github.com/metaphorics/oh-my-pi/blob/0ba736f5bc97127c67918269273309463091fcdf/?2026h` ... \x1b[?2026l), instructing the terminal to buffer the writes and display them as a single atomic frame.
Sources: [packages/tui/README.md:282-286)
Component Lifecycle
All UI elements must implement a standard Component interface. This interface forces a functional approach to rendering where components return an immutable array of strings, facilitating memoization and differential comparison.
The diagram above shows the relationship between the TUI manager, the component contract, and the terminal output.
Sources: packages/tui/README.md:38-55
Core Components
The framework provides a suite of built-in components that handle layout, text processing, and interactive input.
Structural Components
| Component | Description |
|---|---|
| Container | A generic group for child components. |
| Box | A container that applies padding and background colors to its children. |
| Spacer | Provides vertical whitespace between components. |
Sources: packages/tui/README.md:57-79, packages/tui/README.md:204-206
Interactive Components
Interactive components manage their own internal state and handle raw terminal input sequences via the handleInput method.
- Editor: A multi-line text editor supporting word wrap, slash commands, file path autocomplete, and undo/redo functionality. It features "fake cursor" rendering to provide better visual feedback.
- Input: A single-line text input field with horizontal scrolling.
- SelectList: A menu for selecting from a list of items with keyboard navigation.
- SettingsList: A specialized list for cycling through configuration values or opening submenus.
Sources: packages/tui/README.md:104-123, packages/tui/README.md:144-202
Visual Components
- Markdown: Renders markdown with syntax highlighting, tables, and nested lists. It includes a module-level LRU (Least Recently Used) cache to avoid expensive re-rendering of complex blocks like code or tables.
- Image: Supports inline graphics using the Kitty or iTerm2 protocols.
- Loader: Provides animated spinners and status messages, with a
CancellableLoadervariant that supportsAbortSignalfor async task management.
Sources: packages/tui/README.md:208-220, packages/tui/README.md:144-165, packages/tui/test/markdown.test.ts:553-560
Markdown Rendering System
The Markdown component is a high-performance renderer that converts markdown text into ANSI-formatted terminal lines. It handles complex layouting such as table wrapping and nested list indentation.
Performance & Caching
The renderer utilizes two levels of caching:
- L1 Cache: Instance-level caching that returns the identical array reference if text and width have not changed.
- L2 Cache: A module-level LRU cache that allows distinct Markdown instances with identical content and themes to share rendered output.
Sources: packages/tui/test/markdown.test.ts:553-580
Advanced Feature Support
| Feature | Implementation Detail |
|---|---|
| Tables | Supports cell wrapping, alignment, and row dividers. Ensures columns are at least the width of the longest word. |
| Mermaid | Can resolve Mermaid diagrams into ASCII art via a provided resolver function. |
| Math | Converts LaTeX blocks (e.g., \begin{cases}, pmatrix) into Unicode-based multi-line text. |
| Text Sizing | Uses OSC 66 sequences for scale-2 H1 headings in supported terminals. |
Sources: packages/tui/test/markdown.test.ts:74-140, packages/tui/test/markdown.test.ts:400-415, packages/tui/test/markdown.test.ts:608-620, packages/tui/test/markdown.test.ts:778-790
Input Handling and Terminal Integration
pi-tui provides low-level utilities for detecting keyboard input, including support for the Kitty keyboard protocol for advanced modifiers.
Input Flow
The sequence diagram illustrates how raw terminal data is propagated through the framework to trigger state updates and subsequent renders.
Sources: packages/tui/README.md:244-270, packages/tui/README.md:288-300
Terminal Interfaces
The framework is decoupled from the actual process via a Terminal interface. This allows it to run on standard process.stdin/stdout (via ProcessTerminal) or within a headless test environment (via VirtualTerminal).
Key terminal capabilities detected include:
- TrueColor Support: Determines if 24-bit colors can be used.
- Hyperlink Support: Enables OSC 8 hyperlink sequences in components.
- Graphics Protocol: Detects Kitty or iTerm2 support for inline images.
Sources: packages/tui/README.md:288-310, packages/tui/test/markdown.test.ts:503-510, packages/natives/test/native.test.ts:600-610
Technical Utilities
The framework includes several string-processing utilities designed for ANSI-aware text layout:
visibleWidth(str): Calculates the visual columns a string occupies, ignoring ANSI codes and correctly handling wide Unicode characters (viaBun.stringWidth).truncateToWidth(str, width): Truncates a string while ensuring ANSI sequences are properly closed to prevent style leakage.wrapTextWithAnsi(str, width): Performs word wrapping that preserves ANSI formatting across line breaks.
Sources: packages/tui/README.md:313-330, packages/natives/test/native.test.ts:25-35
Conclusion
pi-tui represents a robust solution for building terminal-based developer tools within the oh-my-pi ecosystem. By combining a component-based model with an efficient differential rendering engine and modern terminal protocol support, it enables complex interactive workflows that maintain the responsiveness and visual fidelity usually reserved for GUI environments.
Sources: packages/tui/README.md:1-10, packages/coding-agent/DEVELOPMENT.md:86-90