signal-tui
overview
A terminal user interface for Signal messenger, built with Python and Textual. Connects to a locally running signal-cli daemon to send and receive messages without leaving the terminal.
Features full message send/receive, six built-in themes (plus custom theme support), contact management with persistent storage, read receipts, smart notifications (only for messages outside the current conversation), and message history with attachment indicators.
tech stack
Language: Python 3.10+.
UI framework: Textual — a modern Python TUI framework. The layout is a two-panel split: contact list on the left, message history and input on the right. An info panel (toggled with Tab/Esc) shows conversation stats.
Backend: signal-cli — a Java-based command-line Signal client. Signal-TUI spawns it as a daemon and communicates over a local JSON-RPC socket to send and receive messages.
Storage: Contact names and configuration live in ~/.config/signal-tui/ as YAML and JSON files. Message history is kept in memory per session.
Key dependencies: Textual, plus signal-cli (installed separately — available via pacman, manual download, or Homebrew on macOS).
themes
Six built-in presets: retro-green, cyberpunk-pink, nord, gruvbox, dracula, solarized-dark. Set the active preset in ~/.config/signal-tui/config.yaml under theme.preset.
Custom themes are supported via preset: custom with inline colour overrides, or by defining named custom presets under theme.custom_presets. All colours (primary, secondary, background, text, etc.) are configurable.
development
Signal-TUI manages the signal-cli daemon lifecycle: it starts the daemon on launch, monitors it, and restarts it if it dies. The r keyboard shortcut force-restarts the daemon from within the UI without quitting the app.
Device linking (pairing with your Signal mobile app via QR code) is handled in-app using the l shortcut, which wraps the signal-cli link command and renders the QR code directly in the terminal.
An install.sh script creates a Python virtual environment, installs all dependencies, and sets up a .desktop launcher entry for use from your application menu. An update.sh script handles pulling new versions and upgrading the venv.
Project structure: signal_tui/app.py (main app), daemon.py (signal-cli lifecycle), signal_client.py (JSON-RPC interface), themes.py (theme definitions), widgets/ (UI components), screens/ (modal dialogs).