Skip to main content

saber-tui

A simple TUI in Python, inspired by pi-tui.

saber-tui provides low-level building blocks for terminal UIs: a render tree, raw terminal integration, focus and overlays, editable text controls, list selection, animated loaders, and ANSI/Unicode-aware layout helpers.

Features

  • TUI and Container render trees with differential rendering, resize handling, overlays, focus management, and optional hardware cursor placement.
  • ProcessTerminal for raw terminal lifecycle, bracketed paste, resize callbacks, title/progress control, native scrollback-friendly rendering, and automatic POSIX/native Windows backend selection.
  • Key parsing and customizable keybindings, including kitty keyboard protocol, modifyOtherKeys sequences, printable key decoding, and key repeat/release detection.
  • Text layout components: Text, TruncatedText, Box, and Spacer.
  • Streaming-safe Markdown with headings, inline styles, fenced/highlighted code, nested and task lists, blockquotes, tables, links, HTML text, and ANSI-aware wrapping.
  • Interactive controls: single-line Input, multiline Editor, SelectList, SettingsList, Loader, and CancellableLoader.
  • Editor behavior for command-style input: history, undo, kill/yank, word movement, paste markers, submit/change callbacks, and configurable padding.
  • Autocomplete primitives and providers: AutocompleteItem, SlashCommand, AutocompleteSuggestions, CompletionResult, and CombinedAutocompleteProvider with command and path suggestions.
  • ANSI-aware wrapping, slicing, truncation, background application, grapheme handling, fuzzy matching, and terminal-output normalization utilities.

Usage

from saber_tui import ProcessTerminal, TUI, matches_key
from saber_tui.components import Editor, Text

terminal = ProcessTerminal()
tui = TUI(terminal)
tui.add_child(Text("Welcome"))

editor = Editor(tui)
editor.on_submit = lambda value: tui.add_child(Text(f"You said: {value}"))
tui.add_child(editor)
tui.set_focus(editor)

def exit_on_ctrl_c(data: str):
    if matches_key(data, "ctrl+c"):
        tui.stop()
        raise SystemExit(0)
    return None

tui.add_input_listener(exit_on_ctrl_c)
tui.start()

Markdown can be updated as assistant output streams in. Incomplete closing code fences are stabilized so the block does not flicker when the last backtick arrives:

from saber_tui.components import Markdown, MarkdownTheme

markdown = Markdown("", padding_x=1, theme=MarkdownTheme())
tui.add_child(markdown)

# For each streamed chunk:
markdown.append_text(chunk)
tui.request_render()

Use MarkdownTheme to supply ANSI style functions, DefaultTextStyle for a message-wide foreground/background and decorations, and MarkdownOptions for source marker/escape preservation or explicit OSC 8 hyperlink behavior.

Terminal images

from saber_tui.components import Image

tui.add_child(Image(tui, png_bytes, "image/png"))

Images are detected conservatively per TUI: Kitty, Ghostty, WezTerm, and Warp use the Kitty graphics protocol; iTerm2 uses OSC 1337. Kitty accepts PNG data only, while iTerm2 recognizes PNG, JPEG, GIF, and WebP containers. Unknown terminals, Windows Terminal, VS Code, Alacritty, JetBrains JediTerm, tmux, and screen receive a width-safe text fallback. Sixel is not supported. Terminal image rows are opaque to overlays, and overlays may not contain image commands. Components cache their base64/rendered representation, so retaining many image components also retains their encoded image data in memory; call invalidate() after terminal metrics or image presentation options change.

For settings-style UIs, use SettingsList with value cycling, fuzzy search, and optional submenus:

from saber_tui.components import SettingItem, SettingsList, SettingsListOptions

settings = SettingsList(
    [
        SettingItem("theme", "Theme", "dark", values=["dark", "light", "system"]),
        SettingItem("streaming", "Streaming", "on", values=["on", "off"]),
    ],
    max_visible=8,
    on_change=lambda setting_id, value: print(f"{setting_id} = {value}"),
    options=SettingsListOptions(enable_search=True),
)

Run the examples:

uv run python examples/chat.py
uv run python examples/showcase.py

The chat demo renders its streamed assistant response through Markdown. The component gallery includes a dedicated Markdown page; press r there to replay the stream and watch inline styles, lists, code fences, blockquotes, and tables appear incrementally.

ProcessTerminal supports POSIX terminals and native Windows consoles with virtual terminal processing, including Windows Terminal and recent PowerShell or cmd sessions. WSL uses the POSIX backend.

Development

uv run pytest
uv run ruff check
uv run ruff format --check
uvx ty check

Current Scope

Available in this slice:

  • Core TUI, Container, overlays, focus, and differential rendering.
  • ProcessTerminal on POSIX and native Windows VT-capable consoles.
  • ANSI and Unicode width utilities.
  • StdinBuffer with bracketed paste handling.
  • Key parsing and keybindings.
  • Text, TruncatedText, Box, Spacer, Markdown, Input, Editor, SelectList, SettingsList, Loader, and CancellableLoader.
  • Slash-command and file/path autocomplete support.

Outside this slice:

  • Sixel and terminal image protocols other than Kitty and iTerm2.
  • Legacy Windows consoles without virtual terminal processing.

Metadata

Release files for saber-tui 0.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for saber-tui 0.6.0
File Size Uploaded Provenance
saber_tui-0.6.0.tar.gz 163.8 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for saber-tui 0.6.0
File Interpreter ABI Platform
saber_tui-0.6.0-py3-none-any.whl Python 3 none any Details

Total release size: 234.9 kB

Release files / saber_tui-0.6.0.tar.gz

Download URL saber_tui-0.6.0.tar.gz
Size 163.8 kB
Tags Source
SHA-256 checksum
How to use checksums
f6694087b00508c36cc031a78289a1c696605a79c28331577c3b739ebd241aa5
BLAKE2b-256 checksum
How to use checksums
22516757f60b7350accad4f07118e1d2285c4d3598995cd6c3085b999d8c1d77
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / saber_tui-0.6.0-py3-none-any.whl

Download URL saber_tui-0.6.0-py3-none-any.whl
Size 71.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fa81993c88e09cde17647bc9057e39b90a53a9eee94f53a01b01a2a62ecb3a5f
BLAKE2b-256 checksum
How to use checksums
d9df923445a3c2f15c79f35854ab2ebe007371cdd5d152569267d80ce43578cd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.11.30 {"installer":{"name":"uv","version":"0.11.30","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for saber-tui 0.6.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page