fix: correct outdated plugin marketplace update prompt#9009
fix: correct outdated plugin marketplace update prompt#9009Sisyphbaous-DT-Project wants to merge 2 commits into
Conversation
There was a problem hiding this comment.
Hey - I've found 2 issues, and left some high level feedback:
- The new
parsePluginVersion/comparePluginVersionslogic duplicates some of the normalization currently done (e.g.,normalizeAstrBotVersionSpec), and might be clearer and easier to maintain if you centralize version normalization/comparison into a single shared helper or utility. - When
comparePluginVersionsreturnsnullfor invalid or non-semver-like version strings,has_updateandversion_source_aheadsilently becomefalse; consider explicitly handling this case (e.g. with a fallback state or UI) so users can see that the versions could not be compared instead of just seeing no update indicators.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The new `parsePluginVersion` / `comparePluginVersions` logic duplicates some of the normalization currently done (e.g., `normalizeAstrBotVersionSpec`), and might be clearer and easier to maintain if you centralize version normalization/comparison into a single shared helper or utility.
- When `comparePluginVersions` returns `null` for invalid or non-semver-like version strings, `has_update` and `version_source_ahead` silently become `false`; consider explicitly handling this case (e.g. with a fallback state or UI) so users can see that the versions could not be compared instead of just seeing no update indicators.
## Individual Comments
### Comment 1
<location path="dashboard/src/views/extension/useExtensionPage.js" line_range="662-670" />
<code_context>
if (matchedPlugin) {
extension.online_version = matchedPlugin.version;
+ const onlineVersion = String(matchedPlugin.version || "").trim();
+ const versionComparison = comparePluginVersions(
+ extension.version,
+ onlineVersion,
+ );
+
+ extension.version_source_ahead =
+ typeof versionComparison === "number" && versionComparison > 0;
extension.has_update =
- extension.version !== matchedPlugin.version &&
- matchedPlugin.version !== tm("status.unknown");
+ typeof versionComparison === "number" && versionComparison < 0;
} else {
extension.online_version = "";
</code_context>
<issue_to_address>
**question (bug_risk):** Unparseable versions now suppress update indicators; consider a fallback comparison.
If either `extension.version` or `matchedPlugin.version` fails `parsePluginVersion`, `comparePluginVersions` returns `null`, so both `has_update` and `version_source_ahead` stay `false` even when the raw version strings differ. Previously, non-`status.unknown` mismatches still flagged an update. If real-world versions may not match the regex (e.g. custom tags), this could hide updates; consider a fallback when `versionComparison === null` (e.g. string inequality or treating these as `status.unknown`), aligned with the intended UX.
</issue_to_address>
### Comment 2
<location path="dashboard/src/views/extension/useExtensionPage.js" line_range="1315" />
<code_context>
+ };
+ };
+
+ const comparePluginVersions = (left, right) => {
+ const leftVersion = parsePluginVersion(left);
+ const rightVersion = parsePluginVersion(right);
</code_context>
<issue_to_address>
**issue (complexity):** Consider simplifying version comparison semantics by normalizing invalid versions and using clear ahead/behind helpers so the hook focuses on intent rather than semver details.
You can keep the improved accuracy while reducing complexity and making the intent clearer by:
### 1. Normalize invalid versions *before* comparison
Instead of returning `null` and forcing `typeof === "number"` checks at each callsite, handle invalid versions inside the helper and always return `-1 | 0 | 1`. For example:
```js
const parsePluginVersion = (value) => {
const version = String(value || "").trim().replace(/^v/i, "");
const match = version.match(
/^([0-9]+(?:\.[0-9]+)*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+(.+))?$/
);
if (!match) {
return null;
}
return {
parts: match[1].split(".").map((part) => Number.parseInt(part, 10)),
prerelease: match[2]
? match[2].split(".").map((part) =>
/^\d+$/.test(part) ? Number.parseInt(part, 10) : part,
)
: null,
};
};
const comparePluginVersions = (left, right) => {
const leftVersion = parsePluginVersion(left);
const rightVersion = parsePluginVersion(right);
// Decide a consistent policy for invalid versions:
// e.g. treat invalid as "equal" or always "behind"
if (!leftVersion || !rightVersion) {
return 0; // or -1, depending on desired behavior
}
// ... keep existing comparison logic unchanged ...
};
```
Then the hook can be simplified to intention‑revealing checks without `typeof` noise:
```js
const onlineVersion = String(matchedPlugin.version || "").trim();
const versionComparison = comparePluginVersions(extension.version, onlineVersion);
extension.version_source_ahead = versionComparison > 0;
extension.has_update = versionComparison < 0;
```
### 2. Wrap comparison in higher‑level helpers for the hook
To avoid low‑level semver logic living in the hook, add small helpers near the utilities (same file or a separate module) and use them in the effect:
```js
const isVersionAhead = (local, remote) =>
comparePluginVersions(local, remote) > 0;
const isVersionBehind = (local, remote) =>
comparePluginVersions(local, remote) < 0;
```
Usage in the hook:
```js
if (matchedPlugin) {
extension.online_version = matchedPlugin.version;
const onlineVersion = String(matchedPlugin.version || "").trim();
extension.version_source_ahead = isVersionAhead(extension.version, onlineVersion);
extension.has_update = isVersionBehind(extension.version, onlineVersion);
} else {
extension.online_version = "";
extension.has_update = false;
extension.version_source_ahead = false;
}
```
This keeps all existing behavior but makes the hook read as “ahead/behind” logic instead of embedded semver implementation details.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
Code Review
This pull request adds support for detecting and displaying when an installed extension's version is ahead of the online source version. It introduces SemVer-compliant version parsing and comparison logic, alongside UI updates and localizations in English, Russian, and Chinese. Feedback was provided to improve the robustness of the version comparison function: if the local version is unparseable but the online version is valid, the code should treat the online version as newer to allow updates, rather than returning null.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
优化了一下当前插件市场的版本更新的显示,当当前安装的插件版本高于插件源的版本时,不再显示更新图标,具体修改请看下面的PR内容:
当已安装插件版本高于插件市场或自定义插件源中的版本时,当前面板会把“版本不一致”误判为“有新版本可更新”。例如本地插件版本为
0.1.5,插件源版本为0.1.4时,页面会误提示更新到更旧的0.1.4。此 PR 修复插件更新状态判断:只有插件源版本高于本地版本时才显示更新提示;当本地插件版本高于当前插件源版本时,插件卡片会显示中性提示,不再展示误导性的更新入口。
Modifications / 改动点
调整已安装插件的更新判断逻辑,不再将任意版本字符串不一致都视为可更新。
新增插件版本比较逻辑,支持预发布版本比较,并忽略构建元数据。
当本地插件版本高于插件市场或当前插件源版本时,新增本地版本领先状态。
在已安装插件卡片上显示“当前插件版本比当前插件源更新”的中性提示。
补充
zh-CN、en-US、ru-RU三种语言下的本地版本领先提示文案。This is NOT a breaking change. / 这不是一个破坏性变更。
Screenshots or Test Results / 运行截图或测试结果
本地已执行以下检查:
手动代码链路验证:
0.1.5,插件源版本0.1.4:不再显示更新提示,显示本地版本领先提示。0.1.4,插件源版本0.1.5:仍正常显示更新提示,并保留“更新到 0.1.5”的行为。has_update判断,本地版本领先的插件不会进入批量更新目标。Checklist / 检查清单
😊 If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc.
/ 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。
👀 My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
/ 我的更改经过了良好的测试,并已在上方提供了“验证步骤”和“运行截图”。
🤓 I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in
requirements.txtandpyproject.toml./ 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到
requirements.txt和pyproject.toml文件相应位置。😮 My changes do not introduce malicious code.
/ 我的更改没有引入恶意代码。
Summary by Sourcery
Refine plugin marketplace update status so that update prompts only appear when the marketplace version is newer than the installed version, and show a neutral ahead-of-source state when the local version is more recent.
New Features:
Enhancements: