feat: add Check for Updates in Settings + version bump to 0.0.3#15
feat: add Check for Updates in Settings + version bump to 0.0.3#15aaditagrawal merged 5 commits intomainfrom
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughAdds a manual update-check IPC channel and bridge method, extends the DesktopBridge contract, integrates update-check UI/state in Settings, and bumps package versions across desktop, web, server, and contracts. Changes
Sequence Diagram(s)sequenceDiagram
participant SettingsUI as Settings UI
participant Preload as Preload Bridge
participant MainProc as Main Process
participant UpdateMgr as Update Manager
SettingsUI->>Preload: checkForUpdate()
Preload->>MainProc: invoke "desktop:update-check"
MainProc->>UpdateMgr: checkForUpdates("manual")
UpdateMgr-->>MainProc: DesktopUpdateState
MainProc-->>Preload: DesktopUpdateState
Preload-->>SettingsUI: DesktopUpdateState
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
📝 Coding Plan
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/web/src/routes/_chat.settings.tsx`:
- Around line 222-243: The About section is missing from the Settings JSX so the
update handlers (handleCheckForUpdate, handleDownloadUpdate,
handleInstallUpdate) and state (updateState, isCheckingUpdate,
setIsCheckingUpdate, setUpdateState) are never used; add a new "About" block in
the rendered JSX that displays the current app version and inline buttons for
"Check for Updates", "Download Update", and "Install Update" wired to those
handlers (disable/hide buttons based on isElectron/window.desktopBridge presence
and updateState/isCheckingUpdate), and render updateState status feedback so the
results of checkForUpdate/downloadUpdate/installUpdate are visible to the user.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: a4255fef-32ce-49d9-8281-cfa6b5ac7ba6
📒 Files selected for processing (6)
apps/desktop/package.jsonapps/desktop/src/main.tsapps/desktop/src/preload.tsapps/web/package.jsonapps/web/src/routes/_chat.settings.tsxpackages/contracts/src/ipc.ts
75f1105 to
100bba8
Compare
- Add Check for Updates button, download/install actions, and progress bar to the About section in Settings - Bump server and contracts package versions to match desktop and web
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
apps/web/src/routes/_chat.settings.tsx (1)
214-246:⚠️ Potential issue | 🟠 MajorUpdate workflow is still unreachable from Settings UI.
Lines 214-246 add update state and handlers, but no rendered control invokes them (About currently only shows
APP_VERSION). This leaves the “Check for Updates / Download / Restart & Install / Retry + progress” objective unfulfilled.As per coding guidelines,
**/*.{js,ts,tsx,jsx}: “All ofbun fmt,bun lint, andbun typecheckmust pass before considering tasks completed.”🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/src/routes/_chat.settings.tsx` around lines 214 - 246, The new update state and handlers (updateState, isCheckingUpdate, handleCheckForUpdate, handleDownloadUpdate, handleInstallUpdate) are wired but never rendered; add UI controls in the Settings/About render so users can trigger the flow and see progress: render the APP_VERSION plus conditional buttons and status text that call handleCheckForUpdate, handleDownloadUpdate and handleInstallUpdate based on updateState (e.g., show "Check for Updates" when idle, show "Download" when an update is available, show "Install/Restart" when downloaded, show progress and a "Retry" on errors) and disable buttons when isCheckingUpdate is true; ensure the UI updates reflect updateState fields and errors so the full “Check / Download / Install / Retry + progress” workflow is reachable and test passes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/web/src/routes/_chat.settings.tsx`:
- Around line 217-246: The desktop bridge calls in the useEffect and the
handlers (getUpdateState, checkForUpdate, downloadUpdate, installUpdate) can
reject and currently cause unhandled promise rejections; wrap each async call in
try/catch (or attach .catch) to handle IPC failures, log the error (or surface
user-friendly feedback), and set sensible fallbacks (e.g., leave or reset
setUpdateState and ensure setIsCheckingUpdate(false) in finally for
handleCheckForUpdate). Update the useEffect's initial void
bridge.getUpdateState().then(setUpdateState) to handle rejection as well, and
keep returning the unsubscribe from bridge.onUpdateState as before.
---
Duplicate comments:
In `@apps/web/src/routes/_chat.settings.tsx`:
- Around line 214-246: The new update state and handlers (updateState,
isCheckingUpdate, handleCheckForUpdate, handleDownloadUpdate,
handleInstallUpdate) are wired but never rendered; add UI controls in the
Settings/About render so users can trigger the flow and see progress: render the
APP_VERSION plus conditional buttons and status text that call
handleCheckForUpdate, handleDownloadUpdate and handleInstallUpdate based on
updateState (e.g., show "Check for Updates" when idle, show "Download" when an
update is available, show "Install/Restart" when downloaded, show progress and a
"Retry" on errors) and disable buttons when isCheckingUpdate is true; ensure the
UI updates reflect updateState fields and errors so the full “Check / Download /
Install / Retry + progress” workflow is reachable and test passes.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 2e6af923-dd19-4886-8a5d-0c7aef6fd644
📒 Files selected for processing (6)
apps/desktop/package.jsonapps/desktop/src/main.tsapps/desktop/src/preload.tsapps/web/package.jsonapps/web/src/routes/_chat.settings.tsxpackages/contracts/src/ipc.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/contracts/src/ipc.ts
There was a problem hiding this comment.
♻️ Duplicate comments (1)
apps/web/src/routes/_chat.settings.tsx (1)
217-246:⚠️ Potential issue | 🟡 MinorCatch bridge call failures to avoid uncaught async errors.
getUpdateState,checkForUpdate,downloadUpdate, andinstallUpdatestill reject without localcatchhandling, so IPC failures can bubble as uncaught promise rejections and leave the UI without clear fallback state.Proposed hardening
useEffect(() => { if (!isElectron || !window.desktopBridge) return; const bridge = window.desktopBridge; - void bridge.getUpdateState().then(setUpdateState); + void bridge + .getUpdateState() + .then(setUpdateState) + .catch((error) => { + console.error("Failed to read update state", error); + setUpdateState((prev) => + prev + ? { + ...prev, + status: "error", + message: "Failed to read update state.", + errorContext: "check", + canRetry: true, + } + : prev, + ); + }); const unsubscribe = bridge.onUpdateState(setUpdateState); return unsubscribe; }, []); const handleCheckForUpdate = useCallback(async () => { if (!isElectron || !window.desktopBridge) return; setIsCheckingUpdate(true); try { const state = await window.desktopBridge.checkForUpdate(); setUpdateState(state); + } catch (error) { + console.error("Failed to check for updates", error); + setUpdateState((prev) => + prev + ? { + ...prev, + status: "error", + message: error instanceof Error ? error.message : "Failed to check for updates.", + errorContext: "check", + canRetry: true, + } + : prev, + ); } finally { setIsCheckingUpdate(false); } }, []); const handleDownloadUpdate = useCallback(async () => { if (!isElectron || !window.desktopBridge) return; - const result = await window.desktopBridge.downloadUpdate(); - setUpdateState(result.state); + try { + const result = await window.desktopBridge.downloadUpdate(); + setUpdateState(result.state); + } catch (error) { + console.error("Failed to download update", error); + setUpdateState((prev) => + prev + ? { + ...prev, + status: "error", + message: error instanceof Error ? error.message : "Failed to download update.", + errorContext: "download", + canRetry: true, + } + : prev, + ); + } }, []); const handleInstallUpdate = useCallback(async () => { if (!isElectron || !window.desktopBridge) return; - const result = await window.desktopBridge.installUpdate(); - setUpdateState(result.state); + try { + const result = await window.desktopBridge.installUpdate(); + setUpdateState(result.state); + } catch (error) { + console.error("Failed to install update", error); + setUpdateState((prev) => + prev + ? { + ...prev, + status: "error", + message: error instanceof Error ? error.message : "Failed to install update.", + errorContext: "install", + canRetry: true, + } + : prev, + ); + } }, []);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/src/routes/_chat.settings.tsx` around lines 217 - 246, The bridge IPC calls can reject and must be locally handled: wrap the initial bridge.getUpdateState call in the useEffect and each async handler (handleCheckForUpdate, handleDownloadUpdate, handleInstallUpdate, and the bridge.downloadUpdate/bridge.installUpdate invocations) in try/catch blocks, logging the error (or calling a UI error handler) and optionally setting a safe fallback update state so failures don’t produce uncaught promise rejections or leave the UI in an indeterminate state; preserve the existing finally that clears isCheckingUpdate in handleCheckForUpdate.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@apps/web/src/routes/_chat.settings.tsx`:
- Around line 217-246: The bridge IPC calls can reject and must be locally
handled: wrap the initial bridge.getUpdateState call in the useEffect and each
async handler (handleCheckForUpdate, handleDownloadUpdate, handleInstallUpdate,
and the bridge.downloadUpdate/bridge.installUpdate invocations) in try/catch
blocks, logging the error (or calling a UI error handler) and optionally setting
a safe fallback update state so failures don’t produce uncaught promise
rejections or leave the UI in an indeterminate state; preserve the existing
finally that clears isCheckingUpdate in handleCheckForUpdate.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 3e243437-739f-459a-9a7a-4e3d36574cab
📒 Files selected for processing (3)
apps/server/package.jsonapps/web/src/routes/_chat.settings.tsxpackages/contracts/package.json
✅ Files skipped from review due to trivial changes (2)
- packages/contracts/package.json
- apps/server/package.json
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
apps/web/src/routes/_chat.settings.tsx (1)
217-246:⚠️ Potential issue | 🟡 MinorHandle rejected desktop bridge promises to avoid unhandled async errors.
This is still open from prior feedback: Line 220 and Lines 238-245 can reject without a
catch, andhandleCheckForUpdate(Line 225-234) rethrows on failure. In click handlers, that becomes an unhandled rejection with no user-facing fallback.#!/bin/bash # Verify bridge calls that can reject without explicit catch handling rg -nP 'getUpdateState\(\)\.then\(setUpdateState\)(?!\s*\.catch)' apps/web/src/routes/_chat.settings.tsx -n -C2 rg -nP 'await window\.desktopBridge\.(checkForUpdate|downloadUpdate|installUpdate)\(' apps/web/src/routes/_chat.settings.tsx -n -C2🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@apps/web/src/routes/_chat.settings.tsx` around lines 217 - 246, In useEffect and the three handlers (handleCheckForUpdate, handleDownloadUpdate, handleInstallUpdate) guard against rejected desktop bridge promises by adding explicit error handling: for the useEffect promise from window.desktopBridge.getUpdateState() chain a .catch that logs the error (and does not leave an unhandled rejection) and ensure the unsubscribe from bridge.onUpdateState remains returned; for each click handler wrap await calls to window.desktopBridge.checkForUpdate(), downloadUpdate(), and installUpdate() in try/catch blocks (handleCheckForUpdate already sets isCheckingUpdate—ensure errors are caught and setIsCheckingUpdate(false) in finally without rethrowing) and call setUpdateState only on success, logging or surfacing errors (e.g., via console.error or a UI notification) instead of allowing unhandled rejections.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@apps/web/src/routes/_chat.settings.tsx`:
- Around line 1059-1100: The update buttons display when isElectron is true but
their handlers (handleDownloadUpdate, handleInstallUpdate, handleCheckForUpdate)
are no-ops if window.desktopBridge is missing, so change the render logic to
also check for the real bridge before showing/enabling controls: add a runtime
guard (e.g., hasDesktopBridge = !!window.desktopBridge) and either hide the
buttons or set disabled with a tooltip when hasDesktopBridge is false; update
the disable conditions on the "Check for Updates" and the variant buttons to
include !hasDesktopBridge so clicks are never perceived as actionable when the
bridge is unavailable.
---
Duplicate comments:
In `@apps/web/src/routes/_chat.settings.tsx`:
- Around line 217-246: In useEffect and the three handlers
(handleCheckForUpdate, handleDownloadUpdate, handleInstallUpdate) guard against
rejected desktop bridge promises by adding explicit error handling: for the
useEffect promise from window.desktopBridge.getUpdateState() chain a .catch that
logs the error (and does not leave an unhandled rejection) and ensure the
unsubscribe from bridge.onUpdateState remains returned; for each click handler
wrap await calls to window.desktopBridge.checkForUpdate(), downloadUpdate(), and
installUpdate() in try/catch blocks (handleCheckForUpdate already sets
isCheckingUpdate—ensure errors are caught and setIsCheckingUpdate(false) in
finally without rethrowing) and call setUpdateState only on success, logging or
surfacing errors (e.g., via console.error or a UI notification) instead of
allowing unhandled rejections.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ffe2e910-f702-45b7-9cf6-8b48decbc7b0
📒 Files selected for processing (1)
apps/web/src/routes/_chat.settings.tsx
Summary
checkForUpdateIPC channel so users can manually trigger update checksChanges
packages/contracts/src/ipc.ts— AddedcheckForUpdate()toDesktopBridgeinterfaceapps/desktop/src/main.ts— Addeddesktop:update-checkIPC handlerapps/desktop/src/preload.ts— Wired bridge method to IPC channelapps/web/src/routes/_chat.settings.tsx— Update UI in About sectionapps/web/package.json— Version bump to 0.0.3apps/desktop/package.json— Version bump to 0.0.3Test plan
Summary by CodeRabbit
New Features
Chores