From 9402ac92debc137029f0bd47306c1a74c7fc69c0 Mon Sep 17 00:00:00 2001 From: "opencode-agent[bot]" Date: Tue, 1 Sep 2026 13:14:12 +0000 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=20ClassIsland=202.0.0.0=20?= =?UTF-8?q?=E5=8F=8A=E4=BB=A5=E4=B8=8A=E5=AE=BF=E4=B8=BB=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=AE=89=E8=A3=85=E8=81=94=E5=8A=A8=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 将 MIN_CLASSISLAND_VERSION 从 2.1.1.0 下调到 2.0.0.0。依据 ClassIsland (HelloWRC/ClassIsland) 源码验证: - 插件 manifest.yml 声明 apiVersion: 2.0.0.0,正好满足 ClassIsland 2.0.0.0 起在 PluginService.InitializePlugins 中强制要求的 apiVersion >= 2.0.0.0,也满足 PluginMarketService 的市场显示过滤; - 插件用到的宿主 API(AppBase、IAppHost、IProfileService、 IComponentsService、IExactTimeService、ComponentSettings、 CommonDirectories、AddSettingsPage 等)在 2.0.0.0 标签均存在且未变化。 同步更新 OobeWizard 错误提示与 classisland 测试。 --- src/classisland.test.ts | 22 ++++++++++++---------- src/classisland.ts | 7 ++++++- src/renderer/src/components/OobeWizard.tsx | 2 +- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/classisland.test.ts b/src/classisland.test.ts index 0706885..c4bad0a 100644 --- a/src/classisland.test.ts +++ b/src/classisland.test.ts @@ -38,12 +38,12 @@ function classIslandHealthResponse(input: string | URL): Response | undefined { : undefined; } -test("ClassIsland versions enforce the 2.1.1.0 minimum", () => { - assert.equal(compareClassIslandVersions("2.1.1.0", "2.1.1.0"), 0); - assert.equal(compareClassIslandVersions("2.1.1.1", "2.1.1.0") > 0, true); - assert.equal(compareClassIslandVersions("2.1.0.9", "2.1.1.0") < 0, true); - assert.equal(isCompatibleClassIslandVersion("2.1.1.0"), true); - assert.equal(isCompatibleClassIslandVersion("2.1.0.9"), false); +test("ClassIsland versions enforce the 2.0.0.0 minimum", () => { + assert.equal(compareClassIslandVersions("2.0.0.0", "2.0.0.0"), 0); + assert.equal(compareClassIslandVersions("2.0.0.1", "2.0.0.0") > 0, true); + assert.equal(compareClassIslandVersions("1.9.0.9", "2.0.0.0") < 0, true); + assert.equal(isCompatibleClassIslandVersion("2.0.0.0"), true); + assert.equal(isCompatibleClassIslandVersion("1.9.0.9"), false); assert.equal(isCompatibleClassIslandVersion(undefined), false); }); @@ -74,8 +74,8 @@ test("discovers multiple ClassIsland versions and marks old versions incompatibl const paths = ["C:\\Portable\\ClassIsland.exe", "D:\\Old\\ClassIsland.exe", "C:\\Program Files\\ClassIsland\\ClassIsland.exe"]; const versions: Record = { [paths[0]]: "2.1.1.0", - [paths[1]]: "2.0.4.0", - [paths[2]]: "2.1.1.0" + [paths[1]]: "1.9.0.0", + [paths[2]]: "2.0.4.0" }; const found = await discoverClassIslandInstallations({ platform: "win32", @@ -91,7 +91,9 @@ test("discovers multiple ClassIsland versions and marks old versions incompatibl assert.equal(found.find((item) => item.executablePath === paths[0])?.isRunning, true); assert.deepEqual(found.find((item) => item.executablePath === paths[0])?.launchArgs, ["--quiet"]); assert.equal(found.find((item) => item.executablePath === paths[1])?.compatible, false); - assert.match(found.find((item) => item.executablePath === paths[1])?.reason || "", /2\.1\.1\.0/); + assert.match(found.find((item) => item.executablePath === paths[1])?.reason || "", /2\.0\.0\.0/); + // 2.0.x releases (e.g. the 2.0.4.0 the issue reporter runs) are now supported. + assert.equal(found.find((item) => item.executablePath === paths[2])?.compatible, true); }); test("maps the running ClassIsland.Desktop process back to its launcher and closes the real instance", async () => { @@ -289,7 +291,7 @@ test("does not write a package when ClassIsland is too old or the digest is inva try { const exe = path.win32.join(root, "ClassIsland.exe"); fs.writeFileSync(exe, "test executable"); - const oldInstaller = new ClassIslandInstaller({ platform: "win32", executablePaths: [exe], runningProcesses: [], versionOf: () => "2.1.0.9", exists: (candidate) => fs.existsSync(candidate) }); + const oldInstaller = new ClassIslandInstaller({ platform: "win32", executablePaths: [exe], runningProcesses: [], versionOf: () => "1.9.0.0", exists: (candidate) => fs.existsSync(candidate) }); const [oldTarget] = await oldInstaller.detect(); const [oldResult] = await oldInstaller.install([oldTarget.id]); assert.equal(oldResult.action, "skipped"); diff --git a/src/classisland.ts b/src/classisland.ts index 15d4875..0ad6660 100644 --- a/src/classisland.ts +++ b/src/classisland.ts @@ -10,7 +10,12 @@ import { DEFAULT_MARKETPLACE_PROXY_URL, describeDownloadAttempt, marketplaceRequ export const CLASSISLAND_PLUGIN_REPOSITORY = "SECTL/ClassIsland-SecAgent-Plugin"; export const CLASSISLAND_PLUGIN_ID = "classisland.secagent"; export const CLASSISLAND_PLUGIN_ASSET_NAME = "ClassIsland.SecAgent.Plugin.cipx"; -export const MIN_CLASSISLAND_VERSION = "2.1.1.0"; +// The ClassIsland-side plugin (manifest.yml) declares apiVersion: 2.0.0.0, and +// ClassIsland 2.0.0.0 already enforces that plugins target API version +// >= 2.0.0.0 (PluginService.InitializePlugins) and lists only those in the +// marketplace (PluginMarketService). Every host API the plugin uses exists +// unchanged in 2.0.0.0, so 2.0.0.0 is the real lower bound. +export const MIN_CLASSISLAND_VERSION = "2.0.0.0"; export const CLASSISLAND_RELEASE_API_URL = `https://api.github.com/repos/${CLASSISLAND_PLUGIN_REPOSITORY}/releases/latest`; const CLASSISLAND_RELEASE_PAGE_URL = `https://github.com/${CLASSISLAND_PLUGIN_REPOSITORY}/releases/latest`; diff --git a/src/renderer/src/components/OobeWizard.tsx b/src/renderer/src/components/OobeWizard.tsx index fbdeb4b..144daf4 100644 --- a/src/renderer/src/components/OobeWizard.tsx +++ b/src/renderer/src/components/OobeWizard.tsx @@ -555,7 +555,7 @@ export function OobeWizard() { return false; } if (selectedTargets.some((target) => !target.compatible)) { - setError("所选 ClassIsland 版本低于 2.1.1.0,无法安装联动插件"); + setError("所选 ClassIsland 版本低于 2.0.0.0,无法安装联动插件"); return false; } // Holds land on the 50-100 half of the card when the SecAgent connector