mirror of
https://github.com/moltbot/moltbot.git
synced 2026-05-06 23:55:12 +00:00
fix: align official plugin repair versions
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { VERSION } from "../../../version.js";
|
||||
|
||||
const openClawReleaseSpec = (packageName: string) => `${packageName}@${VERSION}`;
|
||||
|
||||
const mocks = vi.hoisted(() => ({
|
||||
installPluginFromClawHub: vi.fn(),
|
||||
@@ -343,13 +346,13 @@ describe("repairMissingConfiguredPluginInstalls", () => {
|
||||
expect(mocks.installPluginFromClawHub).not.toHaveBeenCalled();
|
||||
expect(mocks.installPluginFromNpmSpec).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
spec: "@openclaw/twitch",
|
||||
spec: openClawReleaseSpec("@openclaw/twitch"),
|
||||
expectedPluginId: "twitch",
|
||||
trustedSourceLinkedOfficialInstall: true,
|
||||
}),
|
||||
);
|
||||
expect(result.changes).toEqual([
|
||||
'Installed missing configured plugin "twitch" from @openclaw/twitch.',
|
||||
`Installed missing configured plugin "twitch" from ${openClawReleaseSpec("@openclaw/twitch")}.`,
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -395,12 +398,12 @@ describe("repairMissingConfiguredPluginInstalls", () => {
|
||||
expect(mocks.installPluginFromClawHub).not.toHaveBeenCalled();
|
||||
expect(mocks.installPluginFromNpmSpec).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
spec: "@openclaw/diagnostics-otel",
|
||||
spec: openClawReleaseSpec("@openclaw/diagnostics-otel"),
|
||||
expectedPluginId: "diagnostics-otel",
|
||||
}),
|
||||
);
|
||||
expect(result.changes).toEqual([
|
||||
'Installed missing configured plugin "diagnostics-otel" from @openclaw/diagnostics-otel.',
|
||||
`Installed missing configured plugin "diagnostics-otel" from ${openClawReleaseSpec("@openclaw/diagnostics-otel")}.`,
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -442,13 +445,13 @@ describe("repairMissingConfiguredPluginInstalls", () => {
|
||||
|
||||
expect(mocks.installPluginFromNpmSpec).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
spec: "@openclaw/acpx",
|
||||
spec: openClawReleaseSpec("@openclaw/acpx"),
|
||||
expectedPluginId: "acpx",
|
||||
trustedSourceLinkedOfficialInstall: true,
|
||||
}),
|
||||
);
|
||||
expect(result.changes).toEqual([
|
||||
'Installed missing configured plugin "acpx" from @openclaw/acpx.',
|
||||
`Installed missing configured plugin "acpx" from ${openClawReleaseSpec("@openclaw/acpx")}.`,
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -999,7 +1002,7 @@ describe("repairMissingConfiguredPluginInstalls", () => {
|
||||
expect(mocks.resolveProviderInstallCatalogEntries).toHaveBeenCalled();
|
||||
expect(mocks.installPluginFromNpmSpec).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
spec: "@openclaw/codex",
|
||||
spec: openClawReleaseSpec("@openclaw/codex"),
|
||||
expectedPluginId: "codex",
|
||||
trustedSourceLinkedOfficialInstall: true,
|
||||
}),
|
||||
@@ -1008,7 +1011,7 @@ describe("repairMissingConfiguredPluginInstalls", () => {
|
||||
expect.objectContaining({
|
||||
codex: expect.objectContaining({
|
||||
source: "npm",
|
||||
spec: "@openclaw/codex",
|
||||
spec: openClawReleaseSpec("@openclaw/codex"),
|
||||
installPath: "/tmp/openclaw-plugins/codex",
|
||||
version: "2026.5.2",
|
||||
}),
|
||||
@@ -1016,7 +1019,7 @@ describe("repairMissingConfiguredPluginInstalls", () => {
|
||||
{ env: {} },
|
||||
);
|
||||
expect(result.changes).toEqual([
|
||||
'Installed missing configured plugin "codex" from @openclaw/codex.',
|
||||
`Installed missing configured plugin "codex" from ${openClawReleaseSpec("@openclaw/codex")}.`,
|
||||
]);
|
||||
expect(result.warnings).toEqual([]);
|
||||
});
|
||||
@@ -1077,7 +1080,7 @@ describe("repairMissingConfiguredPluginInstalls", () => {
|
||||
|
||||
expect(mocks.installPluginFromNpmSpec).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
spec: "@openclaw/codex",
|
||||
spec: openClawReleaseSpec("@openclaw/codex"),
|
||||
expectedPluginId: "codex",
|
||||
trustedSourceLinkedOfficialInstall: true,
|
||||
}),
|
||||
@@ -1086,7 +1089,7 @@ describe("repairMissingConfiguredPluginInstalls", () => {
|
||||
expect.objectContaining({
|
||||
codex: expect.objectContaining({
|
||||
source: "npm",
|
||||
spec: "@openclaw/codex",
|
||||
spec: openClawReleaseSpec("@openclaw/codex"),
|
||||
installPath: "/tmp/openclaw-plugins/codex",
|
||||
version: "2026.5.2",
|
||||
}),
|
||||
@@ -1094,7 +1097,9 @@ describe("repairMissingConfiguredPluginInstalls", () => {
|
||||
{ env },
|
||||
);
|
||||
expect(result).toEqual({
|
||||
changes: ['Installed missing configured plugin "codex" from @openclaw/codex.'],
|
||||
changes: [
|
||||
`Installed missing configured plugin "codex" from ${openClawReleaseSpec("@openclaw/codex")}.`,
|
||||
],
|
||||
warnings: [],
|
||||
});
|
||||
});
|
||||
@@ -1271,7 +1276,7 @@ describe("repairMissingConfiguredPluginInstalls", () => {
|
||||
);
|
||||
expect(mocks.installPluginFromNpmSpec).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
spec: "@openclaw/discord",
|
||||
spec: openClawReleaseSpec("@openclaw/discord"),
|
||||
expectedPluginId: "discord",
|
||||
trustedSourceLinkedOfficialInstall: true,
|
||||
}),
|
||||
@@ -1283,7 +1288,7 @@ describe("repairMissingConfiguredPluginInstalls", () => {
|
||||
{ env: {} },
|
||||
);
|
||||
expect(result.changes).toEqual([
|
||||
'Installed missing configured plugin "discord" from @openclaw/discord.',
|
||||
`Installed missing configured plugin "discord" from ${openClawReleaseSpec("@openclaw/discord")}.`,
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -1616,13 +1621,13 @@ describe("repairMissingConfiguredPluginInstalls", () => {
|
||||
|
||||
expect(mocks.installPluginFromNpmSpec).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
spec: "@openclaw/brave-plugin",
|
||||
spec: openClawReleaseSpec("@openclaw/brave-plugin"),
|
||||
expectedPluginId: "brave",
|
||||
trustedSourceLinkedOfficialInstall: true,
|
||||
}),
|
||||
);
|
||||
expect(result.changes).toEqual([
|
||||
'Installed missing configured plugin "brave" from @openclaw/brave-plugin.',
|
||||
`Installed missing configured plugin "brave" from ${openClawReleaseSpec("@openclaw/brave-plugin")}.`,
|
||||
]);
|
||||
});
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import { listChannelPluginCatalogEntries } from "../../../channels/plugins/catal
|
||||
import type { OpenClawConfig } from "../../../config/types.openclaw.js";
|
||||
import type { PluginInstallRecord } from "../../../config/types.plugins.js";
|
||||
import { parseClawHubPluginSpec } from "../../../infra/clawhub-spec.js";
|
||||
import { parseRegistryNpmSpec } from "../../../infra/npm-registry-spec.js";
|
||||
import { isExactSemverVersion, parseRegistryNpmSpec } from "../../../infra/npm-registry-spec.js";
|
||||
import { buildClawHubPluginInstallRecordFields } from "../../../plugins/clawhub-install-records.js";
|
||||
import { CLAWHUB_INSTALL_ERROR_CODE, installPluginFromClawHub } from "../../../plugins/clawhub.js";
|
||||
import { resolveDefaultPluginExtensionsDir } from "../../../plugins/install-paths.js";
|
||||
@@ -30,6 +30,7 @@ import { resolveProviderInstallCatalogEntries } from "../../../plugins/provider-
|
||||
import { updateNpmInstalledPlugins } from "../../../plugins/update.js";
|
||||
import { resolveWebSearchInstallCatalogEntry } from "../../../plugins/web-search-install-catalog.js";
|
||||
import { resolveUserPath } from "../../../utils.js";
|
||||
import { VERSION } from "../../../version.js";
|
||||
import { asObjectRecord } from "./object.js";
|
||||
|
||||
type DownloadableInstallCandidate = {
|
||||
@@ -381,6 +382,27 @@ function recordClawHubPackageName(value: string | undefined): string | undefined
|
||||
return parseClawHubPluginSpec(trimmed)?.name ?? trimmed;
|
||||
}
|
||||
|
||||
function resolveVersionAlignedOfficialNpmSpec(
|
||||
candidate: DownloadableInstallCandidate,
|
||||
): string | undefined {
|
||||
const npmSpec = candidate.npmSpec?.trim();
|
||||
if (!npmSpec || !candidate.trustedSourceLinkedOfficialInstall) {
|
||||
return npmSpec;
|
||||
}
|
||||
const parsed = parseRegistryNpmSpec(npmSpec);
|
||||
if (!parsed || !parsed.name.startsWith("@openclaw/")) {
|
||||
return npmSpec;
|
||||
}
|
||||
if (parsed.selectorKind === "exact-version") {
|
||||
return npmSpec;
|
||||
}
|
||||
const hostVersion = VERSION.trim();
|
||||
if (!isExactSemverVersion(hostVersion)) {
|
||||
return npmSpec;
|
||||
}
|
||||
return `${parsed.name}@${hostVersion}`;
|
||||
}
|
||||
|
||||
async function installCandidate(params: {
|
||||
candidate: DownloadableInstallCandidate;
|
||||
records: Record<string, PluginInstallRecord>;
|
||||
@@ -430,7 +452,8 @@ async function installCandidate(params: {
|
||||
`ClawHub ${candidate.clawhubSpec} unavailable for "${candidate.pluginId}"; falling back to npm ${candidate.npmSpec}.`,
|
||||
);
|
||||
}
|
||||
if (!candidate.npmSpec) {
|
||||
const npmSpec = resolveVersionAlignedOfficialNpmSpec(candidate);
|
||||
if (!npmSpec) {
|
||||
return {
|
||||
records: params.records,
|
||||
changes: [],
|
||||
@@ -440,7 +463,7 @@ async function installCandidate(params: {
|
||||
};
|
||||
}
|
||||
const result = await installPluginFromNpmSpec({
|
||||
spec: candidate.npmSpec,
|
||||
spec: npmSpec,
|
||||
extensionsDir,
|
||||
expectedPluginId: candidate.pluginId,
|
||||
expectedIntegrity: candidate.expectedIntegrity,
|
||||
@@ -464,17 +487,14 @@ async function installCandidate(params: {
|
||||
...params.records,
|
||||
[pluginId]: {
|
||||
source: "npm",
|
||||
spec: candidate.npmSpec,
|
||||
spec: npmSpec,
|
||||
installPath: result.targetDir,
|
||||
version: result.version,
|
||||
installedAt: new Date().toISOString(),
|
||||
...buildNpmResolutionInstallFields(result.npmResolution),
|
||||
},
|
||||
},
|
||||
changes: [
|
||||
...changes,
|
||||
`Installed missing configured plugin "${pluginId}" from ${candidate.npmSpec}.`,
|
||||
],
|
||||
changes: [...changes, `Installed missing configured plugin "${pluginId}" from ${npmSpec}.`],
|
||||
warnings: [],
|
||||
};
|
||||
}
|
||||
@@ -672,4 +692,5 @@ export const __testing = {
|
||||
collectConfiguredChannelIds,
|
||||
collectConfiguredPluginIds,
|
||||
collectDownloadableInstallCandidates,
|
||||
resolveVersionAlignedOfficialNpmSpec,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user