Repository navigation
fix: update an installed DS Bot in DSH Desktop - #505
Conversation
DSH Desktop (rc.2) runs profiles with HMR, and there installBundle refuses a package the profile already depends on: every self-update ended in already-installed. Fall back to removing the bundle and installing the new spec, the way the manager's own Update does. Removing the bundle disposes this host, so the result cannot be published from here: a note at <home>/bot/update.json carries it to the next start, which reports the version once as updated, warns when the install did not finish, and keeps a clean note while a reload still runs the old modules. The update button also mounted after its early return — an update that turned visible after mount crashed the sidebar slot (React #310), so the hooks come first now. Fixes #423
A refused removal leaves the running version in place, so a note it wrote would otherwise wait for a later start that has nothing to report.
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
Devin Review found 1 potential issue.
1 flag not posted on this PR by your GitHub settings — view it in Devin Review. (Configure)
| repoUrl: repoUrl(), enabled, | ||
| checkedAt: status.checkedAt, phase: status.phase, installed: status.installed, error: status.error, | ||
| available: status.phase !== 'installed' && target !== null && status.latest !== null && newer(status.latest, status.current), | ||
| available: status.phase !== 'installed' && status.phase !== 'updated' && target !== null && status.latest !== null && newer(status.latest, status.current), |
There was a problem hiding this comment.
🟡 Later updates stay hidden until restart
After hot reload, updated keeps a later release unavailable even when runCheck discovers it. The update controls stay hidden until the host restarts.
Learn more
A successful hot-reload update starts a new host whose status begins in updated. An update check can later find a newer release and set target, but view() continues to return available: false for the lifetime of that host. AboutPage also hides its update button while the phase is updated, so simply changing available is not enough.
Example: DS Bot reloads into version 0.2.2 and reports updated. Version 0.2.3 becomes available; a fresh check finds it, but neither the sidebar nor About offers the update.
Recommended fix: Keep updated only as a transient success state. When runCheck finds a newer version than the running package, move the phase to idle and allow view().available and the About control to offer it.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 984baf2246
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } | ||
| try { | ||
| const again = await service.installBundle(chosen.spec, options) | ||
| if (again?.error) mark(again.error.diagnostic ?? again.error.code ?? 'install failed') |
There was a problem hiding this comment.
Mark every unsuccessful reinstall result as failed
When the post-removal install resolves with an unsuccessful application but no error—for example { application: 'failed' } or an undefined result—this condition leaves update.json as a clean in-progress note. The validation below still rejects the result, but because the old bundle has already been removed, the failure diagnostic is not persisted; restoring the old version then silently retains that clean note indefinitely. Validate the accepted application values here and call mark(...) for every rejected result.
Useful? React with 👍 / 👎.


Issue
Fixes #423
Bug: in DSH Desktop 0.2.1-rc.2 and later, DS Bot's own Update always fails with "The update did not finish: already-installed".
What changed / 改了什么
installBundle()for a package the profile already has whenever HMR runs (always in DSH Desktop); an upgrade is a removal and an installation, which is what the plugin page's Update does for official plugins. Onalready-installed, DS Bot now removes its bundle and installs the new version. Without HMR nothing changes.update.jsonin DS Bot's data folder) first. The new version reads it at start and shows "DS Bot {version} is installed."; a failed reinstall writes its reason into the note, and the version that starts next logs it. A refused removal drops the note and shows the reason as before.UpdateButtoncalled hooks after an early return, so an update that became visible after the sidebar mounted crashed the sidebar slot (React Show a group post at once while a round is running #310). The hooks now come first.ds-boton the Plugins page and add it again. The Bots, chats and memory stay (checked below).Thanks @iron-water for the root-cause analysis in #423 and @recall350 for the report.
Changelog
In DSH Desktop, Update in DS Bot installs the new version again instead of failing with "already-installed".
How I checked it / 怎么验证的
npm test: 941 pass, 0 fail, 1 skip (the usual Windows file-name skip);update.test.js20/20, including call order, the note before the removal, a refused removal, a failed reinstall and the three start cases.node scripts/build-client.mjs --checknpm run lint: 0 errorsalready-installed(the bug);ERR_PNPM_FETCH_500; addingds-botagain brings back the Bot, chat and memory, and the note is logged and deleted.Checklist / 检查
src/client/changed →npm run buildran andclient.jsis committed.Co-authored-by.