Add a built-in update check with installer cleanup - #96
Open
manovotny wants to merge 4 commits into
Open
Conversation
Check the GitHub releases API for a newer version from "Check for Updates…" in the menu bar menu, and once a day automatically (opt-out in Advanced Settings). Updating downloads the signed installer package to the Downloads folder and opens it; on the first launch after the update, Capsomnia offers once to move the downloaded installer to the Trash. Only the latest version number is requested — no telemetry, no dependencies. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
manovotny
marked this pull request as draft
August 24, 2026 16:08
Writing to ~/Downloads triggers the macOS Downloads-folder privacy prompt on the first update. Downloading to Capsomnia's own caches folder avoids the prompt entirely, and since the file never lives in a user-facing location, the post-update Trash prompt becomes an automatic silent removal on the first launch after the update. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Quarantine downloaded installer packages before opening them so Installer runs them through Gatekeeper, and fail closed when the attribute cannot be set. - Keep the daily check honest: an hourly re-arming timer covers long-running sessions where the menu never opens, and an in-session attempt floor stops failed checks from retrying on every menu open. - Promote a manual "Check for Updates…" during an in-flight automatic check to user-initiated so its result still alerts. - Persist the last known release version so the "Update available" menu state survives a relaunch within the daily check window. - Surface installer-open failures instead of ignoring the result, and retry failed cache cleanups on the next launch instead of dropping the record. - Describe the network behavior precisely: the check reads GitHub's public release information and sends no telemetry or identifiers. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Download, quarantine, and Installer-launch failures now show a dedicated "Update failed" message instead of the check-failed one, which wrongly claimed GitHub was unreachable after the check had already succeeded. The quarantine DataURL property now passes a URL, matching the documented CFURLRef type. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
manovotny
marked this pull request as ready for review
August 24, 2026 17:01
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
New releases currently reach users only if they revisit the GitHub releases page — the app has no way to tell them an update exists. This adds an update check with zero dependencies and zero infrastructure: it reads the latest version from the GitHub releases API and compares it to the running one. Sparkle was considered and skipped on purpose — since Capsomnia updates through a signed, notarized .pkg with a privileged helper, the installer prompt is unavoidable either way, and Sparkle would add an embedded framework, an EdDSA key to manage, and appcast generation to the release process for little gain here.
Changes
Capsomnia-<version>.pkgto Capsomnia's own caches folder (~/Library/Caches/Capsomnia/), applies the quarantine attribute so Installer runs it through Gatekeeper (failing closed if the attribute can't be set), and opens it. The app-owned location avoids the macOS Downloads-folder privacy prompt, and no new signing material is introduced.UpdateCheckwith unit tests; side effects live inUpdateController. 108 tests passing overall.Notes for the maintainer
Nothing is required beyond review — no keys, no hosting, no release-process changes. The check does depend on two conventions RELEASING.md already documents: tags named
v<version>and aCapsomnia-<version>.pkgasset on each release. I verified both against the live API for v3.4.0.One behavior worth a conscious yes: the daily check is on by default (opt-out), which felt consistent with "Open at login" defaulting on. Happy to flip it to opt-in if you'd rather.
🤖 Generated with Claude Code