























@@ -507,6 +507,59 @@ describe("updateNpmInstalledPlugins", () => {
507507);
508508});
509509510+it("does not skip trusted official default updates when latest resolves to the installed prerelease", async () => {
511+const installPath = createInstalledPackageDir({
512+name: "@openclaw/acpx",
513+version: "2026.5.2-beta.2",
514+});
515+mockNpmViewMetadata({
516+name: "@openclaw/acpx",
517+version: "2026.5.2-beta.2",
518+integrity: "sha512-beta",
519+shasum: "beta",
520+});
521+installPluginFromNpmSpecMock.mockResolvedValue(
522+createSuccessfulNpmUpdateResult({
523+pluginId: "acpx",
524+targetDir: installPath,
525+version: "2026.5.2",
526+npmResolution: {
527+name: "@openclaw/acpx",
528+version: "2026.5.2",
529+resolvedSpec: "@openclaw/acpx@2026.5.2",
530+},
531+}),
532+);
533+534+const result = await updateNpmInstalledPlugins({
535+config: createNpmInstallConfig({
536+pluginId: "acpx",
537+spec: "@openclaw/acpx",
538+ installPath,
539+integrity: "sha512-beta",
540+shasum: "beta",
541+resolvedName: "@openclaw/acpx",
542+resolvedSpec: "@openclaw/acpx@2026.5.2-beta.2",
543+resolvedVersion: "2026.5.2-beta.2",
544+}),
545+pluginIds: ["acpx"],
546+});
547+548+expect(installPluginFromNpmSpecMock).toHaveBeenCalledWith(
549+expect.objectContaining({
550+spec: "@openclaw/acpx",
551+expectedPluginId: "acpx",
552+trustedSourceLinkedOfficialInstall: true,
553+}),
554+);
555+expect(result.outcomes[0]).toMatchObject({
556+pluginId: "acpx",
557+status: "updated",
558+currentVersion: "2026.5.2-beta.2",
559+nextVersion: "2026.5.2",
560+});
561+});
562+510563it("does not trust official npm updates when the install record package mismatches", async () => {
511564const installPath = createInstalledPackageDir({
512565name: "@vendor/acpx-fork",
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。