Comprehensive guide for developing and maintaining MeshTUI, a full-featured MeshCore TUI client for mesh networking. Covers architecture, components, development workflow, and common tasks.
You are assisting with development of **MeshTUI**, a full-featured MeshCore client with a comprehensive Terminal User Interface (TUI). Built with the Textual framework, it provides a complete mesh networking experience with keyboard-driven interface for managing mesh networks, sending messages, configuring devices, monitoring network status, and administering mesh nodes.
The codebase follows a strict layered architecture:
1. **UI Layer** (`app.py`) - Textual widgets, chat interface, contacts, logs, tabs
2. **Connection Orchestration** (`connection.py`) - Lifecycle management, event handling
3. **Domain Managers** - ContactMgr (`contact.py`), ChannelMgr (`channel.py`), RoomMgr (`room.py`), Database (`database.py`)
4. **Transport Layer** (`transport.py`) - SerialTransport, BLETransport, TCPTransport
5. **MeshCore Library** - External dependency for low-level radio communication
1. **Separation of Concerns**: Each module has a single, well-defined responsibility
2. **Async/Await Throughout**: All I/O operations are non-blocking
3. **Manager Pattern**: Domain logic delegated to specialized managers
4. **Event-Driven**: Reactive architecture using callbacks and event subscriptions
5. **Persistent Storage**: SQLite for message history and contact persistence
**Purpose**: Textual UI composition, user interactions, chat interface, node management
**Key Classes**: `MeshTUIApp`, `ChatTab`, `NodeManagementTab`, `ContactList`, `Log` widget
**Important Methods**:
**UI Layout**: Two-panel design with sidebar (contacts/channels) and tabbed main content (Chat / Device Settings / Node Management / Logs)
**Purpose**: Device connection lifecycle, event handling, manager coordination
**Critical Methods**:
**Database Initialization**: Database is created per-device after connection, using the device's public key from `meshcore.self_info`
**Purpose**: Abstract BLE/Serial/TCP connectivity
**Key Classes**: `SerialTransport`, `BLETransport`, `TCPTransport`
**Auto-detection**: Scans for devices, tests identification, prioritizes `/dev/ttyUSB0`
**Per-Device Databases**: Each connected device gets its own database file at `~/.config/meshtui/devices/{device_pubkey[:16]}.db`
**Schema**: `messages`, `contacts`, `last_read` tables
**Methods**: `store_message()`, `get_messages_for_contact()`, `mark_as_read()`, `store_contact()`
**Purpose**: Expose Serial/BLE devices over TCP for remote access
**Status**: Phase 1 MVP complete, experimental
**Key Components**: `proxy.py`, `backends/serial.py`, `tcp_server.py`, `config.py`, `__main__.py`
**Features**: Zero protocol translation, multi-client support, YAML configuration
```bash
git clone <repo>
cd meshtui
python -m venv .venv # Create virtual environment (or: uv venv)
source .venv/bin/activate # Activate (Linux/Mac)
pip install -e . # Install in development mode (or: uv pip install -e .)
```
**For end users**, recommend `pipx install meshtui` or `uv tool install meshtui` to isolate dependencies.
```bash
python -m meshtui # Basic launch
python -m meshtui --serial /dev/ttyUSB0 # With serial device
python -m meshtui --tcp 192.168.1.100:5000 # TCP connection
meshtui --address C2:2B:A1:D5:3E:B6 # BLE connection
```
1. **Type hints on all functions**
2. **Comprehensive docstrings**
3. **Try-catch blocks with logging for async operations**
4. **Structured logging** (DEBUG, INFO, ERROR levels)
1. **Connection status checks** before operations
2. **Command execution** through `commands` attribute:
```python
device.commands.messaging.send_direct_message(recipient, text)
```
3. **Event subscription** for reactive updates:
```python
device.subscribe(event_type, callback)
```
4. **Timeouts on all async operations**
1. **Widget references** stored in `on_mount()`:
```python
def on_mount(self):
self.chat_display = self.query_one("#chat_display", Static)
```
2. **Event handlers** using `@on` decorator:
```python
@on(Button.Pressed, "#send_button")
def handle_send(self):
...
```
3. **UI updates from main thread**
1. Identify the appropriate layer (UI, Connection, Manager, Transport)
2. Update the relevant manager if domain logic is needed
3. Add event handlers in `connection.py` if events are involved
4. Update UI in `app.py` for user interaction
5. Add persistence in `database.py` if data needs to be saved
6. Update tests in `test_connection.py`
1. Update `ContactType` enum in `contact.py`
2. Add detection logic in `ContactManager._detect_contact_type()`
3. Update UI rendering in `app.py` if special display is needed
4. Update database schema if new metadata is required
1. Identify the event type from meshcore API
2. Subscribe in `connection.py` `_setup_event_handlers()`
3. Add handler method `_handle_<event_name>()`
4. Update relevant manager (ContactManager, ChannelManager, etc.)
5. Update UI via callback to `app.py`
1. Check `~/.config/meshtui/meshtui.log` for DEBUG logs
2. Verify device identification in transport layer
3. Check event subscription success in connection layer
4. Verify meshcore API compatibility
5. Test with `test_connection.py` script
**Symptom**: `Task was destroyed but it is pending!` warnings from meshcore
**Cause**: Upstream meshcore library issue
**Impact**: Harmless, doesn't affect functionality
**Status**: No action required
**Symptom**: Connection fails with "Permission denied" or "Could not open port" errors
**Cause**: User not in `dialout` group (Linux) or insufficient permissions
**Solution**:
**Symptom**: BLE scan fails
**Cause**: No Bluetooth adapter or disabled Bluetooth
**Solution**: Enable Bluetooth or use Serial/TCP connection
```python
device.commands.messaging.send_direct_message(recipient_id, text)
device.commands.messaging.send_channel_message(channel, text)
device.commands.contacts.get_contacts()
device.commands.contacts.add_contact(name, pubkey)
device.commands.device.get_info()
device.commands.device.get_status()
device.commands.channels.get_channels()
device.commands.channels.join_channel(channel_name)
device.commands.room.login(node_name, password)
device.commands.room.send_command(command_text)
device.commands.room.logout()
```
1. **TCP Proxy (EXPERIMENTAL)** - Phase 1 MVP complete: expose Serial devices over TCP (~860 lines)
2. **Auto Time Sync** - Automatically syncs device time on connection for devices without GPS
3. **GPS Detection** - Added GPS availability detection via telemetry mode
4. **Per-Device Databases** - Each device now gets its own database file to prevent data collision
5. **Room Messaging Fix** - Fixed room messages handling
---
When working on this codebase, always:
Leave a review
No reviews yet. Be the first to review this skill!
# Download SKILL.md from killerskills.ai/api/skills/meshtui-development-guide/raw