Skip to content

Add an opt-in weekly update check - #74

Open
L-K-M wants to merge 1 commit into
mainfrom
claude/opus-auto-update
Open

Add an opt-in weekly update check#74
L-K-M wants to merge 1 commit into
mainfrom
claude/opus-auto-update

Conversation

@L-K-M

@L-K-M L-K-M commented Jul 25, 2026

Copy link
Copy Markdown
Owner

FEAT-2 shipped the manual "Check for Updates…" item and left the automatic check as a documented follow-up. This is it. Entry FEAT-3 in opus.md.

It matters more for Alan than for most apps, and for a reason specific to this fork: an ad-hoc-signed update can reset the Accessibility grant, so the users most likely to be running a stale build overlap almost exactly with the users who once watched Alan quietly stop drawing borders and never worked out why. A menu-bar utility with its Dock icon hidden can otherwise run a year-old build indefinitely, with nothing ever prompting a look.

Shape

Off by default, weekly, and quiet. The asymmetry with the manual check is deliberate: there, explicit feedback is the entire point — "you're up to date" is the answer that was asked for. Here nobody asked, so both "up to date" and "couldn't reach GitHub" are correctly silent, and the only thing that earns an interruption is a newer version the user hasn't already skipped. The alert offers Download… / Later / Skip This Version; skipping suppresses that one version only, and never affects the manual check.

Mechanics worth reviewing

  • The check timestamp is written before the request, whichever way it goes, so a machine that's offline for a week doesn't retry on every poll.
  • A stamp in the future — a clock that moved backwards, a hand-edited plist — counts as due, rather than suppressing every check until the clock catches up.
  • The first check waits a minute after launch so it can't land on top of the Accessibility permission flow, and both the request and the alert refuse to start while a modal session is up. If a modal appears while a request is out, the alert waits for it rather than nesting a second session inside the permission flow's runModal loop (the same hazard handlingTrustLoss already guards) — or losing the news for a week, since the timestamp is already recorded.
  • The timer only offers a check every six hours, with a 30-minute tolerance so the system can coalesce the wake-up; the weekly gate lives in UpdateChecker.automaticCheckIfDue, which means a rarely-restarted Mac behaves like one rebooted daily.

Merge note

If #73 lands first: add Key.autoCheckUpdates to Key.allStoredKeys so "Restore Defaults" clears it (lastUpdateCheck and skippedUpdateVersion are internal state and are fine either way), and if #72 lands first, move this checkbox into its "General" section of the Behavior tab.

Testing

Not compiled — authored without Xcode; CI builds this. Network behavior can't be exercised off-device either, but the exposure is bounded: the feature is off unless the user turns it on, the request is the same one the shipped manual check already makes, and every failure path is silent.


Generated by Claude Code

FEAT-2 shipped the manual "Check for Updates…" item and left the automatic
check as a documented follow-up. This is it.

It matters more for Alan than for most apps, and for a reason specific to
this fork: an ad-hoc-signed update can reset the Accessibility grant, so the
users most likely to be running a stale build overlap almost exactly with
the users who once watched Alan quietly stop drawing borders and never
worked out why. A menu-bar utility with its Dock icon hidden can otherwise
run a year-old build forever, with nothing ever prompting a look.

Off by default, weekly, and quiet. The asymmetry with the manual check is
deliberate: there, explicit feedback is the entire point — "you're up to
date" is the answer that was asked for. Here nobody asked, so both "up to
date" and "couldn't reach GitHub" are correctly silent, and the only thing
that earns an interruption is a newer version the user hasn't already
skipped. The alert offers Download / Later / Skip This Version; skipping
suppresses that one version only, and never affects the manual check.

Mechanics worth noting:

- The check timestamp is written *before* the request, whichever way it
  goes, so a machine that's offline for a week doesn't retry on every poll.
- A stamp in the future (a clock that moved backwards, a hand-edited plist)
  counts as due rather than suppressing every check until the clock catches
  up.
- The first check waits a minute after launch so it can't land on top of the
  Accessibility permission flow, and both the request and the alert refuse
  to start while a modal session is up. If a modal appears while a request
  is out, the alert waits for it rather than nesting a second session or
  losing the news for a week.
- The timer only *offers* a check every six hours (with a 30-minute
  tolerance, so the system can coalesce the wake-up); the weekly gate lives
  in UpdateChecker, which means a rarely-restarted Mac behaves like one
  rebooted daily.

Merge note: if #status-menu lands first, add Key.autoCheckUpdates to
Key.allStoredKeys so "Restore Defaults" clears it (lastUpdateCheck and
skippedUpdateVersion are internal state and are fine either way), and move
this checkbox into that branch's "General" section of the Behavior tab.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GquohA7BzXxdMSQ5kPp9Ru
@github-actions

Copy link
Copy Markdown

GLM 5.2 Code Review

Actionable suggestions identified: 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants