feat(desktop): the sidebar offers Restart to update above the account row
Merged
DA
8d ago+228+228+012345678901234567890123456789-21-21-01234567890123456789
What
Dean: "Let's add an update button somewhere on the left sidebar wherever it makes sense so that it's not hidden behind settings."
Until now, a newer release only showed as a dot on the account row's gear, and the controls were in Settings ▸ Updates. Now the left sidebar shows an update control just above the account row, the same spot Codex, Cursor and Linear use. It only appears when there's something to do:
| Update state | Sidebar |
|---|---|
| Downloaded, waiting on a restart | Restart to update: a row tinted in the same working blue as the old dot (calm, not the accent fill), with a new arrow-up-in-a-circle glyph. Tooltip: "Luke 0.11.0 is ready". |
| Downloading | A quiet line, nothing to press: "Downloading update… 42%" (no percentage if progress isn't reported yet), with role="status". |
| Up to date, never checked, checking, just updated | Nothing |
| Failed | Nothing. This stays in Settings, and the gear's dot still points there. The update service has no retry act (Settings' fallback is "Download" from the releases page), so I didn't invent one. |
| A build that can't install itself (unsigned/dev) | Nothing. Settings' "Download" covers it. |
- One code path. Pressing the row calls
UpdateControl.onInstall, the sameACT_KIND.UPDATE_INSTALLthat Settings' "Restart to update" button sends. Whether the sidebar shows a control comes fromupdateRow, the same reading the Settings row uses, so the two can't disagree. - Gear dot: dropped while the sidebar row is showing, so the news isn't shown twice. The dot still marks a failed update (a newer version is known but couldn't be installed). The sidebar now works this out from
updatesitself, so the shell no longer passessettingsNote. - Collapsed sidebar: no title-bar control, as asked. The sidebar row comes back when you expand it.
- Menu bar / shortcuts: the app has no "Check for Updates…" or "Restart to Update" menu item, so nothing was added.
- Fixture: any fixture run (
--fixture, so everyevidence.shcapture) stages a release one minor version past the running build, downloaded and waiting on its restart (fixtureUpdateinupdate-row.ts). That puts the sidebar row in the evidence. Settings' Updates row in a fixture run reads the same staged state.
Screenshots (headless Chrome, the real DesktopShell and stylesheet, synthetic data)
Ready, light / dark:


Downloading (dark) and failed (light; the gear's dot is the only signal):


Tests
desktop-sidebar.test.ts(throughDesktopSidebar):- A downloaded release draws Restart to update just above the account row, and pressing it runs the install act.
- A downloading release is a status line with its rounded percentage and no button.
- Up to date, checking, or unable to install in place: no update control.
- The gear's dot stands down while the sidebar shows the release, and still marks a failed one with the update row's words.
update-row.test.ts: a fixture run stages a newer release waiting on its restart, and a live run keeps the updater's own answer.
./scripts/check.sh exits 0.
CI could not verify the Mac UI, and ./scripts/verify.sh was not run (Linux cloud VM). The screenshots are headless Chrome, not Electron. LUKE-159 is the manual Mac pass.
🤖 Generated with Claude Code