Skip to content

feat: add Check for Updates in Settings + version bump to 0.0.3#15

Merged
aaditagrawal merged 5 commits intomainfrom
feat/check-for-updates
Mar 15, 2026
Merged

feat: add Check for Updates in Settings + version bump to 0.0.3#15
aaditagrawal merged 5 commits intomainfrom
feat/check-for-updates

Conversation

@aaditagrawal
Copy link
Copy Markdown
Owner

@aaditagrawal aaditagrawal commented Mar 15, 2026

Summary

  • Add a "Check for Updates" button inline with the version display in Settings > About
  • Wire up a new checkForUpdate IPC channel so users can manually trigger update checks
  • Show contextual Download / Restart & Install / Retry buttons based on update state
  • Include download progress bar during updates
  • Bump app version to 0.0.3 (web + desktop)

Changes

  • packages/contracts/src/ipc.ts — Added checkForUpdate() to DesktopBridge interface
  • apps/desktop/src/main.ts — Added desktop:update-check IPC handler
  • apps/desktop/src/preload.ts — Wired bridge method to IPC channel
  • apps/web/src/routes/_chat.settings.tsx — Update UI in About section
  • apps/web/package.json — Version bump to 0.0.3
  • apps/desktop/package.json — Version bump to 0.0.3

Test plan

  • Open Settings, verify version shows 0.0.3
  • Click "Check for Updates" button, verify it transitions to "Checking..." state
  • If update available, verify Download button appears
  • If downloaded, verify "Restart & Install" button appears
  • Verify download progress bar renders during download

Summary by CodeRabbit

  • New Features

    • Desktop: added a manual "Check for Updates" in Settings showing update status, last-checked time, download progress, and Download / Restart & Install / Retry flows; includes a Check for Updates button.
  • Chores

    • Bumped app/package versions to 0.0.3 across desktop, web, server, and shared packages.

@github-actions github-actions bot added the vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. label Mar 15, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 15, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0848c61d-be05-47eb-8a5d-b90a4a74767d

📥 Commits

Reviewing files that changed from the base of the PR and between 67de18b and 0d96911.

📒 Files selected for processing (1)
  • apps/web/src/routes/_chat.settings.tsx

📝 Walkthrough

Walkthrough

Adds 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

Cohort / File(s) Summary
Package Version Updates
apps/desktop/package.json, apps/web/package.json, apps/server/package.json, packages/contracts/package.json
Bumped package versions from 0.0.2 to 0.0.3.
Desktop IPC & Main
apps/desktop/src/preload.ts, apps/desktop/src/main.ts
Added UPDATE_CHECK_CHANNEL (desktop:update-check). Preload exposes checkForUpdate() on desktopBridge; main registers handler invoking checkForUpdates("manual") and returns DesktopUpdateState.
Contracts
packages/contracts/src/ipc.ts
Added checkForUpdate(): Promise<DesktopUpdateState> to the DesktopBridge interface.
Settings UI Integration
apps/web/src/routes/_chat.settings.tsx
Added updateState and isCheckingUpdate state, a useEffect subscription to update state, and handlers handleCheckForUpdate, handleDownloadUpdate, handleInstallUpdate. UI now shows update status, progress, and check/download/install controls.

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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I tapped the bridge, a tiny cheer,
A ping that chased the updates near,
Downloads hummed and progress grew,
Buttons glowed — install, renew,
🥕 The rabbit watched, content and clear.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes: adding a Check for Updates feature and bumping the version, which align with the primary objectives of the pull request.
Description check ✅ Passed The description covers the required template sections: What Changed is addressed in the Summary and Changes sections, Why is implicit in the feature context, and UI Changes are documented. All key aspects are included.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/check-for-updates
📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added the size:M 30-99 effective changed lines (test files excluded in mixed PRs). label Mar 15, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 38118fb and 75f1105.

📒 Files selected for processing (6)
  • apps/desktop/package.json
  • apps/desktop/src/main.ts
  • apps/desktop/src/preload.ts
  • apps/web/package.json
  • apps/web/src/routes/_chat.settings.tsx
  • packages/contracts/src/ipc.ts

@aaditagrawal aaditagrawal force-pushed the feat/check-for-updates branch from 75f1105 to 100bba8 Compare March 15, 2026 16:58
- 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
@github-actions github-actions bot added size:L 100-499 effective changed lines (test files excluded in mixed PRs). and removed size:M 30-99 effective changed lines (test files excluded in mixed PRs). labels Mar 15, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
apps/web/src/routes/_chat.settings.tsx (1)

214-246: ⚠️ Potential issue | 🟠 Major

Update 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 of bun fmt, bun lint, and bun typecheck must 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

📥 Commits

Reviewing files that changed from the base of the PR and between 75f1105 and 100bba8.

📒 Files selected for processing (6)
  • apps/desktop/package.json
  • apps/desktop/src/main.ts
  • apps/desktop/src/preload.ts
  • apps/web/package.json
  • apps/web/src/routes/_chat.settings.tsx
  • packages/contracts/src/ipc.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/contracts/src/ipc.ts

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
apps/web/src/routes/_chat.settings.tsx (1)

217-246: ⚠️ Potential issue | 🟡 Minor

Catch bridge call failures to avoid uncaught async errors.

getUpdateState, checkForUpdate, downloadUpdate, and installUpdate still reject without local catch handling, 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

📥 Commits

Reviewing files that changed from the base of the PR and between 100bba8 and f02779b.

📒 Files selected for processing (3)
  • apps/server/package.json
  • apps/web/src/routes/_chat.settings.tsx
  • packages/contracts/package.json
✅ Files skipped from review due to trivial changes (2)
  • packages/contracts/package.json
  • apps/server/package.json

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
apps/web/src/routes/_chat.settings.tsx (1)

217-246: ⚠️ Potential issue | 🟡 Minor

Handle 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, and handleCheckForUpdate (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

📥 Commits

Reviewing files that changed from the base of the PR and between f02779b and 67de18b.

📒 Files selected for processing (1)
  • apps/web/src/routes/_chat.settings.tsx

@aaditagrawal aaditagrawal merged commit 5239018 into main Mar 15, 2026
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 effective changed lines (test files excluded in mixed PRs). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant