diff --git a/README.md b/README.md
index c918cf4..598622d 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ Backend server + browser interface for MeshCore mesh radio networks. Connect you
* Run multiple Python bots that can analyze messages and respond to DMs and channels
* Monitor unlimited contacts and channels (radio limits don't apply -- packets are decrypted server-side)
* Access your radio remotely over your network or VPN
-* Search for hashtag room names for channels you don't have keys for yet
+* Search for hashtag channel names for channels you don't have keys for yet
* Forward packets to MQTT, LetsMesh, MeshRank, SQS, Apprise, etc.
* Use the more recent 1.14 firmwares which support multibyte pathing
* Visualize the mesh as a map or node set, view repeater stats, and more!
diff --git a/README_ADVANCED.md b/README_ADVANCED.md
index f061324..64aba19 100644
--- a/README_ADVANCED.md
+++ b/README_ADVANCED.md
@@ -21,7 +21,7 @@ If the audit finds a mismatch, you'll see an error in the application UI and you
## HTTPS
-WebGPU room-finding requires a secure context when you are not on `localhost`.
+WebGPU channel-finding requires a secure context when you are not on `localhost`.
Generate a local cert and start the backend with TLS:
diff --git a/app/AGENTS.md b/app/AGENTS.md
index f87c8a8..105fe7f 100644
--- a/app/AGENTS.md
+++ b/app/AGENTS.md
@@ -101,7 +101,7 @@ app/
- Packet `path_len` values are hop counts, not byte counts.
- Hop width comes from the packet or radio `path_hash_mode`: `0` = 1-byte, `1` = 2-byte, `2` = 3-byte.
- Channel slot count comes from firmware-reported `DEVICE_INFO.max_channels`; do not hardcode `40` when scanning/offloading channel slots.
-- Channel sends use a session-local LRU slot cache after startup channel offload clears the radio. Repeated sends to the same room reuse the loaded slot; new rooms fill free slots up to the discovered channel capacity, then evict the least recently used cached room.
+- Channel sends use a session-local LRU slot cache after startup channel offload clears the radio. Repeated sends to the same channel reuse the loaded slot; new channels fill free slots up to the discovered channel capacity, then evict the least recently used cached channel.
- TCP radios do not reuse cached slot contents. For TCP, channel sends still force `set_channel(...)` before every send because this backend does not have exclusive device access.
- `MESHCORE_FORCE_CHANNEL_SLOT_RECONFIGURE=true` disables slot reuse on all transports and forces the old always-`set_channel(...)` behavior before every channel send.
- Contacts persist canonical direct-route fields (`direct_path`, `direct_path_len`, `direct_path_hash_mode`) so contact sync and outbound DM routing reuse the exact stored hop width instead of inferring from path bytes.
diff --git a/app/models.py b/app/models.py
index 214d884..cf91209 100644
--- a/app/models.py
+++ b/app/models.py
@@ -266,7 +266,7 @@ class ContactNameHistory(BaseModel):
class ContactActiveRoom(BaseModel):
- """A channel/room where a contact has been active."""
+ """A channel where a contact has been active."""
channel_key: str
channel_name: str
diff --git a/app/routers/channels.py b/app/routers/channels.py
index ca4de07..fb3f94f 100644
--- a/app/routers/channels.py
+++ b/app/routers/channels.py
@@ -71,7 +71,7 @@ async def create_channel(request: CreateChannelRequest) -> Channel:
requested_name = request.name
is_hashtag = requested_name.startswith("#")
- # Reserve the canonical Public room so it cannot drift to another key,
+ # Reserve the canonical Public channel so it cannot drift to another key,
# and the well-known Public key cannot be renamed to something else.
if is_public_channel_name(requested_name):
if request.key:
diff --git a/frontend/src/components/ChannelFloodScopeOverrideModal.tsx b/frontend/src/components/ChannelFloodScopeOverrideModal.tsx
index be8b097..11dbf71 100644
--- a/frontend/src/components/ChannelFloodScopeOverrideModal.tsx
+++ b/frontend/src/components/ChannelFloodScopeOverrideModal.tsx
@@ -45,8 +45,8 @@ export function ChannelFloodScopeOverrideModal({
For unknown-keyed GroupText packets, this will attempt to dictionary attack, then brute - force payloads as they arrive, testing room names up to the specified length to discover - active rooms on the local mesh (GroupText packets may not be hashtag messages; we have no + force payloads as they arrive, testing channel names up to the specified length to discover + active channels on the local mesh (GroupText packets may not be hashtag messages; we have no way of knowing but try as if they are). Retry failed at n+1 will let the cracker return to the failed queue and pick up messages it couldn't crack, attempting them at one longer length. @@ -613,8 +613,8 @@ export function CrackerPanel({ concatenated together (e.g. "hello" + "world" = "#helloworld") after the single-word dictionary pass; this can substantially increase search time and also result in false-positives. - Decrypt historical will run an async job on any room name it finds to see - if any historically captured packets will decrypt with that key. + Decrypt historical will run an async job on any channel name it finds to + see if any historically captured packets will decrypt with that key. Turbo mode will push your GPU to the max (target dispatch time of 10s) and may allow accelerated cracking and/or system instability.
diff --git a/frontend/src/components/NewMessageModal.tsx b/frontend/src/components/NewMessageModal.tsx index d44b282..bb2d91a 100644 --- a/frontend/src/components/NewMessageModal.tsx +++ b/frontend/src/components/NewMessageModal.tsx @@ -15,7 +15,7 @@ import { Checkbox } from './ui/checkbox'; import { Button } from './ui/button'; import { toast } from './ui/sonner'; -type Tab = 'new-contact' | 'new-room' | 'hashtag'; +type Tab = 'new-contact' | 'new-channel' | 'hashtag'; interface NewMessageModalProps { open: boolean; @@ -37,7 +37,7 @@ export function NewMessageModal({ const [tab, setTab] = useState
Not recommended; most companions normalize to lowercase
diff --git a/frontend/src/components/RawPacketDetailModal.tsx b/frontend/src/components/RawPacketDetailModal.tsx
index 73c633f..cc33a0d 100644
--- a/frontend/src/components/RawPacketDetailModal.tsx
+++ b/frontend/src/components/RawPacketDetailModal.tsx
@@ -161,7 +161,7 @@ function buildGroupTextResolutionCandidates(channels: Channel[]): GroupTextResol
}));
}
-function resolveGroupTextRoomName(
+function resolveGroupTextChannelName(
payload: {
channelHash?: string;
cipherMac?: string;
@@ -211,15 +211,15 @@ function getPacketContext(
groupTextCandidates: GroupTextResolutionCandidate[]
) {
const fallbackSender = packet.decrypted_info?.sender ?? null;
- const fallbackRoom = packet.decrypted_info?.channel_name ?? null;
+ const fallbackChannel = packet.decrypted_info?.channel_name ?? null;
if (!inspection.decoded?.payload.decoded) {
- if (!fallbackSender && !fallbackRoom) {
+ if (!fallbackSender && !fallbackChannel) {
return null;
}
return {
- title: fallbackRoom ? 'Room' : 'Context',
- primary: fallbackRoom ?? 'Sender metadata available',
+ title: fallbackChannel ? 'Channel' : 'Context',
+ primary: fallbackChannel ?? 'Sender metadata available',
secondary: fallbackSender ? `Sender: ${fallbackSender}` : null,
};
}
@@ -231,11 +231,12 @@ function getPacketContext(
ciphertext?: string;
decrypted?: { sender?: string; message?: string };
};
- const roomName = fallbackRoom ?? resolveGroupTextRoomName(payload, groupTextCandidates);
+ const channelName =
+ fallbackChannel ?? resolveGroupTextChannelName(payload, groupTextCandidates);
return {
- title: roomName ? 'Room' : 'Channel',
+ title: 'Channel',
primary:
- roomName ?? (payload.channelHash ? `Channel hash ${payload.channelHash}` : 'GroupText'),
+ channelName ?? (payload.channelHash ? `Channel hash ${payload.channelHash}` : 'GroupText'),
secondary: payload.decrypted?.sender
? `Sender: ${payload.decrypted.sender}`
: fallbackSender
diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx
index d6b7bae..178937e 100644
--- a/frontend/src/components/Sidebar.tsx
+++ b/frontend/src/components/Sidebar.tsx
@@ -748,7 +748,7 @@ export function Sidebar({
icon: