feat: in-app auto-update via tauri-plugin-updater + signing pipeline#2
Merged
Conversation
Add a full version-detection + auto-update flow so users get new releases without ever leaving the app. Client side - tauri-plugin-updater + tauri-plugin-process registered in main.rs; capabilities/default.json grants updater + process:allow-restart - tauri.conf.json: bundle.createUpdaterArtifacts=true and plugins.updater with GitHub Releases endpoint (pubkey left blank for maintainers to fill) - src/updater.ts: friendly wrapper around check / downloadAndInstall / relaunch; silent-by-default so a startup auto-check stays quiet, but re-throws when called explicitly so the UI can show errors - store.ts: new updater slice (status / latestUpdate / progress / error / lastUpdateCheck) + actions (checkForUpdate / installUpdate / restartForUpdate / dismissUpdate); auto-runs a silent check 3s after init - AboutPanel: new UpdaterCard with five visual states — idle / checking, available (with release notes + Install / Not now), downloading (with KB/MB progress bar), installed (with Restart now), error (with retry) - Sidebar and Settings sub-nav both show a green dot on Settings/About when an update is available CI / CD - release.yml: wires TAURI_SIGNING_PRIVATE_KEY + TAURI_SIGNING_PRIVATE_KEY_PASSWORD env so the bundler signs each updater artifact and includeUpdaterJson emits the latest.json manifest alongside installers Tests (+23, total 279/32 files) - tests/__mocks__/tauri-updater.ts: in-memory updater plugin with hooks for next-update / next-error / chunk-sizes / download-fail - tests/__mocks__/tauri-process.ts: relaunch spy - tests/updater.test.ts: wrapper silent vs non-silent, progress streaming - tests/store.updater.test.ts: every status transition + error paths - tests/components/AboutPanel.test.tsx: identity + all updater UI states Docs - README.md and README.zh.md: new "Auto-update setup (maintainers)" / "自动更新设置(维护者)" section with the 4-step signing onboarding; feature table picks up a 🔄 Auto-update row Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
…rives
Two UX glitches around the "EchoWise is thinking…" state:
1. Two thinking indicators were rendered at once — a line above the
composer ("EchoWise is thinking…") and the composer ThinkingBar
itself. Replace the message-stream copy with an iMessage-style
TypingIndicator (avatar + three pulsing dots) that only shows while
the AI hasn't replied yet (i.e. the last turn is still the user's).
Removes the duplicate language and avoids the awkward "AI thinks
again" pulse after the reply already appeared.
2. After the AI's text bubble shows up, the composer stayed stuck on
"EchoWise is thinking…" for several seconds while TTS synthesized
and saved audio. Run the TTS chain in the background (fire-and-
forget) so setBusy(false) fires the moment the reply lands; audio
still streams in once ready and the bubble's play button works.
ThinkingBar copy keeps the companion name ("EchoWise is thinking…") per
user preference; the leading three-dot icon was dropped to clean up the
pill visually.
Also remove Release flow / Roadmap / Contributing sections from both
READMEs per request to keep the public landing page focused.
Test updates:
- Replace the old "is thinking" text assertion with the new
"EchoWise is thinking…" pill + aria-label="thinking" lookup.
279/279 tests pass.
Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
A 36-second GIF showing the core conversation loop (record / transcribe / AI reply / scoring chip). Replaces the "Screenshots coming soon" placeholder in both READMEs. Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
The recording covers the full walk-through (talk + scoring + growth + settings), not just the talking flow. `demo.gif` is the convention used by most open-source projects (VS Code, Linear, shadcn-ui) and reads as "the canonical visual" without an arbitrary numeric prefix. Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
2 tasks
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
Add a full version-detection + auto-update flow so users get new releases without ever leaving the app.
What's in this PR
🔌 Client side
tauri-plugin-updater+tauri-plugin-process(forrelaunch) registered inmain.rs; capabilities/default.json grantsupdater:*+process:allow-restarttauri.conf.json:bundle.createUpdaterArtifacts: true+plugins.updatersection pointing at the GitHub Releaseslatest.jsonendpoint (pubkey left blank for maintainers to fill — see README)src/updater.ts: friendly wrapper aroundcheck / downloadAndInstall / relaunch. Silent-by-default so a startup auto-check stays quiet, but re-throws when called explicitly so the UI can surface errorsstore.ts):updateStatus(idle / checking / upToDate / available / downloading / installed / error),latestUpdate,updateProgress,updateError,lastUpdateCheck. Actions:checkForUpdate({silent}),installUpdate(),restartForUpdate(),dismissUpdate(). Auto-runs a silent check 3 s after init🎨 UI
AboutPanel.tsxhas a new<UpdaterCard>with five visual states:🚀 CI / CD
.github/workflows/release.ymlwiresTAURI_SIGNING_PRIVATE_KEY+TAURI_SIGNING_PRIVATE_KEY_PASSWORDenv so the bundler signs each updater artifact, andincludeUpdaterJson: trueemits thelatest.jsonmanifest alongside the installers🧪 Tests (+23 / total 279 across 32 files)
tests/__mocks__/tauri-updater.ts— in-memory updater plugin with hooks fornext update/next error/chunk sizes/download failtests/__mocks__/tauri-process.ts—relaunchspytests/updater.test.ts— wrapper silent vs non-silent, progress streaming, download errorstests/store.updater.test.ts— every status transition + error paths + dismisstests/components/AboutPanel.test.tsx— identity + every updater UI state (idle / available / installed / error)📝 Docs
Test plan
npm testgreen (279/279)npm run vite:buildpassescargo buildpassesnpm run dev→ Settings → About → click "Check for updates" (will show an error untillatest.jsonexists, which is expected)TAURI_SIGNING_PRIVATE_KEYsecret and tags a release: verifylatest.jsonshows up in Releases and the in-app updater flow works end-to-endHow users will experience this