A console app UI (Textual-based TUI) dashboard for monitoring InfoMesh node status. Runs directly in the terminal without a separate web server, making it usable via SSH, mobile terminal apps (Termux, Blink, etc.), and low-spec server environments.
| Item | Choice | Reason |
|---|---|---|
| Framework | Textual (β₯1.0) | Rich-based, responsive CSS layout, mouse/keyboard support |
| Alternatives | curses/blessed/urwid | Textual dominates in CSS layout, widget system, and testability |
ββ InfoMesh Dashboard βββββββββββββββββββββββββββ v0.1.0 ββ
β β
β ββ Node βββββββββββββββ ββ Resources βββββββββββββββ β
β β Peer ID: Qm...3kF β β CPU: ββββββββββ 38% β β
β β State: π’ Running β β RAM: ββββββββββ 62% β β
β β Uptime: 3d 14h 22m β β Disk: ββββββββββ 81% β β
β β Version: 0.1.0 β β Netβ: 2.1/5.0 Mbps β β
β β GitHub: user@e... β β Netβ: 4.3/10.0 Mbps β β
β β Data dir: ~/.info... β β β β
β ββββββββββββββββββββββββ ββββββββββββββββββββββββββββ β
β β
β ββ Activity (last 1h) βββββββββββββββββββββββββββββββ β
β β Crawled: 142 pages βββ
ββ
ββββ
βββββ
ββ β β
β β Indexed: 138 docs βββ
ββ
ββββ
βββββ
ββ β β
β β Searches: 23 queries ββββββ
βββββββ
ββ β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββ Recent Events ββββββββββββββββββββββββββββββββββββ β
β β 14:23:01 Crawled example.com/page1 +1.0 cr β β
β β 14:22:58 π "python async" (12 results, 8ms) β β
β β 14:22:45 Peer Qm...xY2 connected β β
β β 14:22:30 Index snapshot exported (2.3 MB) β β
β β 14:22:15 Crawled docs.python.org/3/ +1.0 cr β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Implementation Notes: NodeInfoPanel shows Data dir instead of Peers. GitHub email is auto-detected from
git config user.emailand shown if available; displayed asnot connectedotherwise. The value is resolved once and cached. ResourcePanel displays CPU/RAM whenpsutilis installed, N/A otherwise. Resource bar colors auto-switch based on usage (β₯90% red, β₯70% yellow).
ββ Crawl ββββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β Workers: 3/5 active Rate: 42 pages/hr β
β Queue: 156 pending Errors: 2 (1.4%) β
β β
β ββ Top Domains ββββββββββββββββββββββββββββββββββββββ β
β β docs.python.org ββββββββββββ 234 pages β β
β β en.wikipedia.org βββββββββ 178 pages β β
β β developer.mozilla.org βββββββ 145 pages β β
β β stackoverflow.com βββββ 98 pages β β
β β arxiv.org βββ 67 pages β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββ Live Feed ββββββββββββββββββββββββββββββββββββββββ β
β β β docs.python.org/3/tutorial/ 1.2s 4.2KB β β
β β β en.wikipedia.org/wiki/P2P 0.8s 8.1KB β β
β β β example.com/blocked robots.txt β β β β
β β β arxiv.org/abs/2401.01234 2.1s 3.7KB β β
β β β³ developer.mozilla.org/en-US/... crawling... β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββ Search βββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β π Query: [python async tutorial________________] β
β β
β Found 12 results (8ms, local): β
β β
β ββ Results ββββββββββββββββββββββββββββββββββββββββββ β
β β 1. Python Asyncio Tutorial β β
β β https://docs.python.org/3/library/asyncio.html β β
β β BM25=2.341 Fresh=0.95 Trust=0.88 Auth=0.72 β β
β β Score: 1.8234 β β
β β This module provides infrastructure for writing β β
β β single-threaded concurrent code using... β β
β β β β
β β 2. Async IO in Python β β
β β https://realpython.com/async-io-python/ β β
β β BM25=2.102 Fresh=0.82 Trust=0.91 Auth=0.68 β β
β β Score: 1.6891 β β
β β Async IO is a concurrent programming design... β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
ββ Network ββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β ββ P2P Status βββββββββββ ββ DHT ββββββββββββββββββ β
β β State: π΄ Offline β β Keys stored: 1,234 β β
β β Peers: 0 connected β β Lookups/hr: 456 β β
β β Bootstrap: 3 nodes β β Publications: 89 β β
β β Port: 4001 TCP β β β β
β β Replication: 3x β β β β
β ββββββββββββββββββββββββββ ββββββββββββββββββββββββββ β
β β
β ββ Connected Peers ββββββββββββββββββββββββββββββββββ β
β β Peer ID Latency Trust State β β
β β Qm...aB2 23ms 0.92 active β β
β β Qm...cD4 45ms 0.85 active β β
β β Qm...eF6 102ms 0.78 idle β β
β β Qm...gH8 67ms 0.71 active β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββ Bandwidth ββββββββββββββββββββββββββββββββββββββββ β
β β Upload: βββ
ββ
ββββ
β 2.1/5.0 Mbps β β
β β Download: ββ
ββββ
ββ
ββ 4.3/10.0 Mbps β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Implementation Notes: P2P Status shows Bootstrap node count and Replication factor. Peer table columns: Peer ID, Latency, Trust, State (4 columns). Bandwidth sparkline shows current/limit format.
ββ Credits ββββββββββββββββββββββββββββββββββββββββββββββββ
β β
β ββ Balance ββββββββββββββββββββββββββββββββββββββββββ β
β β β β
β β Balance: 1,234.50 credits Tier: βββ (3) β β
β β Earned: 1,456.75 Search cost: 0.033 β β
β β Spent: 222.25 Score: 1,456.75 β β
β β β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββ Earnings Breakdown βββββββββββββββββββββββββββββββ β
β β Crawling ββββββββββββββ 702.0 (48.2%) β β
β β Uptime ββββββββ 396.0 (27.2%) β β
β β Query Process ββββ 178.5 (12.2%) β β
β β LLM (own) βββ 135.0 (9.3%) β β
β β Doc Hosting ββ 45.25 (3.1%) β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β
β ββ Recent Transactions ββββββββββββββββββββββββββββββ β
β β 14:23:01 +1.000 crawl example.com/page1 β β
β β 14:22:58 -0.033 search "python async" β β
β β 14:22:30 +0.500 uptime 1 hour β β
β β 14:22:15 +1.000 crawl docs.python.org/3/ β β
β β 14:21:00 +1.500 llm_own summarize page #456 β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Using Textual's responsive CSS, the layout automatically switches to a single-column layout on narrow screens (under 40 columns).
ββ InfoMesh ββββ v0.1.0 ββ
β β
β Peer: Qm...3kF β
β State: π’ Running β
β Uptime: 3d 14h β
β Peers: 12 β
β β
β CPU: ββββββββ 38% β
β RAM: ββββββββ 62% β
β Disk: ββββββββ 81% β
β β
β Crawled : 142 pages/hr β
β Indexed : 138 docs/hr β
β Searches: 23 queries/hr β
ββββββββββββββββββββββββββββ
infomesh/dashboard/ # 16 modules, 2,340 lines
βββ __init__.py
βββ app.py # DashboardApp (main Textual Application, 276 lines)
βββ bgm.py # BGMPlayer (background music via mpv/ffplay/aplay, 228 lines)
βββ text_report.py # Rich-based text report (non-interactive fallback, 333 lines)
βββ screens/
β βββ __init__.py
β βββ overview.py # OverviewPane β NodeInfoPanel, ResourcePanel, ActivityPanel, LiveLog (284 lines)
β βββ crawl.py # CrawlPane β CrawlStatsPanel, TopDomainsPanel, LiveLog (182 lines)
β βββ search.py # SearchPane β Input, SearchResultsPanel (151 lines)
β βββ network.py # NetworkPane β P2PStatusPanel, DHTPanel, PeerTable, BandwidthPanel (246 lines)
β βββ credits.py # CreditsPane β BalancePanel, EarningsBreakdownPanel, TransactionTable (289 lines)
βββ widgets/
β βββ __init__.py
β βββ sparkline.py # SparklineChart (Unicode block character mini chart, 75 lines)
β βββ bar_chart.py # BarChart + BarItem (horizontal bar graph, 90 lines)
β βββ resource_bar.py # ResourceBar (CPU/RAM/Disk/Net resource bar, 80 lines)
β βββ live_log.py # LiveLog (real-time event log, RichLog-based, 96 lines)
βββ dashboard.tcss # Textual CSS stylesheet (responsive layout)
# Launch dashboard
infomesh dashboard
# Start on a specific tab
infomesh dashboard --tab credits
# Available tabs: overview, crawl, search, network, credits (default: overview)
infomesh dashboard -t networkDashboardApp (App[None])
βββ Header β Title "InfoMesh Dashboard" + version display
βββ TabbedContent (initial=selected tab)
β βββ TabPane "Overview" β OverviewPane
β β βββ Horizontal
β β β βββ NodeInfoPanel (Peer ID, State, Uptime, Version, Data dir)
β β β βββ ResourcePanel (CPU, RAM, Disk, Netβ, Netβ)
β β βββ ActivityPanel (Crawled/Indexed/Searches + SparklineChart Γ3)
β β βββ LiveLog (event feed)
β βββ TabPane "Crawl" β CrawlPane
β β βββ CrawlStatsPanel (Workers, Queue, Rate, Errors)
β β βββ TopDomainsPanel (SQL GROUP BY domain β BarChart)
β β βββ LiveLog (crawl feed)
β βββ TabPane "Search" β SearchPane
β β βββ Input (search query)
β β βββ SearchResultsPanel (BM25 scores + snippets)
β βββ TabPane "Network" β NetworkPane
β β βββ Horizontal
β β β βββ P2PStatusPanel (State, Peers, Bootstrap, Port, Replication)
β β β βββ DHTPanel (Keys, Lookups/hr, Publications)
β β βββ PeerTable (DataTable: Peer ID, Latency, Trust, State)
β β βββ BandwidthPanel (Upload/Download SparklineChart + current/limit)
β βββ TabPane "Credits" β CreditsPane
β βββ BalancePanel (Balance, Earned, Spent, Tier, Search cost)
β βββ EarningsBreakdownPanel (per-action BarChart)
β βββ TransactionTable (DataTable: Time, Amount, Type, Note)
βββ Footer β keyboard shortcut display
| Key | Action | Scope |
|---|---|---|
1-5 |
Switch tabs (Overview β Credits) | Global |
Tab |
Focus next widget | Global (Textual default) |
Shift+Tab |
Focus previous widget | Global (Textual default) |
/ |
Focus search input | Search tab only |
q |
Quit | Global |
r |
Refresh (Overview, Crawl, Network, Credits) | Global |
m |
Toggle BGM on/off | Global |
? |
Show help notification (5s timeout) | Global |
The dashboard can play background music during operation via an external player subprocess.
Players are auto-detected in this order: mpv, ffplay (part of ffmpeg). If neither is found, BGM is silently disabled.
# Install on Debian/Ubuntu:
sudo apt install mpv # or: sudo apt install ffmpeg
# Install on macOS:
brew install mpv # or: brew install ffmpegBGM is off by default. Enable it with the m keyboard shortcut or via config:
[dashboard]
bgm_auto_start = true # false by default β enable to auto-play on start
bgm_volume = 50 # 0β100
bgm_idle_stop = true # auto-stop BGM when crawling is idle (set false to keep playing)If the audio player process crashes unexpectedly, BGM will automatically restart (up to 5 attempts). This is handled transparently β a notification appears when auto-restart occurs.
On resource-constrained systems (especially WSL2), the audio player subprocess may compete with crawling and indexing for CPU time, causing stuttering. If this occurs:
- Press
mto disable BGM - Use
mpvinstead offfplay(lighter CPU usage) - Increase
refresh_intervalto reduce dashboard overhead - Use the
minimalresource profile
- Dependencies:
textual>=1.0(in main deps, currentlytextual==8.0.0) - Data refresh intervals (per-tab):
- Overview:
set_interval(2.0)β refresh resource/node status every 2s - Crawl:
set_interval(3.0)β refresh domain stats every 3s - Network:
set_interval(2.0)β refresh P2P status every 2s - Credits:
set_interval(5.0)β refresh credit data every 5s - Search: no auto-refresh (runs only on user query input)
- Overview:
- Data sources:
LocalStoreβ document count, domain stats, search (SQLite FTS5)CreditLedgerβ balance, earnings breakdown, transaction recordspsutil(optional) β CPU/RAM usage (shows N/A if not installed)shutil.disk_usage()β disk usage- PID file (
infomesh.pid) β node running status check KeyPair.load()β Peer ID loading
- Error handling: Shows "N/A" or guidance message when data source is unavailable; all
refresh_data()wrapped withcontextlib.suppress(Exception) - Tests: 53 pytest unit/integration tests (
tests/test_dashboard.py)- Widget tests: SparklineChart (6), BarChart (4), ResourceBar (4), LiveLog (1)
- Helper tests:
_format_uptime(),_is_node_running(),_get_peer_id()(7) - Screen tests: SearchResultsPanel (3), CreditsHelpers (2), NetworkPanels (1), CrawlStatsPanel (2)
- App/CLI tests: DashboardApp (3), CLI command (1), BarItem (3), Sparkline edge cases (4)
- BGM/text report tests: BGMPlayer, text_report, etc. (12)
- Uses Unicode block characters:
" βββββ βββ"(9 levels) reactiveproperties for automatic re-render on data changepush_value(max_points=30)β maintains up to 30 data points- Automatic value normalization (min-max scaling)
BarItemdataclass: label, value, color, suffixβ/βcharacters for horizontal bar rendering (default width 20 chars)- Displays both ratio to max value and percentage of total simultaneously
Related docs: Overview Β· Architecture Β· Credit System Β· Tech Stack Β· Legal Β· Trust & Integrity Β· Security Audit Β· MCP Integration Β· Publishing Β· FAQ