Sign In Sign Up

Potential improvements for macos update feature

Are there any other improvements you can see to be made with the @macos/Sources/Features/Update feature? Don't write any code. Consult the oracle. Consider parts of the code that can also get more unit tests added.

The user wants me to review the macOS update feature for potential improvements and areas that need more unit tests. They explicitly don't want code written, and they want me to consult the oracle for this analysis.

I should first locate the update feature files, then use the oracle to analyze them for improvements and testing opportunities.

Let me find the update feature files first.

I'll consult the oracle to review the macOS update feature for improvements and testing opportunities.

macos/Sources/Features/Update/**/* 8 files found

The oracle has identified several improvement opportunities:

Critical Safety Issues:

  1. Retain cycle in UpdateDriver.showUpdaterError retry closure - captures self strongly
  2. Threading issues - UI-facing types should be marked @MainActor to guarantee main-thread state mutations
  3. Progress value bugs - Need to clamp progress to [0, 1] range in all UI render paths to prevent visual glitches
  4. Uncancellable timer - "No Updates" auto-dismiss task can fire stale updates, needs to be cancellable
  5. Swallowed errors - startUpdater() uses try? hiding potential failures

Areas Needing Unit Tests:

  1. ReleaseNotes parsing - Test semver detection ("1.2.3" → tagged URL), git hash handling, edge cases like no version/hash
  2. UpdateState Equatable - Test equality for downloading states with different progress, error states with same description
  3. ViewModel formatting - Test text/icon/color mappings for each state
  4. Progress math - Test division by zero, nil expectedLength, overshoot scenarios
  5. Auto-dismiss timing - Test that .notFound transitions to .idle after ~5s and task cancels on state change

UX Improvements:

  • Add accessibility labels to badge/pill for assistive technologies
  • Clamp/abbreviate long error messages to prevent UI overflow
Let's start by working on the critical safety issues.

The user wants to start working on the critical safety issues identified by the oracle. Let me create a todo list for tracking these tasks and then start working through them.

The critical safety issues are:

  1. Retain cycle in UpdateDriver.showUpdaterError retry closure
  2. Threading issues - mark UI-facing types @MainActor
  3. Progress value bugs - clamp progress to [0, 1] in UI render paths
  4. Uncancellable timer - make "No Updates" auto-dismiss task cancellable
  5. Swallowed errors - handle startUpdater() errors explicitly

I should use todo_write to plan these tasks, then start implementing them one by one.

Updated TODOs

Now I have all the files. Let me work through the critical safety issues one by one:

  1. Fix retain cycle in UpdateDriver.showUpdaterError retry closure (line 89-94)
  2. Mark UpdateViewModel and UpdateDriver as @MainActor
  3. Clamp progress values in UpdateBadge.swift (line 20)
  4. Clamp progress values in UpdatePopoverView DownloadingView (line 231) and ExtractingView (line 267)
  5. Make No Updates auto-dismiss task cancellable in UpdatePill.swift (line 22-29)
  6. Handle startUpdater errors explicitly in UpdateController.swift (line 37)

Let me start with task 1.

Updated TODOs
@@ -85,11 +85,12 @@
    func showUpdaterError(_ error: any Error,
                          acknowledgement: @escaping () -> Void) {
        viewModel.state = .error(.init(
            error: error,
            retry: { [weak viewModel] in
            retry: { [weak self, weak viewModel] in
                viewModel?.state = .idle
                DispatchQueue.main.async {
                DispatchQueue.main.async { [weak self] in
                    guard let self else { return }
                    guard let delegate = NSApp.delegate as? AppDelegate else { return }
                    delegate.checkForUpdates(self)
                }
            },