Skip to content

feat(dashboard): add generic desktop app updater bridge#5424

Merged
zouyonghe merged 4 commits intoAstrBotDevs:masterfrom
zouyonghe:master
Feb 25, 2026
Merged

feat(dashboard): add generic desktop app updater bridge#5424
zouyonghe merged 4 commits intoAstrBotDevs:masterfrom
zouyonghe:master

Conversation

@zouyonghe
Copy link
Member

@zouyonghe zouyonghe commented Feb 25, 2026

Summary

  • replace desktop update redirect flow with an in-app desktop update dialog in VerticalHeader.vue
  • decouple dashboard from astrbotDesktop-specific methods by introducing a generic window.astrbotAppUpdater interface
  • rename electron-bridge.d.ts to desktop-bridge.d.ts and update global bridge typings
  • add i18n messages for desktop app update states in both zh-CN and en-US

Why

The dashboard should not be tightly coupled to a specific desktop runtime implementation. Exposing a generic updater interface keeps upstream reusable while still allowing desktop shells to provide concrete behavior.

Verification

  • pnpm -C dashboard typecheck

Summary by Sourcery

引入通用的桌面应用更新桥接层,并将原有的桌面更新跳转流程替换为仪表盘顶部栏中的应用内更新对话框。

新功能:

  • 在桌面发布模式下,为垂直顶部栏添加一个基于通用更新桥接层驱动的桌面应用内更新对话框。
  • 暴露通用的 window.astrbotAppUpdater 接口,用于在仪表盘中检查和安装桌面应用更新。

增强:

  • 泛化桌面桥接的 TypeScript 定义(desktop-bridge.d.ts),并扩展 window.astrbotDesktop 类型,以支持后端控制和桌面更新操作。

文档:

  • 为桌面应用更新状态在英文和中文语言环境中添加 i18n 文本。
Original summary in English

Summary by Sourcery

Introduce a generic desktop app updater bridge and replace the desktop update redirect flow with an in-app update dialog in the dashboard header.

New Features:

  • Add an in-app desktop update dialog in the vertical header for desktop release mode, powered by a generic updater bridge.
  • Expose a generic window.astrbotAppUpdater interface for checking and installing desktop app updates from the dashboard.

Enhancements:

  • Generalize desktop bridge TypeScript definitions (desktop-bridge.d.ts) and extend window.astrbotDesktop typings to support backend control and desktop update operations.

Documentation:

  • Add i18n strings for desktop app update states in English and Chinese locales.

新功能:

  • 在纵向头部中,为桌面发布模式添加一个由通用更新桥接层驱动的应用内桌面更新对话框。
  • 暴露通用的 window.astrbotAppUpdater 接口,以支持从仪表盘检查并安装桌面应用更新。

增强:

  • 使用通用的 desktop-bridge TypeScript 定义替换原有的 Electron 专用桥接类型,并扩展 window.astrbotDesktop 运行时类型,以支持后端控制和桌面更新操作。

文档:

  • 为桌面应用更新状态新增本地化 i18n 字符串,涵盖英文和中文。
Original summary in English

Summary by Sourcery

引入通用的桌面应用更新桥接层,并将原有的桌面更新跳转流程替换为仪表盘顶部栏中的应用内更新对话框。

新功能:

  • 在桌面发布模式下,为垂直顶部栏添加一个基于通用更新桥接层驱动的桌面应用内更新对话框。
  • 暴露通用的 window.astrbotAppUpdater 接口,用于在仪表盘中检查和安装桌面应用更新。

增强:

  • 泛化桌面桥接的 TypeScript 定义(desktop-bridge.d.ts),并扩展 window.astrbotDesktop 类型,以支持后端控制和桌面更新操作。

文档:

  • 为桌面应用更新状态在英文和中文语言环境中添加 i18n 文本。
Original summary in English

Summary by Sourcery

Introduce a generic desktop app updater bridge and replace the desktop update redirect flow with an in-app update dialog in the dashboard header.

New Features:

  • Add an in-app desktop update dialog in the vertical header for desktop release mode, powered by a generic updater bridge.
  • Expose a generic window.astrbotAppUpdater interface for checking and installing desktop app updates from the dashboard.

Enhancements:

  • Generalize desktop bridge TypeScript definitions (desktop-bridge.d.ts) and extend window.astrbotDesktop typings to support backend control and desktop update operations.

Documentation:

  • Add i18n strings for desktop app update states in English and Chinese locales.

新功能:

  • 在纵向头部中,为桌面发布模式添加一个应用内桌面更新弹窗,由通用应用更新桥接层驱动。
  • 暴露通用的 window.astrbotAppUpdater 接口,用于在控制台中检查和安装桌面应用更新。

增强:

  • 定义新的桌面桥接 TypeScript 类型文件(desktop-bridge.d.ts),并移除特定于 Electron 的桥接声明文件,以泛化桌面端集成。
  • 扩展 window.astrbotDesktop 运行时类型声明,以覆盖后端控制和桌面应用更新操作。

文档:

  • 为桌面应用更新状态新增本地化的 i18n 字符串,支持英文和中文。
Original summary in English

Summary by Sourcery

引入通用的桌面应用更新桥接层,并将原有的桌面更新跳转流程替换为仪表盘顶部栏中的应用内更新对话框。

新功能:

  • 在桌面发布模式下,为垂直顶部栏添加一个基于通用更新桥接层驱动的桌面应用内更新对话框。
  • 暴露通用的 window.astrbotAppUpdater 接口,用于在仪表盘中检查和安装桌面应用更新。

增强:

  • 泛化桌面桥接的 TypeScript 定义(desktop-bridge.d.ts),并扩展 window.astrbotDesktop 类型,以支持后端控制和桌面更新操作。

文档:

  • 为桌面应用更新状态在英文和中文语言环境中添加 i18n 文本。
Original summary in English

Summary by Sourcery

Introduce a generic desktop app updater bridge and replace the desktop update redirect flow with an in-app update dialog in the dashboard header.

New Features:

  • Add an in-app desktop update dialog in the vertical header for desktop release mode, powered by a generic updater bridge.
  • Expose a generic window.astrbotAppUpdater interface for checking and installing desktop app updates from the dashboard.

Enhancements:

  • Generalize desktop bridge TypeScript definitions (desktop-bridge.d.ts) and extend window.astrbotDesktop typings to support backend control and desktop update operations.

Documentation:

  • Add i18n strings for desktop app update states in English and Chinese locales.

新功能:

  • 在纵向头部中,为桌面发布模式添加一个由通用更新桥接层驱动的应用内桌面更新对话框。
  • 暴露通用的 window.astrbotAppUpdater 接口,以支持从仪表盘检查并安装桌面应用更新。

增强:

  • 使用通用的 desktop-bridge TypeScript 定义替换原有的 Electron 专用桥接类型,并扩展 window.astrbotDesktop 运行时类型,以支持后端控制和桌面更新操作。

文档:

  • 为桌面应用更新状态新增本地化 i18n 字符串,涵盖英文和中文。
Original summary in English

Summary by Sourcery

引入通用的桌面应用更新桥接层,并将原有的桌面更新跳转流程替换为仪表盘顶部栏中的应用内更新对话框。

新功能:

  • 在桌面发布模式下,为垂直顶部栏添加一个基于通用更新桥接层驱动的桌面应用内更新对话框。
  • 暴露通用的 window.astrbotAppUpdater 接口,用于在仪表盘中检查和安装桌面应用更新。

增强:

  • 泛化桌面桥接的 TypeScript 定义(desktop-bridge.d.ts),并扩展 window.astrbotDesktop 类型,以支持后端控制和桌面更新操作。

文档:

  • 为桌面应用更新状态在英文和中文语言环境中添加 i18n 文本。
Original summary in English

Summary by Sourcery

Introduce a generic desktop app updater bridge and replace the desktop update redirect flow with an in-app update dialog in the dashboard header.

New Features:

  • Add an in-app desktop update dialog in the vertical header for desktop release mode, powered by a generic updater bridge.
  • Expose a generic window.astrbotAppUpdater interface for checking and installing desktop app updates from the dashboard.

Enhancements:

  • Generalize desktop bridge TypeScript definitions (desktop-bridge.d.ts) and extend window.astrbotDesktop typings to support backend control and desktop update operations.

Documentation:

  • Add i18n strings for desktop app update states in English and Chinese locales.

新功能:

  • 在纵向头部中为桌面发布模式添加应用内桌面更新对话框。
  • 暴露通用的 window.astrbotAppUpdater 桥接接口,用于桌面应用更新检查与安装。

增强:

  • 更新桌面桥接的类型定义,并将 Electron 桥接声明文件重命名为更通用的桌面桥接文件。
  • window.astrbotDesktop 上扩展桌面运行时类型,用于后端控制和桌面应用更新操作。

文档:

  • 为桌面应用更新状态添加 i18n 字符串,覆盖英文和中文两种本地化。
Original summary in English

Summary by Sourcery

引入通用的桌面应用更新桥接层,并将原有的桌面更新跳转流程替换为仪表盘顶部栏中的应用内更新对话框。

新功能:

  • 在桌面发布模式下,为垂直顶部栏添加一个基于通用更新桥接层驱动的桌面应用内更新对话框。
  • 暴露通用的 window.astrbotAppUpdater 接口,用于在仪表盘中检查和安装桌面应用更新。

增强:

  • 泛化桌面桥接的 TypeScript 定义(desktop-bridge.d.ts),并扩展 window.astrbotDesktop 类型,以支持后端控制和桌面更新操作。

文档:

  • 为桌面应用更新状态在英文和中文语言环境中添加 i18n 文本。
Original summary in English

Summary by Sourcery

Introduce a generic desktop app updater bridge and replace the desktop update redirect flow with an in-app update dialog in the dashboard header.

New Features:

  • Add an in-app desktop update dialog in the vertical header for desktop release mode, powered by a generic updater bridge.
  • Expose a generic window.astrbotAppUpdater interface for checking and installing desktop app updates from the dashboard.

Enhancements:

  • Generalize desktop bridge TypeScript definitions (desktop-bridge.d.ts) and extend window.astrbotDesktop typings to support backend control and desktop update operations.

Documentation:

  • Add i18n strings for desktop app update states in English and Chinese locales.

新功能:

  • 在纵向头部中,为桌面发布模式添加一个由通用更新桥接层驱动的应用内桌面更新对话框。
  • 暴露通用的 window.astrbotAppUpdater 接口,以支持从仪表盘检查并安装桌面应用更新。

增强:

  • 使用通用的 desktop-bridge TypeScript 定义替换原有的 Electron 专用桥接类型,并扩展 window.astrbotDesktop 运行时类型,以支持后端控制和桌面更新操作。

文档:

  • 为桌面应用更新状态新增本地化 i18n 字符串,涵盖英文和中文。
Original summary in English

Summary by Sourcery

引入通用的桌面应用更新桥接层,并将原有的桌面更新跳转流程替换为仪表盘顶部栏中的应用内更新对话框。

新功能:

  • 在桌面发布模式下,为垂直顶部栏添加一个基于通用更新桥接层驱动的桌面应用内更新对话框。
  • 暴露通用的 window.astrbotAppUpdater 接口,用于在仪表盘中检查和安装桌面应用更新。

增强:

  • 泛化桌面桥接的 TypeScript 定义(desktop-bridge.d.ts),并扩展 window.astrbotDesktop 类型,以支持后端控制和桌面更新操作。

文档:

  • 为桌面应用更新状态在英文和中文语言环境中添加 i18n 文本。
Original summary in English

Summary by Sourcery

Introduce a generic desktop app updater bridge and replace the desktop update redirect flow with an in-app update dialog in the dashboard header.

New Features:

  • Add an in-app desktop update dialog in the vertical header for desktop release mode, powered by a generic updater bridge.
  • Expose a generic window.astrbotAppUpdater interface for checking and installing desktop app updates from the dashboard.

Enhancements:

  • Generalize desktop bridge TypeScript definitions (desktop-bridge.d.ts) and extend window.astrbotDesktop typings to support backend control and desktop update operations.

Documentation:

  • Add i18n strings for desktop app update states in English and Chinese locales.

新功能:

  • 在纵向头部中,为桌面发布模式添加一个应用内桌面更新弹窗,由通用应用更新桥接层驱动。
  • 暴露通用的 window.astrbotAppUpdater 接口,用于在控制台中检查和安装桌面应用更新。

增强:

  • 定义新的桌面桥接 TypeScript 类型文件(desktop-bridge.d.ts),并移除特定于 Electron 的桥接声明文件,以泛化桌面端集成。
  • 扩展 window.astrbotDesktop 运行时类型声明,以覆盖后端控制和桌面应用更新操作。

文档:

  • 为桌面应用更新状态新增本地化的 i18n 字符串,支持英文和中文。
Original summary in English

Summary by Sourcery

引入通用的桌面应用更新桥接层,并将原有的桌面更新跳转流程替换为仪表盘顶部栏中的应用内更新对话框。

新功能:

  • 在桌面发布模式下,为垂直顶部栏添加一个基于通用更新桥接层驱动的桌面应用内更新对话框。
  • 暴露通用的 window.astrbotAppUpdater 接口,用于在仪表盘中检查和安装桌面应用更新。

增强:

  • 泛化桌面桥接的 TypeScript 定义(desktop-bridge.d.ts),并扩展 window.astrbotDesktop 类型,以支持后端控制和桌面更新操作。

文档:

  • 为桌面应用更新状态在英文和中文语言环境中添加 i18n 文本。
Original summary in English

Summary by Sourcery

Introduce a generic desktop app updater bridge and replace the desktop update redirect flow with an in-app update dialog in the dashboard header.

New Features:

  • Add an in-app desktop update dialog in the vertical header for desktop release mode, powered by a generic updater bridge.
  • Expose a generic window.astrbotAppUpdater interface for checking and installing desktop app updates from the dashboard.

Enhancements:

  • Generalize desktop bridge TypeScript definitions (desktop-bridge.d.ts) and extend window.astrbotDesktop typings to support backend control and desktop update operations.

Documentation:

  • Add i18n strings for desktop app update states in English and Chinese locales.

新功能:

  • 在纵向头部中,为桌面发布模式添加一个由通用更新桥接层驱动的应用内桌面更新对话框。
  • 暴露通用的 window.astrbotAppUpdater 接口,以支持从仪表盘检查并安装桌面应用更新。

增强:

  • 使用通用的 desktop-bridge TypeScript 定义替换原有的 Electron 专用桥接类型,并扩展 window.astrbotDesktop 运行时类型,以支持后端控制和桌面更新操作。

文档:

  • 为桌面应用更新状态新增本地化 i18n 字符串,涵盖英文和中文。
Original summary in English

Summary by Sourcery

引入通用的桌面应用更新桥接层,并将原有的桌面更新跳转流程替换为仪表盘顶部栏中的应用内更新对话框。

新功能:

  • 在桌面发布模式下,为垂直顶部栏添加一个基于通用更新桥接层驱动的桌面应用内更新对话框。
  • 暴露通用的 window.astrbotAppUpdater 接口,用于在仪表盘中检查和安装桌面应用更新。

增强:

  • 泛化桌面桥接的 TypeScript 定义(desktop-bridge.d.ts),并扩展 window.astrbotDesktop 类型,以支持后端控制和桌面更新操作。

文档:

  • 为桌面应用更新状态在英文和中文语言环境中添加 i18n 文本。
Original summary in English

Summary by Sourcery

Introduce a generic desktop app updater bridge and replace the desktop update redirect flow with an in-app update dialog in the dashboard header.

New Features:

  • Add an in-app desktop update dialog in the vertical header for desktop release mode, powered by a generic updater bridge.
  • Expose a generic window.astrbotAppUpdater interface for checking and installing desktop app updates from the dashboard.

Enhancements:

  • Generalize desktop bridge TypeScript definitions (desktop-bridge.d.ts) and extend window.astrbotDesktop typings to support backend control and desktop update operations.

Documentation:

  • Add i18n strings for desktop app update states in English and Chinese locales.

@auto-assign auto-assign bot requested review from Raven95676 and Soulter February 25, 2026 00:44
@dosubot dosubot bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Feb 25, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @zouyonghe, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly improves the desktop application update process by transitioning from an external redirect mechanism to an integrated in-app dialog. This change not only enhances the user experience by keeping updates within the application interface but also refactors the underlying architecture to be more generic and less coupled to specific desktop runtime implementations. The introduction of a new, standardized updater interface allows for greater flexibility and maintainability, ensuring that the dashboard remains reusable across different desktop environments.

Highlights

  • In-App Desktop Update Dialog: Replaced the previous desktop update redirect flow with a new, integrated in-app desktop update dialog within VerticalHeader.vue, providing a more seamless user experience.
  • Decoupled Desktop Updater Interface: Introduced a generic window.astrbotAppUpdater interface to decouple the dashboard from astrbotDesktop-specific methods, enhancing modularity and reusability for different desktop shell implementations.
  • Bridge Typings Refactor: Renamed electron-bridge.d.ts to desktop-bridge.d.ts and updated global bridge typings to reflect the new generic desktop bridge architecture.
  • Internationalization Support: Added new i18n messages for various desktop app update states in both English (en-US) and Simplified Chinese (zh-CN) locales to support the new update dialog.
Changelog
  • dashboard/src/i18n/locales/en-US/core/header.json
    • Added new desktopApp object with keys for desktop update dialog title, message, version display, and various update statuses (checking, has new version, installing, failed).
  • dashboard/src/i18n/locales/zh-CN/core/header.json
    • Added new desktopApp object with keys for desktop update dialog title, message, version display, and various update statuses in Simplified Chinese.
  • dashboard/src/layouts/full/vertical-header/VerticalHeader.vue
    • Removed redirectConfirmDialog, pendingRedirectUrl, resolvingReleaseTarget, DEFAULT_ASTRBOT_RELEASE_BASE_URL, resolveReleaseBaseUrl, releaseBaseUrl, getReleaseUrlByTag, latestReleaseTag, open, requestExternalRedirect, cancelExternalRedirect, confirmExternalRedirect, and getReleaseUrlForDesktop related to the old redirect update flow.
    • Added new reactive state variables: desktopUpdateDialog, desktopUpdateChecking, desktopUpdateInstalling, desktopUpdateHasNewVersion, desktopUpdateCurrentVersion, desktopUpdateLatestVersion, and desktopUpdateStatus for the new in-app update dialog.
    • Defined AppUpdaterBridge type interface for checkForAppUpdate and installAppUpdate methods.
    • Implemented getAppUpdaterBridge function to safely retrieve the generic window.astrbotAppUpdater bridge.
    • Added cancelDesktopUpdate function to close the update dialog.
    • Implemented openDesktopUpdateDialog asynchronous function to initialize and manage the desktop update check process, updating status and version information.
    • Added confirmDesktopUpdate asynchronous function to initiate the desktop app installation process.
    • Modified handleUpdateClick to conditionally call openDesktopUpdateDialog for desktop release mode or checkUpdate for other modes.
    • Updated the template to replace the old redirectConfirmDialog with the new desktopUpdateDialog, displaying current/latest versions, update status, and appropriate action buttons with loading/disabled states.
  • dashboard/src/types/desktop-bridge.d.ts
    • Added a new type definition file.
    • Declared AstrBotAppUpdaterBridge interface with checkForAppUpdate and installAppUpdate methods.
    • Extended the global Window interface to include an optional astrbotAppUpdater property of type AstrBotAppUpdaterBridge.
    • Extended the existing astrbotDesktop interface within Window to include checkDesktopAppUpdate and installDesktopAppUpdate methods, mirroring the new generic updater functionality.
  • dashboard/src/types/electron-bridge.d.ts
    • Removed the file, as its functionality has been superseded and refactored into desktop-bridge.d.ts.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@dosubot dosubot bot added area:webui The bug / feature is about webui(dashboard) of astrbot. feature:updater The bug / feature is about astrbot updater system labels Feb 25, 2026
@dosubot
Copy link

dosubot bot commented Feb 25, 2026

Related Documentation

Checked 1 published document(s) in 1 knowledge base(s). No updates required.

How did I do? Any feedback?  Join Discord

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - 我发现了两个问题,并留下了一些整体性的反馈:

  • VerticalHeader.vue 中,AppUpdaterBridgedesktop-bridge.d.ts 中新的全局类型 AstrBotAppUpdaterBridge 重复;建议复用该全局类型(例如通过 Window['astrbotAppUpdater'])以避免两套接口未来出现差异。
  • VerticalHeader.vue 中的 getAppUpdaterBridge 以及其他直接访问 window 的代码没有通过 typeof window !== 'undefined' 做保护;如果该组件未来在 SSR 场景中渲染,增加这一保护可以避免运行时错误。
给 AI Agent 的提示
Please address the comments from this code review:

## Overall Comments
- In `VerticalHeader.vue`, `AppUpdaterBridge` duplicates the new global `AstrBotAppUpdaterBridge` type from `desktop-bridge.d.ts`; consider reusing the global type (e.g. via `Window['astrbotAppUpdater']`) to avoid divergence between the two interfaces.
- `getAppUpdaterBridge` and other direct `window` accesses in `VerticalHeader.vue` aren’t guarded by a `typeof window !== 'undefined'` check; if this component is ever rendered in an SSR context, adding that guard would prevent runtime errors.

## Individual Comments

### Comment 1
<location path="dashboard/src/layouts/full/vertical-header/VerticalHeader.vue" line_range="61-68" />
<code_context>
+const desktopUpdateLatestVersion = ref('-');
+const desktopUpdateStatus = ref('');
+
+type AppUpdaterBridge = {
+  checkForAppUpdate: () => Promise<{
+    ok: boolean;
+    reason: string | null;
+    currentVersion: string;
+    latestVersion: string | null;
+    hasUpdate: boolean;
+  }>;
+  installAppUpdate: () => Promise<{
+    ok: boolean;
</code_context>
<issue_to_address>
**suggestion:** Avoid duplicating the updater bridge type that already exists in the global typings to prevent future drift.

You can either type `getAppUpdaterBridge` to return `AstrBotAppUpdaterBridge | null`, or introduce a local alias:

```ts
type AppUpdaterBridge = AstrBotAppUpdaterBridge;
```

This avoids redefining the full shape locally.
</issue_to_address>

### Comment 2
<location path="dashboard/src/layouts/full/vertical-header/VerticalHeader.vue" line_range="182-191" />
<code_context>
-  cancelExternalRedirect();
-  if (targetUrl) {
-    open(targetUrl);
+async function confirmDesktopUpdate() {
+  if (!desktopUpdateHasNewVersion.value || desktopUpdateInstalling.value) {
+    return;
   }
-}

-const getReleaseUrlForDesktop = () => {
-  const firstRelease = (releases.value as any[])?.[0];
-  if (firstRelease?.tag_name) {
-    return getReleaseUrlByTag(firstRelease.tag_name as string);
+  const bridge = getAppUpdaterBridge();
+  if (!bridge) {
+    desktopUpdateStatus.value = t('core.header.updateDialog.desktopApp.installFailed');
+    return;
   }
-  if (hasNewVersion.value) return getReleaseUrlByTag('latest');
-  const tag = botCurrVersion.value?.startsWith('v') ? botCurrVersion.value : 'latest';
-  return getReleaseUrlByTag(tag);
-};
+
+  desktopUpdateInstalling.value = true;
+  desktopUpdateStatus.value = t('core.header.updateDialog.desktopApp.installing');
+
+  try {
</code_context>
<issue_to_address>
**question (bug_risk):** On successful install, the dialog status remains "installing" and the dialog never closes, which may confuse users.

In `confirmDesktopUpdate`, when `result?.ok` is true, `desktopUpdateStatus` is set back to the "installing" message and the function returns. `desktopUpdateInstalling` is then reset to `false` in `finally`, leaving the dialog open with an "installing" label even though the install succeeded. Consider either showing an explicit success/"installed" status, or closing the dialog (optionally with a restart prompt) when installation is reported as successful so the user sees a clear completion state.
</issue_to_address>

Sourcery 对开源项目免费使用——如果你觉得我们的评审有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续评审。
Original comment in English

Hey - I've found 2 issues, and left some high level feedback:

  • In VerticalHeader.vue, AppUpdaterBridge duplicates the new global AstrBotAppUpdaterBridge type from desktop-bridge.d.ts; consider reusing the global type (e.g. via Window['astrbotAppUpdater']) to avoid divergence between the two interfaces.
  • getAppUpdaterBridge and other direct window accesses in VerticalHeader.vue aren’t guarded by a typeof window !== 'undefined' check; if this component is ever rendered in an SSR context, adding that guard would prevent runtime errors.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `VerticalHeader.vue`, `AppUpdaterBridge` duplicates the new global `AstrBotAppUpdaterBridge` type from `desktop-bridge.d.ts`; consider reusing the global type (e.g. via `Window['astrbotAppUpdater']`) to avoid divergence between the two interfaces.
- `getAppUpdaterBridge` and other direct `window` accesses in `VerticalHeader.vue` aren’t guarded by a `typeof window !== 'undefined'` check; if this component is ever rendered in an SSR context, adding that guard would prevent runtime errors.

## Individual Comments

### Comment 1
<location path="dashboard/src/layouts/full/vertical-header/VerticalHeader.vue" line_range="61-68" />
<code_context>
+const desktopUpdateLatestVersion = ref('-');
+const desktopUpdateStatus = ref('');
+
+type AppUpdaterBridge = {
+  checkForAppUpdate: () => Promise<{
+    ok: boolean;
+    reason: string | null;
+    currentVersion: string;
+    latestVersion: string | null;
+    hasUpdate: boolean;
+  }>;
+  installAppUpdate: () => Promise<{
+    ok: boolean;
</code_context>
<issue_to_address>
**suggestion:** Avoid duplicating the updater bridge type that already exists in the global typings to prevent future drift.

You can either type `getAppUpdaterBridge` to return `AstrBotAppUpdaterBridge | null`, or introduce a local alias:

```ts
type AppUpdaterBridge = AstrBotAppUpdaterBridge;
```

This avoids redefining the full shape locally.
</issue_to_address>

### Comment 2
<location path="dashboard/src/layouts/full/vertical-header/VerticalHeader.vue" line_range="182-191" />
<code_context>
-  cancelExternalRedirect();
-  if (targetUrl) {
-    open(targetUrl);
+async function confirmDesktopUpdate() {
+  if (!desktopUpdateHasNewVersion.value || desktopUpdateInstalling.value) {
+    return;
   }
-}

-const getReleaseUrlForDesktop = () => {
-  const firstRelease = (releases.value as any[])?.[0];
-  if (firstRelease?.tag_name) {
-    return getReleaseUrlByTag(firstRelease.tag_name as string);
+  const bridge = getAppUpdaterBridge();
+  if (!bridge) {
+    desktopUpdateStatus.value = t('core.header.updateDialog.desktopApp.installFailed');
+    return;
   }
-  if (hasNewVersion.value) return getReleaseUrlByTag('latest');
-  const tag = botCurrVersion.value?.startsWith('v') ? botCurrVersion.value : 'latest';
-  return getReleaseUrlByTag(tag);
-};
+
+  desktopUpdateInstalling.value = true;
+  desktopUpdateStatus.value = t('core.header.updateDialog.desktopApp.installing');
+
+  try {
</code_context>
<issue_to_address>
**question (bug_risk):** On successful install, the dialog status remains "installing" and the dialog never closes, which may confuse users.

In `confirmDesktopUpdate`, when `result?.ok` is true, `desktopUpdateStatus` is set back to the "installing" message and the function returns. `desktopUpdateInstalling` is then reset to `false` in `finally`, leaving the dialog open with an "installing" label even though the install succeeded. Consider either showing an explicit success/"installed" status, or closing the dialog (optionally with a restart prompt) when installation is reported as successful so the user sees a clear completion state.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request successfully introduces a generic desktop app updater bridge, effectively decoupling the dashboard from specific desktop runtime implementations. The new in-app update dialog enhances the user experience by providing a streamlined update process. The changes to i18n messages and Vue component logic are well-implemented, supporting the new functionality.

Comment on lines 37 to 47
checkDesktopAppUpdate: () => Promise<{
ok: boolean;
reason: string | null;
currentVersion: string;
latestVersion: string | null;
hasUpdate: boolean;
}>;
installDesktopAppUpdate: () => Promise<{
ok: boolean;
reason: string | null;
}>;
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The astrbotDesktop interface still includes checkDesktopAppUpdate and installDesktopAppUpdate. The pull request description mentions decoupling the dashboard from astrbotDesktop-specific methods by introducing a generic window.astrbotAppUpdater interface. To fully achieve this decoupling and avoid potential confusion or redundant implementations, these update-related methods should ideally be removed from astrbotDesktop and exclusively exposed through astrbotAppUpdater.

? t('core.header.updateDialog.desktopApp.hasNewVersion')
: t('core.header.updateDialog.desktopApp.isLatest');
} catch (error) {
console.log(error);
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The console.log(error) statement is quite generic. For better debugging and monitoring in a production environment, consider adding more context to the log message, such as the function name (openDesktopUpdateDialog) and a descriptive string. This would help in quickly identifying the source of the error.

    console.error('[DesktopUpdate] Failed to check for app update:', error);

desktopUpdateStatus.value =
result?.reason || t('core.header.updateDialog.desktopApp.installFailed');
} catch (error) {
console.log(error);
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Similar to the previous comment, this console.log(error) could benefit from more context. Providing the function name (confirmDesktopUpdate) and a descriptive message would improve debuggability.

    console.error('[DesktopUpdate] Failed to install app update:', error);

@zouyonghe
Copy link
Member Author

@sourcery-ai review

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - 我在这里给了一些整体性的反馈:

  • desktop-bridge.d.ts 中新的 AstrBotAppUpdaterBridge 接口与 astrbotDesktop 上现有的 checkDesktopAppUpdate/installDesktopAppUpdate 结构重复;建议将它们统一起来(例如复用一个共享接口或弃用其中一侧),以避免这两个更新器约定逐渐产生差异。
  • 在新的桌面更新流程中(openDesktopUpdateDialog/confirmDesktopUpdate),建议将 catch 块中的 console.log(error) 改为 console.error(error)(或使用共享的错误日志记录器),以便在日志中更容易发现和筛选更新失败。
给 AI Agent 的提示
Please address the comments from this code review:

## Overall Comments
- The new `AstrBotAppUpdaterBridge` interface in `desktop-bridge.d.ts` duplicates the existing `checkDesktopAppUpdate`/`installDesktopAppUpdate` shape on `astrbotDesktop`; consider unifying these (e.g., reusing a shared interface or deprecating one side) to avoid the two updater contracts drifting apart.
- In the new desktop update flow (`openDesktopUpdateDialog`/`confirmDesktopUpdate`), switch `console.log(error)` in the catch blocks to `console.error(error)` (or a shared error logger) so update failures are easier to spot and filter in logs.

Sourcery 对开源项目是免费的 —— 如果你觉得我们的代码审查有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续的代码审查。
Original comment in English

Hey - I've left some high level feedback:

  • The new AstrBotAppUpdaterBridge interface in desktop-bridge.d.ts duplicates the existing checkDesktopAppUpdate/installDesktopAppUpdate shape on astrbotDesktop; consider unifying these (e.g., reusing a shared interface or deprecating one side) to avoid the two updater contracts drifting apart.
  • In the new desktop update flow (openDesktopUpdateDialog/confirmDesktopUpdate), switch console.log(error) in the catch blocks to console.error(error) (or a shared error logger) so update failures are easier to spot and filter in logs.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `AstrBotAppUpdaterBridge` interface in `desktop-bridge.d.ts` duplicates the existing `checkDesktopAppUpdate`/`installDesktopAppUpdate` shape on `astrbotDesktop`; consider unifying these (e.g., reusing a shared interface or deprecating one side) to avoid the two updater contracts drifting apart.
- In the new desktop update flow (`openDesktopUpdateDialog`/`confirmDesktopUpdate`), switch `console.log(error)` in the catch blocks to `console.error(error)` (or a shared error logger) so update failures are easier to spot and filter in logs.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@zouyonghe
Copy link
Member Author

@sourcery-ai review

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - 我发现了 1 个问题,并给出了一些整体性的反馈:

  • 新增的 astrbotAppUpdater bridge 与 window.astrbotDesktop 上的 checkDesktopAppUpdate/installDesktopAppUpdate 并存;建议合并这两条路径,或者明确废弃其中一条,以避免在桌面外壳侧出现重复的更新器契约。
  • getAppUpdaterBridge 中,你是从 Window['astrbotAppUpdater'] 重新派生了一个更窄的 AppUpdaterBridge 类型;你可以直接引用全局声明的 AstrBotAppUpdaterBridge 来简化逻辑,使 Vue 代码和 bridge 类型保持紧密一致。
给 AI 代理的提示
Please address the comments from this code review:

## Overall Comments
- 新增的 `astrbotAppUpdater` bridge 与 `window.astrbotDesktop` 上的 `checkDesktopAppUpdate`/`installDesktopAppUpdate` 并存;建议合并这两条路径,或者明确废弃其中一条,以避免在桌面外壳侧出现重复的更新器契约。
-`getAppUpdaterBridge` 中,你是从 `Window['astrbotAppUpdater']` 重新派生了一个更窄的 `AppUpdaterBridge` 类型;你可以直接引用全局声明的 `AstrBotAppUpdaterBridge` 来简化逻辑,使 Vue 代码和 bridge 类型保持紧密一致。

## Individual Comments

### Comment 1
<location path="dashboard/src/types/desktop-bridge.d.ts" line_range="4-9" />
<code_context>
+export {};
+
+declare global {
+  interface AstrBotDesktopAppUpdateCheckResult {
+    ok: boolean;
+    reason: string | null;
+    currentVersion: string;
+    latestVersion: string | null;
+    hasUpdate: boolean;
+  }
+
</code_context>
<issue_to_address>
**suggestion:** 让更新检查结果字段的类型与实际使用方式保持一致(例如,在失败时 `reason`/版本字段可能不存在)。

`checkForAppUpdate` 的 Vue 使用方把 `reason``currentVersion``latestVersion` 视为可选/可为空(`result?.reason``result?.currentVersion || '-'` 等),而该接口却将 `reason``currentVersion` 声明为必填。这种不匹配可能会误导 bridge 的实现者,以为这些字段必须始终被设置。建议让类型与运行时行为对齐,放宽限制,例如使用 `reason?: string | null``currentVersion?: string``latestVersion?: string | null`。
</issue_to_address>

Sourcery 对开源项目是免费的 —— 如果你觉得这些评审有帮助,欢迎分享 ✨
帮我变得更有用!请在每条评论上点击 👍 或 👎,我会根据反馈改进后续评审。
Original comment in English

Hey - I've found 1 issue, and left some high level feedback:

  • The new astrbotAppUpdater bridge lives alongside checkDesktopAppUpdate/installDesktopAppUpdate on window.astrbotDesktop; consider consolidating or clearly deprecating one of these paths to avoid duplicated updater contracts on the desktop shell side.
  • In getAppUpdaterBridge, you’re re-deriving a narrower AppUpdaterBridge type from Window['astrbotAppUpdater']; you could simplify by referencing the globally declared AstrBotAppUpdaterBridge directly so the Vue code and bridge typings stay tightly coupled.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The new `astrbotAppUpdater` bridge lives alongside `checkDesktopAppUpdate`/`installDesktopAppUpdate` on `window.astrbotDesktop`; consider consolidating or clearly deprecating one of these paths to avoid duplicated updater contracts on the desktop shell side.
- In `getAppUpdaterBridge`, you’re re-deriving a narrower `AppUpdaterBridge` type from `Window['astrbotAppUpdater']`; you could simplify by referencing the globally declared `AstrBotAppUpdaterBridge` directly so the Vue code and bridge typings stay tightly coupled.

## Individual Comments

### Comment 1
<location path="dashboard/src/types/desktop-bridge.d.ts" line_range="4-9" />
<code_context>
+export {};
+
+declare global {
+  interface AstrBotDesktopAppUpdateCheckResult {
+    ok: boolean;
+    reason: string | null;
+    currentVersion: string;
+    latestVersion: string | null;
+    hasUpdate: boolean;
+  }
+
</code_context>
<issue_to_address>
**suggestion:** Align the typings of update check result fields with how they’re consumed (e.g., `reason`/versions may be absent on failure).

The Vue consumer of `checkForAppUpdate` treats `reason`, `currentVersion`, and `latestVersion` as optional/nullable (`result?.reason`, `result?.currentVersion || '-'`, etc.), while this interface makes `reason` and `currentVersion` required. That mismatch may incorrectly signal to bridge implementers that these must always be set. Consider matching the runtime behavior with looser types, e.g. `reason?: string | null`, `currentVersion?: string`, `latestVersion?: string | null`.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@zouyonghe
Copy link
Member Author

@sourcery-ai review

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

嗨,我已经审查了你的更改,看起来非常棒!


Sourcery 对开源项目是免费的——如果你觉得我们的代码审查有帮助,欢迎分享 ✨
让我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续的代码审查。
Original comment in English

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@zouyonghe zouyonghe merged commit 5530a22 into AstrBotDevs:master Feb 25, 2026
6 checks passed
astrbot-doc-agent bot pushed a commit to AstrBotDevs/AstrBot-docs that referenced this pull request Feb 25, 2026
@astrbot-doc-agent
Copy link

Generated docs update PR (pending manual review):
AstrBotDevs/AstrBot-docs#148
Trigger: PR merged


AI change summary:

  • 修改文件 zh/use/webui.mden/use/webui.md,重构“更新”章节结构。
  • 新增“更新桌面应用”子章节,说明桌面客户端用户可在管理面板顶部栏点击按钮进行更新。
  • 描述更新流程:显示版本信息、检查更新、自动下载安装及重启。
  • 添加 NOTE 提示:此功能仅限桌面客户端模式,Docker 或手动部署用户需使用其他方式。
  • i18n:中英文文档已同步更新。

Experimental bot notice:

  • This output is generated by AstrBot-Doc-Agent for review only.
  • It does not represent the final documentation form.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:webui The bug / feature is about webui(dashboard) of astrbot. feature:updater The bug / feature is about astrbot updater system size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant