diff --git a/desktop/public/mesh-buddy.html b/desktop/public/mesh-buddy.html
new file mode 100644
index 0000000000..b9bcbee6b3
--- /dev/null
+++ b/desktop/public/mesh-buddy.html
@@ -0,0 +1,63 @@
+
+
+
+
+ Mesh Buddy
+
+
+
+
+
🙂
+
0
+
tokens helped compute
+
+
+
+
diff --git a/desktop/src-tauri/capabilities/default.json b/desktop/src-tauri/capabilities/default.json
index a2e09bcb33..86b9277cf1 100644
--- a/desktop/src-tauri/capabilities/default.json
+++ b/desktop/src-tauri/capabilities/default.json
@@ -2,7 +2,7 @@
"$schema": "../gen/schemas/desktop-schema.json",
"identifier": "default",
"description": "Capability for the main window and trusted huddle companions",
- "windows": ["main", "huddle-*"],
+ "windows": ["main", "huddle-*", "mesh-buddy"],
"permissions": [
"core:default",
"core:webview:allow-set-webview-zoom",
diff --git a/desktop/src-tauri/src/commands/mesh_buddy_window.rs b/desktop/src-tauri/src/commands/mesh_buddy_window.rs
new file mode 100644
index 0000000000..d3303ecfff
--- /dev/null
+++ b/desktop/src-tauri/src/commands/mesh_buddy_window.rs
@@ -0,0 +1,36 @@
+//! Mesh Buddy — a small square companion window showing a smiley and how many
+//! completion tokens this machine has served to the community mesh.
+//!
+//! The window is chrome only: it loads the static `mesh-buddy.html` page,
+//! which polls the existing read-only `mesh_serving_usage` command. No new
+//! trust surface — the page reads the same counters the Share compute card
+//! already shows.
+
+use tauri::{Manager, WebviewUrl, WebviewWindowBuilder};
+
+const MESH_BUDDY_LABEL: &str = "mesh-buddy";
+
+/// Open (or re-focus) the Mesh Buddy window.
+pub fn open_mesh_buddy_window_impl(app: &tauri::AppHandle) -> Result<(), String> {
+ if let Some(window) = app.get_webview_window(MESH_BUDDY_LABEL) {
+ window.show().map_err(|error| error.to_string())?;
+ window.set_focus().map_err(|error| error.to_string())?;
+ return Ok(());
+ }
+ WebviewWindowBuilder::new(
+ app,
+ MESH_BUDDY_LABEL,
+ WebviewUrl::App("mesh-buddy.html".into()),
+ )
+ .title("Mesh Buddy")
+ .inner_size(320.0, 320.0)
+ .resizable(false)
+ .build()
+ .map_err(|error| error.to_string())?;
+ Ok(())
+}
+
+#[tauri::command]
+pub fn open_mesh_buddy_window(app: tauri::AppHandle) -> Result<(), String> {
+ open_mesh_buddy_window_impl(&app)
+}
diff --git a/desktop/src-tauri/src/commands/mesh_llm.rs b/desktop/src-tauri/src/commands/mesh_llm.rs
index 7356cd7fc0..13a116e67e 100644
--- a/desktop/src-tauri/src/commands/mesh_llm.rs
+++ b/desktop/src-tauri/src/commands/mesh_llm.rs
@@ -399,6 +399,7 @@ pub(crate) async fn restore_mesh_sharing(app: &AppHandle, state: &AppState) -> C
);
}
mesh_llm::publish_current_status_once(app, "restore").await;
+ open_mesh_buddy_on_main_thread(app);
Ok(())
}
@@ -528,9 +529,24 @@ pub async fn mesh_start_node(
}
}
mesh_llm::publish_current_status_once(&app, "start").await;
+ if sharing_config.is_some() {
+ open_mesh_buddy_on_main_thread(&app);
+ }
Ok(status)
}
+/// Pop the Mesh Buddy companion when this machine starts serving. Window
+/// creation must not run on an async worker on macOS, so hop to main.
+fn open_mesh_buddy_on_main_thread(app: &AppHandle) {
+ let handle = app.clone();
+ let _ = app.run_on_main_thread(move || {
+ if let Err(error) = crate::commands::mesh_buddy_window::open_mesh_buddy_window_impl(&handle)
+ {
+ eprintln!("buzz-mesh: failed to open mesh buddy window: {error}");
+ }
+ });
+}
+
pub(crate) async fn ensure_client_node_for_model(
state: &AppState,
model_id: impl AsRef,
diff --git a/desktop/src-tauri/src/commands/mod.rs b/desktop/src-tauri/src/commands/mod.rs
index 7cb2d8e3b8..ec0c2be6b9 100644
--- a/desktop/src-tauri/src/commands/mod.rs
+++ b/desktop/src-tauri/src/commands/mod.rs
@@ -35,6 +35,7 @@ mod media_raw;
mod media_snapshot_png;
mod media_transcode;
mod media_upload_progress;
+pub(crate) mod mesh_buddy_window;
#[cfg(feature = "mesh-llm")]
pub(crate) mod mesh_llm;
#[cfg(feature = "mesh-llm")]
diff --git a/desktop/src-tauri/src/lib.rs b/desktop/src-tauri/src/lib.rs
index 71a5eb3806..7be2d2ed50 100644
--- a/desktop/src-tauri/src/lib.rs
+++ b/desktop/src-tauri/src/lib.rs
@@ -717,6 +717,7 @@ pub fn run() {
mesh_serving_usage,
mesh_installed_models,
mesh_model_catalog,
+ commands::mesh_buddy_window::open_mesh_buddy_window,
update_managed_agent,
discover_backend_providers,
probe_backend_provider,