Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/cortex-tui/src/runner/app_runner/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,7 @@ impl AppRunner {
// 2. Background update check task - check for new versions without blocking startup
let update_check_task = tokio::spawn(async move {
match UpdateManager::new() {
Ok(manager) => match manager.check_update().await {
Ok(mut manager) => match manager.check_update_for_notification().await {
Ok(info) => info,
Err(e) => {
tracing::debug!("Update check failed: {}", e);
Expand Down
27 changes: 27 additions & 0 deletions src/cortex-update/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,4 +145,31 @@ impl UpdateConfig {
pub fn is_version_skipped(&self, version: &str) -> bool {
self.skip_version.as_deref() == Some(version)
}

/// Check if the user has already been notified about a version.
pub fn is_version_notified(&self, version: &str) -> bool {
self.last_notified_version.as_deref() == Some(version)
}

/// Remember that the user has been notified about a version.
pub fn mark_version_notified(&mut self, version: &str) {
self.last_notified_version = Some(version.to_string());
}
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn tracks_last_notified_version() {
let mut config = UpdateConfig::default();

assert!(!config.is_version_notified("1.2.3"));

config.mark_version_notified("1.2.3");

assert!(config.is_version_notified("1.2.3"));
assert!(!config.is_version_notified("1.2.4"));
}
}
23 changes: 23 additions & 0 deletions src/cortex-update/src/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,29 @@ impl UpdateManager {
self.check_update_forced().await
}

/// Check for an update that should be shown as a user notification.
///
/// This suppresses repeat notifications for the same latest version while
/// leaving the regular update check behavior unchanged for explicit update
/// commands and install flows.
pub async fn check_update_for_notification(&mut self) -> UpdateResult<Option<UpdateInfo>> {
let info = match self.check_update().await? {
Some(info) => info,
None => return Ok(None),
};

if self.config.is_version_notified(&info.latest_version) {
return Ok(None);
}

self.config.mark_version_notified(&info.latest_version);
if let Err(e) = self.config.save() {
tracing::warn!("Failed to save update notification state: {}", e);
}

Ok(Some(info))
}

/// Force check for updates (bypass cache).
pub async fn check_update_forced(&self) -> UpdateResult<Option<UpdateInfo>> {
let latest = self.client.get_latest(self.config.channel).await?;
Expand Down