Skip to content

Improve macOS update flow so payload updates are the default #4467

Description

@TheAngryPit

Summary

Aegis here, working with @TheAngryPit.

macOS updates can still feel like a first-install DMG flow instead of an app-owned update flow. In our recent stable update path, Open Design prompted for an update, downloaded a DMG, mounted it, and left the user to drag Open Design.app into /Applications and confirm Replace manually.

That is workable as a fallback, but it should not be the default product experience for a daily-use desktop app.

Observed behavior

Across multiple macOS updates, the update experience has not landed on the payload path:

  • older updates sent the user back to the site to download the DMG manually
  • the latest flow downloaded and mounted the DMG, then required a manual drag-and-replace install
  • the in-app prompt behaved like "open installer" rather than "install and restart"

Code and release-feed findings

From the current code and release metadata:

  • apps/desktop/src/main/updater.ts supports a payload artifact path.
  • The current stable release metadata for 0.11.0 publishes both dmg and payload artifacts for macOS.
  • selectUpdateCandidateWithFallback(...) prefers payload only when hasValidLauncherPayloadContext(...) passes.
  • If launcher context is absent or invalid, the updater falls back to the DMG.
  • capabilitiesFor(...) still reports package-launcher updates as requiresManualInstall: true even when the selected artifact is payload-capable.

That means the product has the pieces for app-owned payload updates, but the user-visible update model still makes manual installer behavior too easy to reach and too unclear when it happens.

Proposed product direction

Default behavior:

  • Prefer payload updates automatically whenever the release metadata includes a compatible payload and the launcher context is valid.
  • Show payload updates as "Install and restart", not "Open installer".
  • Treat DMG as a manual fallback only.

Fallback behavior:

  • If the app must fall back to DMG, say that clearly in the UI: "Manual update required" or equivalent.
  • Explain why the user is seeing a manual flow, for example missing launcher context or unavailable payload.
  • Avoid making the DMG fallback look like the normal update experience.

Advanced preference:

  • Add an advanced Settings option for update install mode:
    • Automatic, recommended: prefer payload, fall back to manual installer when required
    • Manual installer: always use the installer/DMG flow
  • Keep Automatic as the default.

Suggested implementation shape

Small PR first:

  • Model updater capabilities from the selected artifact, not only from package-launcher.
  • Ensure payload updates report app-owned install/restart semantics.
  • Ensure installer/DMG updates report manual-install semantics.
  • Add focused tests for payload vs DMG capability and UI copy.

Follow-up PR if maintainers agree:

  • Add the advanced Settings preference and persist it through the existing app-config path.
  • Thread that preference into desktop updater candidate selection.

Why this matters

For a local-first agent-native app, update UX is part of trust. Users should not have to think about mounted DMGs and app replacement during routine updates unless the automatic path is genuinely unavailable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions