Skip to content

feat: add desktop auto-update flow#119

Draft
juacker wants to merge 6 commits into
mainfrom
feat/auto-update
Draft

feat: add desktop auto-update flow#119
juacker wants to merge 6 commits into
mainfrom
feat/auto-update

Conversation

@juacker

@juacker juacker commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add a persisted auto-update setting, enabled by default, with About settings UI for support status, manual checks, and install/restart.
  • Add backend updater commands, startup background checks, update-available events, install progress events, and platform/package support detection.
  • Gate unsupported/external package flows such as dev builds, Flatpak, mismatched Linux package-manager installs, and missing native bundle metadata.
  • Serialize ts-rs binding generation to avoid parallel export tests truncating src/generated/bindings.ts.

Verification

  • cargo test --lib -- --test-threads=1 (826 tests)
  • cargo fmt --check
  • cargo check
  • cargo test --lib app_updates
  • npm run gen:bindings
  • npm run typecheck
  • npm run lint
  • npm run build
  • npm test (179 tests; existing act/canvas warnings)
  • git diff --check HEAD

Review

  • Independent final source-only review: production_quality, no blocker/major findings.
  • Fixed validated reviewer findings: About toggle save rollback race and unbounded artifact download timeout.

Notes

  • macOS updater availability still depends on release metadata publishing darwin-* updater entries.
  • Flatpak and package-manager-managed installs report as externally managed instead of attempting native self-update.

juacker added 2 commits July 23, 2026 15:13
Flatpak bundles are side-loaded (no origin remote), so Flatpak never
updates them and the self-updater must not install a .deb inside the
sandbox. Instead of staying silent, the flatpak channel now fetches the
release manifest (latest.json), compares versions numerically, and
surfaces a non-installable update: the toast and About panel show a
'View release' link to GitHub Releases instead of 'Install and restart'.

- AppUpdateSupportStatus.canCheck: check-capable superset of supported
- AppUpdateInfo.installable: false for notify-only updates
- package_manager channel (e.g. AUR) stays silent: those installs do
  receive updates through their repo
@juacker

juacker commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

Added notify-only update checks for Flatpak builds (372f908): CLAI's Flatpak is a side-loaded bundle with no origin remote, so Flatpak itself never updates it. The flatpak channel now fetches the release manifest, compares versions, and shows a non-installable 'View release' notification instead of staying silent. deb/rpm/MSI/NSIS keep the full self-install flow; package-manager installs (AUR) stay silent since their repo delivers updates. Independent review round 3: production_quality.

A dismissible toast alone is easy to miss or dismiss and forget. Add a
persistent 'Update available · vX' pill next to the settings gear that
stays visible until the update is applied, and opens Settings > About
(which hosts the install / view-release controls) on click.

- new useAvailableAppUpdate hook shares the status-seed + event
  subscription between the toast and the badge
- toast dismissal is now keyed by version: dismissing v1 keeps it
  hidden for v1, but a later v2 re-surfaces it
- badge covers both installable and notify-only channels
- 4 unit tests for the badge (empty, seeded, event-driven, click)
@juacker

juacker commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator Author

Added a persistent update indicator in the fleet top bar (2e8fba0), per feedback that a dismissible toast alone is too easy to miss:

  • AppUpdateBadge: an "Update available · vX" pill next to the settings gear, visible until the update is applied. Click opens Settings → About (which hosts install / view-release controls). Covers both installable and notify-only (Flatpak) channels.
  • useAvailableAppUpdate hook shared by badge and toast: seeds from get_app_update_status, follows app-updates://available; live events win over the seed.
  • Toast dismissal is now version-keyed: dismissing v1 stays dismissed for v1, a later v2 re-surfaces it. Install error/progress state resets when a new version arrives.
  • Manual checks now emit the update event too, so an update found via Settings → About surfaces the badge — the user is always aware, however the update was discovered.
  • 4 new unit tests for the badge.

Validation: cargo fmt/clippy -D warnings, 829 lib tests, tsc, eslint, prettier, 183 vitest, vite build — all green. Independent review rounds 4+5: production_quality, no open findings.

- Checking for updates is now always on (cheap anonymous manifest fetch);
  the autoUpdate.enabled setting is replaced by autoUpdate.autoDownload
  (default on).
- When auto-download is enabled on a self-update-capable build, the update
  package is downloaded in the background after any check that finds one
  (startup or manual); the badge/toast flip to 'Update ready — restart to
  apply' and install reuses the cached, signature-verified bytes.
- The Settings > About toggle becomes 'Automatically download updates' and
  only renders on builds that can self-update; notify-only builds (Flatpak)
  keep the badge/toast with no dead setting.
@juacker

juacker commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator Author

Reworked the settings model per feedback (7ba055f):

  • Checking for updates is now always on — no setting. It's a cheap anonymous manifest fetch; the user must at least learn an update exists (notify-only builds like Flatpak included).
  • autoUpdate.enabledautoUpdate.autoDownload (default on). When enabled on a self-update-capable build, the package is downloaded in the background after any check that finds one; the badge/toast flip to "Update ready — restart to apply" and install reuses the cached, signature-verified bytes.
  • The Settings → About toggle ("Automatically download updates") only renders on builds that can self-update — no dead toggle on Flatpak/notify-only installs.

Validation: cargo clippy -D warnings, 834 backend tests (+5), tsc/eslint/prettier, 185 frontend tests (+2), vite build. Two independent review rounds on this commit: final verdict production_quality, 0 findings.

… check

Fully-unavailable builds (dev, package-manager installs like AUR) used to
render the support reason twice — once as the header description and once
as the last-check status, because the backend mirrors the reason into
lastCheck.error — plus a permanently disabled 'Check for updates' button.

The panel now collapses to just the header (title + reason + Unavailable
badge) for those builds. Notify-only (Flatpak) and self-updating builds
are unchanged. Adds AboutSettings tests covering both states.
@juacker

juacker commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator Author

Fixed the ugly Updates panel on non-updatable builds (d542e51): dev builds and package-manager installs (e.g. AUR) were rendering the support reason twice (the backend mirrors it into lastCheck.error) plus a permanently disabled 'Check for updates' button. The panel now collapses to just title + reason + Unavailable badge for those builds. Flatpak (notify-only) and self-updating builds are unchanged. Added AboutSettings tests for both states. Reviewed: production_quality, 0 findings.

…te or check

Dev builds and package-manager installs (e.g. AUR) get their updates
through the build/package channel, so an 'Unavailable' panel has nothing
actionable to say. Settings > About now renders no Updates section at all
for them, per the settled UX model: checking is always on where possible,
and unavailable capabilities show no UI rather than a disabled one.
Flatpak (notify-only) and self-updating builds are unchanged.
@juacker

juacker commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator Author

Per user decision (c9ee962, replaces d542e51): builds that can neither self-update nor check for updates (dev, package-manager installs like AUR) now render no Updates panel at all in Settings → About — not even the collapsed 'Unavailable' header. The panel also stays hidden until update support is known, so there's no appear-then-vanish flicker on load; it still appears if the status read itself fails, so errors stay visible. Flatpak (notify-only) and self-updating builds unchanged. Reviewed twice: production_quality, 0 findings.

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.

1 participant