feat(mesh): server name in adverts + clear-all button + CI fix

- Mesh adverts now use the node's configured server name (e.g. "ThinkPad",
  "Arch Dev") instead of DID key fragments ("Archy-z6MkmkSB")
- Added mesh.clear-all RPC to reset peers, messages, contacts, and history
- Added "Clear All" button in Mesh UI peers panel
- Both glibc and musl builds verified

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dorian
2026-04-18 11:53:06 -04:00
co-authored by Claude Opus 4.6
parent 0c02d06a66
commit 1736f6f99e
7 changed files with 86 additions and 6 deletions
@@ -319,6 +319,7 @@ impl RpcHandler {
"mesh.send-channel-invite" => self.handle_mesh_send_channel_invite(params).await,
"conversations.list" => self.handle_conversations_list(params).await,
"conversations.messages" => self.handle_conversations_messages(params).await,
"mesh.clear-all" => self.handle_mesh_clear_all().await,
"mesh.outbox" => self.handle_mesh_outbox(params).await,
"mesh.session-status" => self.handle_mesh_session_status(params).await,
"mesh.rotate-prekeys" => self.handle_mesh_rotate_prekeys().await,
@@ -215,4 +215,39 @@ impl RpcHandler {
}))
}
}
/// mesh.clear-all — Clear all peers, messages, contacts, and presence data.
/// Resets the mesh state to a fresh start while keeping the device connected.
pub(in crate::api::rpc) async fn handle_mesh_clear_all(&self) -> Result<serde_json::Value> {
let service = self.mesh_service.read().await;
if let Some(svc) = service.as_ref() {
let state = svc.state();
// Clear peers (except synthetic federation peers)
state.peers.write().await.clear();
// Clear all messages
state.messages.write().await.clear();
// Clear contacts
state.contacts.write().await.clear();
// Clear presence
state.presence.write().await.clear();
// Clear chunk buffer
state.chunk_buffer.write().await.clear();
// Re-seed federation peers
let data_dir = self.config.data_dir.clone();
crate::mesh::seed_federation_peers_into_mesh(state, &data_dir).await;
// Delete persisted messages file
let msg_file = data_dir.join("messages.json");
let _ = tokio::fs::remove_file(&msg_file).await;
// Delete persisted contacts file
let contacts_file = data_dir.join("mesh-contacts.json");
let _ = tokio::fs::remove_file(&contacts_file).await;
// Trigger a contact refresh from the radio device
let _ = state.send_cmd(
crate::mesh::listener::MeshCommand::RefreshContacts,
).await;
Ok(serde_json::json!({ "status": "cleared" }))
} else {
Ok(serde_json::json!({ "status": "no_service" }))
}
}
}