Add built-in auto-updater with tab-bar update pill
Wires electrobun's Updater to the /dl download host. The packaged app checks https://miniscp.com/dl on launch + every 6h; when a newer build exists, an accent-colored "update tool" appears next to Connections in the tab bar. It announces the update, becomes its own inline progress bar while downloading, then flips to "Restart to apply" (two-step: download, then user-triggered relaunch). - electrobun.config.ts: release.baseUrl = https://miniscp.com/dl (baked into version.json at build; miniscp.com fronted by an external proxy for TLS). - rpc.ts: checkForUpdate/downloadUpdate/applyUpdate requests + updateStatus push. - rpc-handlers.ts + index.ts: call Updater; poll on launch+6h; stream onStatusChange progress. checkForUpdate self-guards the dev channel. - rpc.service.ts + new updater.service.ts: signal-based state (available -> downloading -> ready, ready derived from downloadUpdate ok). - tab-bar.ts: single bg-primary pill; progress fills the pill itself. - icons.ts: register mynaDownload. i18n: tabBar + menu keys across all locales. - menu.ts + app.ts: "Check for Updates…" app-menu item -> UpdaterService.check(). - docs: build-and-release + architecture updated. Unsigned builds still update (applyUpdate strips the macOS quarantine xattr). Verified: tsc --noEmit (exit 0) + build:ui AOT (exit 0). Live pill + full download/apply flow require a two-build test on the host. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -88,9 +88,33 @@ internal box (plain HTTP `:80`, no domain/TLS). Deploys to `/srv/miniscp/`.
|
||||
- `site/deploy.sh` — run per build machine after `scripts/release.ts`; copies `artifacts/stable-*`
|
||||
and renames the build-numbered win portable zip to the stable `stable-win-x64-miniSCP-portable.zip`.
|
||||
`MINISCP_DL_DIR` overrides the target (stage locally, then rsync to the server).
|
||||
- **Future updater** (not wired yet): set `release.baseUrl = http://<host>/dl/` in
|
||||
`electrobun.config.ts` (currently unset) → builds start emitting `.patch` files that `deploy.sh`
|
||||
already ships. Then call the electrobun `Updater` API on launch/interval/tray.
|
||||
- `release.baseUrl = https://miniscp.com/dl` is set in `electrobun.config.ts`; `miniscp.com` is
|
||||
fronted by an external proxy for TLS (Caddy itself stays on `:80` behind it). The value is baked
|
||||
into `version.json` at build time, so only builds made after it was added check for updates.
|
||||
With `generatePatch` (default true), release builds now need **build-time network to
|
||||
`miniscp.com/dl`** so electrobun can fetch the currently-published version to diff a `.patch`
|
||||
(the first build after enabling it has nothing to diff and just ships the full artifacts).
|
||||
|
||||
## Auto-updater (app side)
|
||||
|
||||
Wired on top of the download host above. See the "Auto-updater" section in
|
||||
[architecture.md](architecture.md) for the runtime flow.
|
||||
|
||||
- **Backend** ([src/bun/index.ts](../src/bun/index.ts)): `Updater.checkForUpdate()` runs ~5s after launch and
|
||||
every 6h; on `updateAvailable` it pushes `rpc.send.updateStatus({phase:"available",…})`.
|
||||
`Updater.onStatusChange` streams `download-progress` (0–100) → `updateStatus{downloading}`.
|
||||
`checkForUpdate` self-guards the `dev` channel, so `bun run dev` never shows the pill.
|
||||
- **RPC** ([src/shared/rpc.ts](../src/shared/rpc.ts)): requests `checkForUpdate` / `downloadUpdate` /
|
||||
`applyUpdate` (handlers in [rpc-handlers.ts](../src/bun/rpc-handlers.ts) call the electrobun `Updater`);
|
||||
push message `updateStatus`.
|
||||
- **UI**: `UpdaterService` ([ui/src/app/updater.service.ts](../ui/src/app/updater.service.ts)) holds signals
|
||||
(`state`/`version`/`progress`); the tab-bar "update pill" ([tab-bar.ts](../ui/src/app/tab-bar/tab-bar.ts))
|
||||
is one accent (`bg-primary`) control that announces → fills as a progress bar while downloading →
|
||||
"Restart to apply". `state` is `available → downloading → ready` (ready derived from the
|
||||
`downloadUpdate` response). App-menu "Check for Updates…" ([menu.ts](../src/bun/menu.ts)) routes a
|
||||
`check-for-updates` menu action into `UpdaterService.check()`.
|
||||
- **Unsigned is fine:** `applyUpdate()` strips the macOS quarantine xattr before relaunch, so the
|
||||
swapped bundle isn't Gatekeeper-blocked.
|
||||
|
||||
## Icons
|
||||
|
||||
|
||||
Reference in New Issue
Block a user