Initial commit: Metro Warden TUI network operations center

This commit is contained in:
2026-03-22 21:33:40 -04:00
commit 98a17d9b7e
45 changed files with 4215 additions and 0 deletions
+136
View File
@@ -0,0 +1,136 @@
# Metro Warden
**Industrial dark metro map Network Operations Centre — Python Textual TUI**
Metro Warden is a keyboard-driven terminal UI for monitoring network
interfaces, routing tables, firewall rules, DNS health, and system resources.
It is built on [Textual](https://github.com/Textualize/textual) and follows a
pub/sub event-bus architecture with a single source of truth state store and
a plugin system.
---
## Architecture
```
┌─────────────────────────────────────────────────────────────┐
│ MetroWarden (App) │
│ ┌──────────┐ ┌───────────┐ ┌──────────────────────────┐ │
│ │ EventBus │ │StateStore │ │ PluginRegistry │ │
│ │ pub/sub │◄─│ reactive │ │ network dns firewall sys │ │
│ └──────────┘ └───────────┘ └──────────────────────────┘ │
│ ▲ ▲ │ │
│ │ │ publishes │ │
│ ┌────┴───────────────────────────────┐ │ │
│ │ UI Tabs │◄─┘ │
│ │ Lines · Routes · Signals │ │
│ │ Chronicle · Registry · Garrison │ │
│ │ Settings │ │
│ └────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
### Core
| Module | Purpose |
|--------|---------|
| `core/bus.py` | Asyncio pub/sub event bus with wildcard topic support |
| `core/state.py` | Reactive state store; watchers + bus publication on change |
| `core/registry.py` | Plugin discovery, loading, lifecycle management |
| `core/app.py` | Main `MetroWarden(App)` class — wires everything together |
### Plugins
| Plugin | Topics published |
|--------|-----------------|
| `network` | `network.interfaces`, `network.stats` |
| `dns` | `dns.resolvers`, `dns.health`, `dns.query.result` |
| `firewall` | `firewall.rules`, `firewall.chains` |
| `system` | `system.cpu`, `system.memory`, `system.disk`, `system.load`, `system.snapshot` |
### Tabs
| Tab | Key | Content |
|-----|-----|---------|
| Lines | `1` | Network interfaces — name, status, IP, RX/TX |
| Routes | `2` | System routing table |
| Signals | `3` | Live scrolling event monitor |
| Chronicle | `4` | Persistent log viewer with filtering |
| Registry | `5` | Plugin status and toggle |
| Garrison | `6` | Firewall chains and rules |
| Settings | `7` | Configuration form |
---
## Installation
```bash
# Create a virtual environment
python -m venv .venv
source .venv/bin/activate # or .venv\Scripts\activate on Windows
# Install dependencies
pip install -e ".[dev]"
```
## Running
```bash
python main.py
# With debug logging
python main.py --debug
# Log to file
python main.py --log-file metro-warden.log
# Custom config
python main.py --config /path/to/config.toml
```
Or via the installed script:
```bash
metro-warden
```
## Keybindings
| Key | Action |
|-----|--------|
| `17` | Switch tab |
| `q` | Quit |
| `Ctrl+R` | Reload all plugins |
| `r` | Refresh current tab (where supported) |
| `c` | Clear log (Signals / Chronicle) |
| `p` | Pause Signals stream |
| `f` | Focus filter input (Chronicle) |
| `Enter` | Toggle plugin load (Registry) |
| `s` | Save settings (Settings) |
## Testing
```bash
pytest
pytest --cov
```
## Configuration
Edit `config/defaults.toml` to adjust poll intervals, enable/disable plugins,
and set display limits. The Settings tab writes back to this file on save.
## Theme
The industrial dark metro map aesthetic uses:
| Role | Colour |
|------|--------|
| Background | `#1a1a2e` deep charcoal |
| Surface / panels | `#16213e` |
| Primary / electric blue | `#00d4ff` |
| Active / green | `#00ff88` |
| Warning / amber | `#ff8c00` |
| Error / red | `#ff4444` |
CSS overrides live in `assets/styles/metro.tcss`.