fix(desktop): stop offering an update track the app cannot switch to - #442
Merged
Merged
Conversation
Settings offered an "Update track" select that promised stable and nightly builds were interchangeable. They have not been since 7a61251 split their identities: nightly declares com.pylon.code.nightly, is named Pylon (Nightly), and keeps its data in ~/.pylon-code-nightly. Picking Nightly on a stable install pointed electron-updater at the nightly feed and offered a download that can never install. Squirrel.Mac validates an update against the running app's designated requirement, which pins the bundle identifier: Pylon (Alpha): identifier "com.pylon.code" and anchor apple generic ... Pylon (Nightly): identifier "com.pylon.code.nightly" and anchor apple ... So the install is refused, and MacUpdater.quitAndInstall then waits on a native update-downloaded event that never arrives — with the backends already stopped, which reads as the app hanging on restart. No second app appears in /Applications either, because Squirrel only ever replaces the running bundle. Windows and Linux fail differently for the same reason. Even a hypothetical success would relaunch against a different runtime home, so the user's projects would look erased. The track is now a property of the build, not a preference: DesktopUpdates derives it from the app version, and setChannel is gone from the service, the IPC method, the preload bridge, and the contract. updateChannel and updateChannelConfiguredByUser leave DesktopSettings; existing documents still decode (excess keys are ignored) and shed the keys on the next write, which is what unsticks anyone whose stable install is currently polling the nightly feed. Remote SSH environments pick their t3 dist-tag from the build for the same reason. The settings row keeps its place and tells the truth instead: which build you are on, that the other one installs alongside with its own data, and a button that opens its download page. Model: Claude Opus 5 via Claude Code.
Contributor
Thread transfer impact✅ Thread transfer remains within every enforced ceiling.
Baseline: Scenario and decoded snapshot size10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed. |
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.
The problem
Settings → About offered an Update track select — "Use stable releases or nightly builds. Switch back anytime." Picking Nightly on a stable install offers a download that can never install, then hangs the app on restart. No nightly app ever appears in
/Applications.Stable and nightly stopped being interchangeable in 7a61251, which gave them separate identities on purpose:
com.pylon.codevscom.pylon.code.nightly,Pylon (Alpha)vsPylon (Nightly),~/.pylon-codevs~/.pylon-code-nightly. macOS in-place updates go through Squirrel.Mac, which validates the downloaded bundle against the running app's designated requirement — and that pins the bundle identifier. From two installed builds:The nightly bundle cannot satisfy the stable app's requirement, so the install is refused.
MacUpdater.quitAndInstall()then registers a listener for a nativeupdate-downloadedevent that never arrives — by which pointinstallDownloadedUpdatehas already stopped every backend and setquitting, which is the hang. And Squirrel only ever replaces the running bundle, so a second app was never on the table. Windows and Linux fail differently for the same reason, and even a hypothetical success would relaunch against a different runtime home, so the user's projects would look erased.Anyone who already flipped the select is stuck: their stable install has
updateChannel: "nightly"on disk and keeps polling a feed it cannot install from.The fix
The track becomes a property of the build rather than a preference.
DesktopUpdatesderives its channel from the app version.setChannelis gone from the service, the IPC method, the preload bridge, and the contract.updateChannel/updateChannelConfiguredByUserleaveDesktopSettings. Existing documents still decode — excess keys are ignored — and shed the keys on the next write, which is what unsticks installs currently pointed at the wrong feed.t3dist-tag from the build for the same reason, instead of from the setting.Net −300 lines.
Verification
vp test runoverapps/desktop/src/updates/,apps/desktop/src/settings/,apps/desktop/src/window/,apps/web/src/components/settings/,packages/ssh/src/command.test.ts— 44 files, 421 tests, all passing.typecheckclean for@t3tools/desktop,@t3tools/web,@t3tools/contracts. (Note for reviewers: this repo'stypecheckexits 0 with errors present — read the output.)vp lintclean on every changed file, apart from a pre-existing unuseduseNavigateimport inSettingsPanels.tsxthat is also onpylon.DesktopUpdatesfollows the stable feed on a stable build and the nightly feed on a nightly build;DesktopSettingsignores a retired update-channel preference and drops it on write.Not verified in a running client — no UI screenshots. The changed row is text plus a button and I did not spin up a browser; happy to do a pass if you want one before merge.
Out of scope, but blocking for users
pylon-code.comis serving a September 2 build (last-modified: Wed, 02 Sep 2026on both/and/download/), so the nightly download toggle from #385 is not live and?channel=nightlycurrently lands on the stable page. Git deploys are enabled inapps/marketing/vercel.ts, so this needs a look in the Vercel dashboard. Until it redeploys, the new Get nightly button — and the link indocs/user/updating.md— points at a page without the nightly option.Model: Claude Opus 5 via Claude Code.
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.