From d61d4fbbedfd0e5bdbbe73cf58e9bfce2935c5b3 Mon Sep 17 00:00:00 2001 From: Jean-Pierre Martineau Date: Sat, 11 Jul 2026 18:49:02 -0400 Subject: [PATCH] Menu: split the crowded Mesh section, Messaging now leads Chat, Channels, and Courier move into their own Messaging section at the top; Mesh keeps the views over the mesh itself - Dashboard, Nodes, Map, Atlas, Watchtower, Send advert - dropping from nine rows to six. Co-Authored-By: Claude Fable 5 --- meshterm/tools/base.py | 11 ++++++----- meshterm/tools/channels.py | 2 +- meshterm/tools/chat.py | 2 +- meshterm/tools/courier.py | 4 ++-- meshterm/tools/nodes.py | 2 +- meshterm/tools/watchtower.py | 2 +- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/meshterm/tools/base.py b/meshterm/tools/base.py index 5ac7d7b..26f0c7c 100644 --- a/meshterm/tools/base.py +++ b/meshterm/tools/base.py @@ -149,11 +149,12 @@ class Tool(ABC): _REGISTRY: dict[str, Tool] = {} -#: Explicit menu ordering for tool categories. Mesh leads because it holds the -#: first-class, everyday features (chat, channels, the nodes and map views, adverts); -#: the rest follow in a natural workflow order. Categories not listed here sort last, -#: alphabetically, so a new category still appears. -_CATEGORY_ORDER = ["Mesh", "Device management", "Tools"] +#: Explicit menu ordering for tool categories. Messaging leads because it holds the +#: first-class, everyday features (chat, channels, the courier); Mesh follows with +#: the views over the mesh itself (dashboard, nodes, map, atlas, watchtower, +#: adverts); the rest in a natural workflow order. Categories not listed here sort +#: last, alphabetically, so a new category still appears. +_CATEGORY_ORDER = ["Messaging", "Mesh", "Device management", "Tools"] def _category_rank(category: str) -> int: diff --git a/meshterm/tools/channels.py b/meshterm/tools/channels.py index c11fbfd..6fb6ecc 100644 --- a/meshterm/tools/channels.py +++ b/meshterm/tools/channels.py @@ -38,7 +38,7 @@ class ChannelsTool(Tool): title = "Channels" icon = "📻" help = "Create, join, and share mesh channels (with QR codes)" - category = "Mesh" + category = "Messaging" order = 20 async def run(self, ctx: AppContext, params: dict[str, Any]) -> ToolResult: diff --git a/meshterm/tools/chat.py b/meshterm/tools/chat.py index 0b3a7a1..eab2625 100644 --- a/meshterm/tools/chat.py +++ b/meshterm/tools/chat.py @@ -46,7 +46,7 @@ class ChatTool(Tool): title = "Chat" icon = "💬" help = "Channel and direct messaging — live chat, with stored history" - category = "Mesh" + category = "Messaging" order = 10 async def prompt_params(self, ctx: AppContext) -> Optional[dict[str, Any]]: diff --git a/meshterm/tools/courier.py b/meshterm/tools/courier.py index 6ff53cb..e0f5d78 100644 --- a/meshterm/tools/courier.py +++ b/meshterm/tools/courier.py @@ -32,8 +32,8 @@ class CourierTool(Tool): title = "Courier" icon = "📨" help = "Store-and-forward outbox — deliver when the node is next heard" - category = "Mesh" - order = 12 # right after Chat: the same conversation, minus the waiting around + category = "Messaging" + order = 30 # after Chat and Channels: the same conversations, minus the waiting around async def prompt_params(self, ctx: AppContext) -> Optional[dict[str, Any]]: """Run the outbox screen; there are never parameters to collect. diff --git a/meshterm/tools/nodes.py b/meshterm/tools/nodes.py index 7b35094..7c2de3e 100644 --- a/meshterm/tools/nodes.py +++ b/meshterm/tools/nodes.py @@ -19,7 +19,7 @@ class NodesTool(Tool): icon = "👥" help = "List this node and known contacts (last heard, packets, type, key)" category = "Mesh" - order = 25 # between Channels and Map: the "who's out there" view + order = 10 # right under the Dashboard: the "who's out there" view async def run(self, ctx: AppContext, params: dict[str, Any]) -> ToolResult: """Query the device and render the node/contact list. diff --git a/meshterm/tools/watchtower.py b/meshterm/tools/watchtower.py index 08847a7..8ce0af6 100644 --- a/meshterm/tools/watchtower.py +++ b/meshterm/tools/watchtower.py @@ -31,7 +31,7 @@ class WatchtowerTool(Tool): icon = "🚨" help = "Alerts for watched nodes — silence, SNR sag, new arrivals" category = "Mesh" - order = 7 # right under the Dashboard: the section's other always-on eye + order = 35 # after the views: the section's always-on alerting eye async def prompt_params(self, ctx: AppContext) -> Optional[dict[str, Any]]: """Run the Watchtower screen; there are never parameters to collect.