Add a "check for updates" button to Settings → App - #31
Merged
MyNamesEMurray merged 1 commit intoSep 7, 2026
Merged
Conversation
Updating was launch-only: if you left the app running in the tray for a week -- which is what a tray app is for -- there was no way to ask. The button relays to the host's updater rather than building a second update path, so finding, downloading, and the restart prompt are the same flow the automatic check already uses. It reports what happened in every case: downloading, already downloaded and waiting on a restart, or already current, with the version. A tray app that answers a button with silence is indistinguishable from a broken one, and a failed check must never read as "you're up to date". Two behaviours worth naming: Automatic updates being off no longer disables the machinery, only the check at launch. The updater's listeners are wired on any packaged build, because a manual check that found an update and then did nothing with it would be worse than no button. Asking by hand also clears a skip marker. "Skip this update" means stop telling me about it; clicking Check for updates is asking about that version too, so answering "you're on the latest" would be a lie. Only a packaged build can update itself, so running from source passes no hook and the row stays hidden rather than being offered and then refused. The endpoint still answers there, which is what the smoke test asserts. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LWa54BF5RjHWC5GFaENZMM
MyNamesEMurray
enabled auto-merge
September 7, 2026 02:49
MyNamesEMurray
deleted the
claude/live-mic-transcription-accuracy-x5ptio
branch
September 7, 2026 02:50
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
Updating was launch-only. Leave the app running in the tray for a week — which is what a tray app is for — and there was no way to ask whether a new version exists. Settings → App now has one.
Changes
The button relays to the host's updater rather than building a second update path, so finding, downloading and the restart prompt are all the flow the automatic check already uses. It reports what happened in every case — downloading, already downloaded and waiting on a restart, already current — with the version. A tray app that answers a button with silence is indistinguishable from a broken one, and a failed check must never read as "you're up to date".
Two behaviours worth calling out for review:
autoUpdate !== falsebranch, so with automatic updates off a manual check would have found an update and then done nothing with it.UpdateSkipholds exactly one marker, so this is its existingclear().Only a packaged build can update itself, so running from source passes no hook and the row stays hidden rather than being offered and then refused. The endpoint still answers there, with a sentence saying why.
Verification
node --checkover every JS file,config.example.jsonparse,npm test(161 pass, 0 fail, 1 pre-existing Windows-only SAPI skip),npm run smoke→ SMOKE OK.scripts/smoke.mjsnow assertsPOST /api/update/checkanswers 200 withok:falseand a reason when no host is attached — the headless case, where the endpoint must neither hang nor 500.checkUpdateshook, since Electron can't run in this environment:current→{"state":"current","version":"3.8.2"},downloading→{"state":"downloading","version":"3.9.0"},downloaded,starting, and a throwing hook →{"ok":false,"error":"net::ERR_INTERNET_DISCONNECTED"}.canCheckUpdates, the button disables while in flight and re-enables after, and the result renders as "✓ v3.9.0 found — downloading now. You'll be asked to restart when it's ready." No console errors beyond the known/favicon.ico404.What I could not verify here: the packaged path — a real
autoUpdater.checkForUpdates()against GitHub Releases, the skip-clearing, and the restart dialog — needs a packaged Windows build. The host-side logic is small and reviewable, but it is the part that has not been run.Risk & rollout
app.autoUpdateandapp.updateChannelkeep their meanings;autoUpdate: falsenow means "don't check at launch" rather than "don't wire the updater at all", which is the intended widening.update-available/update-downloadedhandlers attached. The launch-time check remains gated, so a user who turned updates off is still never prompted unless they ask.src/server.jsgains one endpoint that only relays; the server still imports nothing from Electron.Checklist
npm run smokepasses locally (or CI is green)main🤖 Generated with Claude Code
https://claude.ai/code/session_01LWa54BF5RjHWC5GFaENZMM
Generated by Claude Code