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,