Skip to content

fix: update an installed DS Bot in DSH Desktop - #505

Merged
Fei2411 merged 2 commits into
devfrom
fix/423-update-already-installed
Oct 23, 2026
Merged

Fei2411 merged 2 commits into
devfrom
fix/423-update-already-installed

Conversation

@Fei2411

@Fei2411 Fei2411 commented Oct 23, 2026 •

Copy link
Copy Markdown
Owner

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 / 改了什么

  • Update under hot reload. Since DSH 0.2.1-rc.2 the plugin manager refuses 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. On already-installed, DS Bot now removes its bundle and installs the new version. Without HMR nothing changes.
  • Result after the switch. Removing the bundle stops the DS Bot host that runs the update, so it leaves a note (update.json in 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.
  • Sidebar crash. UpdateButton called 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.
  • README / README.zh: 0.2.1 and earlier still run the old update code, so they need one manual update: remove ds-bot on 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.js 20/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 --check
  • npm run lint: 0 errors
  • Smoke test: 52/52
  • Real run on DSH Web 0.2.1-rc.2 with HMR, a separate DSH home and a local npm registry with test versions:
    • stock 0.2.1 → Update: already-installed (the bug);
    • this branch, test.3 → test.4 and test.4 → test.5: DS Bot leaves the page, the new version loads without a restart and shows "Update installed · DS Bot … is installed."; the profile dependency follows; the Bot and its chat are still there and keep working;
    • registry answers 500 for the new tarball: DS Bot is removed, the note keeps ERR_PNPM_FETCH_500; adding ds-bot again brings back the Bot, chat and memory, and the note is logged and deleted.
  • Screenshot attached

Checklist / 检查

  • One issue, one subject. / 只做一件事。
  • src/client/ changed → npm run build ran and client.js is committed.
  • No keys, tokens or personal data, also in screenshots.
  • No AI tool as author or Co-authored-by.

Devin Review

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.
@Fei2411

Fei2411 commented Oct 23, 2026

Copy link
Copy Markdown
Owner Author

Update from test.3 to test.4 on DSH Web 0.2.1-rc.2 with HMR, and the result card afterwards.

update-flow

case2-updated

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 23, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-23T18:08:13.187064Z 984baf2 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

1 flag not posted on this PR by your GitHub settings — view it in Devin Review. (Configure)

Devin Review

Comment thread ds-bot/src/host/update.js
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),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 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.

Devin Review


Was this helpful? React with 👍 or 👎 to provide feedback.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 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".

Comment thread ds-bot/src/host/update.js
}
try {
const again = await service.installBundle(chosen.spec, options)
if (again?.error) mark(again.error.diagnostic ?? again.error.code ?? 'install failed')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge 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 👍 / 👎.

@Fei2411
Fei2411 merged commit 94d9630 into dev Oct 23, 2026
13 checks passed
@Fei2411
Fei2411 deleted the fix/423-update-already-installed branch October 23, 2026 18:17
This was referenced Oct 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant