Files
MeshTerm/meshterm/tools/livefeed.py
T
Jean-Pierre MartineauandClaude Fable 5 79410c4f16 Live feed: the dashboard's packet stream, promoted to the menu
The feed panel moves out of the dashboard into its own first-class Mesh
tool, right below it: a full-screen newest-first stream with the same
row lanes, highlight walking, and Enter-into-the-packet-viewer, wired
to the hub by its opener exactly as the dashboard is. The dashboard
becomes pure overview — activity, traffic, RF health — scrolling as
one body, and sheds the viewer-only plumbing (prefix bytes, channels,
self name, node types) it only carried for the feed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 00:52:45 -04:00

72 lines
2.4 KiB
Python

"""The ``livefeed`` tool: every packet as it arrives, right under the dashboard.
Opens the full-screen live feed (see :mod:`meshterm.ui.livefeed_screen`): the
streaming packet list that used to be the dashboard's bottom panel, promoted to its
own menu entry — newest first, every class, Enter opening any row in the shared
packet viewer. It sits directly under the dashboard because the two split one
question between them: the dashboard summarizes *what's going on out there*, the
feed shows every individual packet behind those numbers.
Menu-only: the feed is inherently live (it rides the event hub and repaints every
second), so there is no scripted one-shot to register — the ``monitor`` subcommand
covers scripted packet-watching.
"""
from __future__ import annotations
from typing import Any, Optional
import typer
from ..context import AppContext
from .base import Tool, ToolResult, register
@register
class LiveFeedTool(Tool):
"""Watch every packet stream in, newest first, and open any in the viewer."""
name = "livefeed"
title = "Live feed"
icon = "📰"
help = "Every packet as it arrives, newest first — open any in the viewer"
category = "Mesh"
order = 6 # right under the dashboard it was promoted out of
async def prompt_params(self, ctx: AppContext) -> Optional[dict[str, Any]]:
"""Run the live feed; there are never parameters to collect.
The screen presents everything itself and returns when dismissed, so
returning ``None`` tells the menu the invocation is complete (the same
pattern as the ``dashboard`` tool).
Args:
ctx: Shared application context.
Returns:
Always ``None``.
"""
from ..ui.livefeed_screen import open_livefeed
await open_livefeed(ctx)
return None
async def run(self, ctx: AppContext, params: dict[str, Any]) -> ToolResult:
"""Nothing runs here: the feed lives inside :meth:`prompt_params`.
Args:
ctx: Shared application context.
params: Unused.
Returns:
An empty :class:`ToolResult` (only reachable from a scripted call).
"""
return ToolResult(summary={})
def register_cli(self, app: typer.Typer) -> None:
"""Register no CLI command — the feed is a live, menu-only screen.
Args:
app: The Typer application (untouched).
"""