Skip to main content

hop3-tui

Terminal User Interface for Hop3 PaaS.

Overview

A modern, keyboard-driven terminal interface for managing Hop3 applications, built with turbodesk.

Features

  • Dashboard overview: System stats, app summary, recent activity
  • Application management: List, filter, start/stop/restart apps
  • Environment variables: View, add, edit, delete with sensitive value hiding
  • Live log polling: Filter logs, pause/resume, auto-scroll
  • Chat interface: Interactive command line with tab completion
  • System monitoring: CPU, memory, disk usage and service status
  • Addon management: Create, attach, detach PostgreSQL, Redis, MySQL
  • Backup management: Create, restore, delete app backups
  • Connection status indicator: Visual feedback for server connectivity

Installation

pip install hop3-tui

Quick Start

# Set your server URL
export HOP3_SERVER_URL="https://hop3.example.com"
export HOP3_TOKEN="your-api-token"

# Run the TUI
hop3-tui

Configuration

Configuration via environment variables or ~/.config/hop3/tui.toml:

Variable Description Default
HOP3_SERVER_URL Server URL http://localhost:5000
HOP3_TOKEN API authentication token -
HOP3_TUI_THEME Color theme (dark/light) dark

Config File

[server]
url = "https://hop3.example.com"
token = "your-api-token"

[display]
theme = "dark"
refresh_interval = 5

Keyboard Shortcuts

Global

Key Action
d Dashboard
a Apps list
s System status
o Addons
b Backups
c Chat interface
? Help
q Quit

Navigation

Key Action
j/Down Move down
k/Up Move up
Enter Select
Escape Go back
/ Filter
R Refresh

Apps

Key Action
s Start app
S Stop app
r Restart app
l View logs
e Environment variables

Architecture

hop3-tui/
├── src/hop3_tui/
│   ├── __main__.py       # Entry point
│   ├── app.py            # Main Hop3TUI class with connection state
│   ├── config.py         # Configuration loading (env vars + TOML)
│   ├── api/
│   │   ├── client.py     # JSON-RPC client with error handling
│   │   └── models.py     # Pydantic data models
│   ├── screens/          # One `render(ui, hop3, size, ...) -> View` per screen
│   │   ├── _common.py    # bind(), halves(), rows(), fill() — what CSS used to do
│   │   ├── _logview.py   # The pane behind both logs.py and system_logs.py
│   │   ├── dashboard.py  # Overview with app counts
│   │   ├── apps.py       # App list and management
│   │   ├── app_detail.py # Single app view
│   │   ├── logs.py       # Live log polling
│   │   ├── env_vars.py   # Environment variable editor
│   │   ├── system.py     # System status
│   │   ├── addons.py     # Addon management
│   │   ├── backups.py    # Backup management
│   │   ├── processes.py  # Running processes
│   │   ├── system_logs.py# System-wide logs
│   │   └── chat.py       # Command interface
│   └── widgets/
│       ├── chrome.py        # Header, footer, panel frames
│       ├── status_panel.py  # Resource meters
│       ├── status_badge.py  # Status indicators
│       └── util.py          # Bar gauges, and the "not reported" marker
└── tests/                # pytest test suite (235 tests)

Immediate mode

There is no widget tree. The app is a function (UI) -> View that turbodesk re-runs whenever a frame is marked dirty, and a screen is a function of its arguments — so there is no compose(), no reactive/watch_*, no query_one, and no stylesheet. Layout is arithmetic (halves, rows), and state lives in ui.state hooks matched between frames by call order. Each screen renders inside its own ui.scope, which is what keeps those slots from being handed to the next screen on a switch.

Rendering has no side effect on the screen, so a test calls the app function at any size and asserts on what came out — no pilot, no event loop, no async harness:

to_text(render(app(hop3), size=Size(90, 26)))

Nothing is invented

A panel shows what the server reported or says that it does not know (not reported by the server); it never shows a plausible-looking constant. The log pane's heading drops from LIVE to UNREACHABLE when a poll fails, rather than going on looking live over a dead connection. tests/test_no_fabricated_data.py holds that line.

Connection Handling

The TUI tracks connection state to the Hop3 server:

  • Connected (green indicator): Server is reachable
  • Disconnected (red indicator): Connection lost, will retry
  • Connecting (yellow indicator): Attempting to connect

Connection failures are tracked and the state updates automatically. The UI continues to show cached data while disconnected.

Development

# Run it
uv run hop3-tui

# Run tests (from the workspace root)
uv run pytest packages/hop3-tui/tests

# Lint and format
uv run ruff check src/
uv run ruff format src/

Documentation

Related Packages

  • hop3-server - The server that hop3-tui communicates with
  • hop3-cli - Alternative command-line interface

License

Apache-2.0 - Copyright (c) 2024-2026, Abilian SAS

Metadata

Release files for hop3-tui 0.7.3

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

Source distribution (sdist)

Source distribution for hop3-tui 0.7.3
File Size Uploaded
hop3_tui-0.7.3.tar.gz 32.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for hop3-tui 0.7.3
File Interpreter ABI Platform
hop3_tui-0.7.3-py3-none-any.whl Python 3 none any Details

Total release size: 81.5 kB

Release files / hop3_tui-0.7.3.tar.gz

Download URL hop3_tui-0.7.3.tar.gz
Size 32.1 kB
Tags Source
SHA-256 checksum
How to use checksums
4ffc1b5e58f9f031f32adda7fdf4badb0ae43923ed2654e97341995b986b42de
BLAKE2b-256 checksum
How to use checksums
8350891278d88b4e9574aa77d96d1194d18694008a1eaf1653f346d35db2fcd7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Release files / hop3_tui-0.7.3-py3-none-any.whl

Download URL hop3_tui-0.7.3-py3-none-any.whl
Size 49.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c6b3a4ad4994cc7b3b0dec4b8eb138d51a744c17debeb243226278dd7138bcd2
BLAKE2b-256 checksum
How to use checksums
016ab9467f339deb5f236c196979daf0a0be2b70efde5b17c2a949cf2352fb0a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13
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