diff --git a/Cargo.toml b/Cargo.toml index 98da698..d3bd925 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -139,6 +139,11 @@ landlock = ["sandbox-landlock"] probe = ["dep:probe-rs"] # rag-pdf = PDF ingestion for datasheet RAG rag-pdf = ["dep:pdf-extract"] +# sandbox backends (optional, platform-specific) +sandbox-landlock = [] +sandbox-bubblewrap = [] +# native browser backend (optional, adds WebDriver dependency) +browser-native = [] [profile.release] opt-level = "z" # Optimize for size diff --git a/src/agent/mod.rs b/src/agent/mod.rs index 89406ef..93d1222 100644 --- a/src/agent/mod.rs +++ b/src/agent/mod.rs @@ -7,7 +7,7 @@ pub mod prompt; #[allow(unused_imports)] pub use agent::{Agent, AgentBuilder}; -pub use loop_::{process_message, run}; +pub use loop_::run; #[cfg(test)] mod tests { @@ -18,7 +18,6 @@ mod tests { #[test] fn run_function_is_reexported() { assert_reexport_exists(run); - assert_reexport_exists(process_message); assert_reexport_exists(loop_::run); assert_reexport_exists(loop_::process_message); } diff --git a/src/gateway/mod.rs b/src/gateway/mod.rs index 6301015..df500a5 100644 --- a/src/gateway/mod.rs +++ b/src/gateway/mod.rs @@ -810,7 +810,9 @@ mod tests { .requests .lock() .unwrap_or_else(std::sync::PoisonError::into_inner); - guard.1 = Instant::now() - Duration::from_secs(RATE_LIMITER_SWEEP_INTERVAL_SECS + 1); + guard.1 = Instant::now() + .checked_sub(Duration::from_secs(RATE_LIMITER_SWEEP_INTERVAL_SECS + 1)) + .unwrap(); // Clear timestamps for ip-2 and ip-3 to simulate stale entries guard.0.get_mut("ip-2").unwrap().clear(); guard.0.get_mut("ip-3").unwrap().clear(); diff --git a/src/memory/backend.rs b/src/memory/backend.rs index 4de636a..8ba7ec3 100644 --- a/src/memory/backend.rs +++ b/src/memory/backend.rs @@ -7,6 +7,7 @@ pub enum MemoryBackendKind { Unknown, } +#[allow(clippy::struct_excessive_bools)] #[derive(Debug, Clone, Copy, Eq, PartialEq)] pub struct MemoryBackendProfile { pub key: &'static str, diff --git a/src/memory/lucid.rs b/src/memory/lucid.rs index 00e03f6..9a0e84d 100644 --- a/src/memory/lucid.rs +++ b/src/memory/lucid.rs @@ -74,6 +74,7 @@ impl LucidMemory { } #[cfg(test)] + #[allow(clippy::too_many_arguments)] fn with_options( workspace_dir: &Path, local: SqliteMemory, diff --git a/src/memory/response_cache.rs b/src/memory/response_cache.rs index 3135b2b..e7fb3f2 100644 --- a/src/memory/response_cache.rs +++ b/src/memory/response_cache.rs @@ -166,7 +166,7 @@ impl ResponseCache { |row| row.get(0), )?; - #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)] Ok((count as usize, hits as u64, tokens_saved as u64)) } diff --git a/src/observability/mod.rs b/src/observability/mod.rs index 1093a4e..89284c1 100644 --- a/src/observability/mod.rs +++ b/src/observability/mod.rs @@ -6,11 +6,9 @@ pub mod traits; pub mod verbose; pub use self::log::LogObserver; -pub use self::multi::MultiObserver; pub use noop::NoopObserver; pub use otel::OtelObserver; pub use traits::{Observer, ObserverEvent}; -pub use verbose::VerboseObserver; use crate::config::ObservabilityConfig; diff --git a/src/onboard/wizard.rs b/src/onboard/wizard.rs index bf7c842..70e12c6 100644 --- a/src/onboard/wizard.rs +++ b/src/onboard/wizard.rs @@ -2271,14 +2271,11 @@ fn setup_memory() -> Result { let backend = backend_key_from_choice(choice); let profile = memory_backend_profile(backend); - let auto_save = if !profile.auto_save_default { - false - } else { - Confirm::new() + let auto_save = profile.auto_save_default + && Confirm::new() .with_prompt(" Auto-save conversations to memory?") .default(true) - .interact()? - }; + .interact()?; println!( " {} Memory: {} (auto-save: {})", diff --git a/src/peripherals/arduino_flash.rs b/src/peripherals/arduino_flash.rs index 8aaf287..7bc53f5 100644 --- a/src/peripherals/arduino_flash.rs +++ b/src/peripherals/arduino_flash.rs @@ -38,6 +38,10 @@ pub fn ensure_arduino_cli() -> Result<()> { anyhow::bail!("brew install arduino-cli failed. Install manually: https://arduino.github.io/arduino-cli/"); } println!("arduino-cli installed."); + if !arduino_cli_available() { + anyhow::bail!("arduino-cli still not found after install. Ensure it's in PATH."); + } + return Ok(()); } #[cfg(target_os = "linux")] @@ -54,11 +58,6 @@ pub fn ensure_arduino_cli() -> Result<()> { println!("arduino-cli not found. Install it: https://arduino.github.io/arduino-cli/"); anyhow::bail!("arduino-cli not installed."); } - - if !arduino_cli_available() { - anyhow::bail!("arduino-cli still not found after install. Ensure it's in PATH."); - } - Ok(()) } /// Ensure arduino:avr core is installed. diff --git a/src/peripherals/serial.rs b/src/peripherals/serial.rs index 05d0bae..2bcec56 100644 --- a/src/peripherals/serial.rs +++ b/src/peripherals/serial.rs @@ -112,6 +112,7 @@ pub struct SerialPeripheral { impl SerialPeripheral { /// Create and connect to a serial peripheral. + #[allow(clippy::unused_async)] pub async fn connect(config: &PeripheralBoardConfig) -> anyhow::Result { let path = config .path diff --git a/src/providers/mod.rs b/src/providers/mod.rs index 83fcda5..14d1b58 100644 --- a/src/providers/mod.rs +++ b/src/providers/mod.rs @@ -269,7 +269,7 @@ pub fn create_provider_with_url( "Groq", "https://api.groq.com/openai", key, AuthStyle::Bearer, ))), "mistral" => Ok(Box::new(OpenAiCompatibleProvider::new( - "Mistral", "https://api.mistral.ai", key, AuthStyle::Bearer, + "Mistral", "https://api.mistral.ai/v1", key, AuthStyle::Bearer, ))), "xai" | "grok" => Ok(Box::new(OpenAiCompatibleProvider::new( "xAI", "https://api.x.ai", key, AuthStyle::Bearer, diff --git a/src/security/pairing.rs b/src/security/pairing.rs index 806431b..2a828e1 100644 --- a/src/security/pairing.rs +++ b/src/security/pairing.rs @@ -184,7 +184,7 @@ fn generate_token() -> String { use rand::RngCore; let mut bytes = [0u8; 32]; rand::thread_rng().fill_bytes(&mut bytes); - format!("zc_{}", hex::encode(&bytes)) + format!("zc_{}", hex::encode(bytes)) } /// SHA-256 hash a bearer token for storage. Returns lowercase hex. diff --git a/src/tools/hardware_board_info.rs b/src/tools/hardware_board_info.rs index f7af262..73b30fc 100644 --- a/src/tools/hardware_board_info.rs +++ b/src/tools/hardware_board_info.rs @@ -124,10 +124,11 @@ impl Tool for HardwareBoardInfoTool { }); } Err(e) => { - output.push_str(&format!( - "probe-rs attach failed: {}. Using static info.\n\n", - e - )); + use std::fmt::Write; + let _ = write!( + output, + "probe-rs attach failed: {e}. Using static info.\n\n" + ); } } } @@ -135,13 +136,15 @@ impl Tool for HardwareBoardInfoTool { if let Some(info) = self.static_info_for_board(board) { output.push_str(&info); if let Some(mem) = memory_map_static(board) { - output.push_str(&format!("\n\n**Memory map:**\n{}", mem)); + use std::fmt::Write; + let _ = write!(output, "\n\n**Memory map:**\n{mem}"); } } else { - output.push_str(&format!( - "Board '{}' configured. No static info available.", - board - )); + use std::fmt::Write; + let _ = write!( + output, + "Board '{board}' configured. No static info available." + ); } Ok(ToolResult { diff --git a/src/tools/hardware_memory_map.rs b/src/tools/hardware_memory_map.rs index bdb4f96..41fd07b 100644 --- a/src/tools/hardware_memory_map.rs +++ b/src/tools/hardware_memory_map.rs @@ -122,14 +122,16 @@ impl Tool for HardwareMemoryMapTool { if !probe_ok { if let Some(map) = self.static_map_for_board(board) { - output.push_str(&format!("**{}** (from datasheet):\n{}", board, map)); + use std::fmt::Write; + let _ = write!(output, "**{board}** (from datasheet):\n{map}"); } else { + use std::fmt::Write; let known: Vec<&str> = MEMORY_MAPS.iter().map(|(b, _)| *b).collect(); - output.push_str(&format!( - "No memory map for board '{}'. Known boards: {}", - board, + let _ = write!( + output, + "No memory map for board '{board}'. Known boards: {}", known.join(", ") - )); + ); } }