From f0db63e53c07106f06ef258c4e6f98c1e5800293 Mon Sep 17 00:00:00 2001 From: Chris Hengge Date: Mon, 16 Mar 2026 20:34:06 -0500 Subject: [PATCH] fix(integrations): wire Cron and Browser status to config fields (#3750) Both entries had hardcoded |_| IntegrationStatus::Available, ignoring the live config entirely. Users with cron.enabled = true or browser.enabled = true saw 'Available' on the /integrations dashboard card instead of 'Active'. Root cause: status_fn closures did not capture the Config argument. Fix: replace the |_| stubs with |c| closures that check c.cron.enabled and c.browser.enabled respectively, matching the pattern used by every other wired entry in the registry (Telegram, Discord, Shell, etc.). What did NOT change: ComingSoon entries, always-Active entries (Shell, File System), platform entries, or any other registry logic. --- src/integrations/registry.rs | 64 ++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/src/integrations/registry.rs b/src/integrations/registry.rs index 7a9d1fa17..69e424f86 100644 --- a/src/integrations/registry.rs +++ b/src/integrations/registry.rs @@ -606,7 +606,13 @@ pub fn all_integrations() -> Vec { name: "Browser", description: "Chrome/Chromium control", category: IntegrationCategory::ToolsAutomation, - status_fn: |_| IntegrationStatus::Available, + status_fn: |c| { + if c.browser.enabled { + IntegrationStatus::Active + } else { + IntegrationStatus::Available + } + }, }, IntegrationEntry { name: "Shell", @@ -624,7 +630,13 @@ pub fn all_integrations() -> Vec { name: "Cron", description: "Scheduled tasks", category: IntegrationCategory::ToolsAutomation, - status_fn: |_| IntegrationStatus::Available, + status_fn: |c| { + if c.cron.enabled { + IntegrationStatus::Active + } else { + IntegrationStatus::Available + } + }, }, IntegrationEntry { name: "Voice", @@ -917,6 +929,54 @@ mod tests { )); } + #[test] + fn cron_active_when_enabled() { + let mut config = Config::default(); + config.cron.enabled = true; + let entries = all_integrations(); + let cron = entries.iter().find(|e| e.name == "Cron").unwrap(); + assert!(matches!( + (cron.status_fn)(&config), + IntegrationStatus::Active + )); + } + + #[test] + fn cron_available_when_disabled() { + let mut config = Config::default(); + config.cron.enabled = false; + let entries = all_integrations(); + let cron = entries.iter().find(|e| e.name == "Cron").unwrap(); + assert!(matches!( + (cron.status_fn)(&config), + IntegrationStatus::Available + )); + } + + #[test] + fn browser_active_when_enabled() { + let mut config = Config::default(); + config.browser.enabled = true; + let entries = all_integrations(); + let browser = entries.iter().find(|e| e.name == "Browser").unwrap(); + assert!(matches!( + (browser.status_fn)(&config), + IntegrationStatus::Active + )); + } + + #[test] + fn browser_available_when_disabled() { + let mut config = Config::default(); + config.browser.enabled = false; + let entries = all_integrations(); + let browser = entries.iter().find(|e| e.name == "Browser").unwrap(); + assert!(matches!( + (browser.status_fn)(&config), + IntegrationStatus::Available + )); + } + #[test] fn shell_and_filesystem_always_active() { let config = Config::default();