fix(update): prefer npm during post-core repair

(cherry picked from commit eab57ad8ad)
This commit is contained in:
Peter Steinberger
2026-05-20 14:00:35 +01:00
parent f4dc9b1232
commit 2e389b6a46
2 changed files with 62 additions and 1 deletions
@@ -1209,6 +1209,67 @@ describe("repairMissingConfiguredPluginInstalls", () => {
});
});
it("prefers npm over ClawHub during post-core repair", async () => {
const npmRoot = makeTempDir();
const packageDir = path.join(npmRoot, "node_modules", "@openclaw", "whatsapp");
mocks.resolveDefaultPluginNpmDir.mockReturnValue(npmRoot);
mocks.listChannelPluginCatalogEntries.mockReturnValue([
{
id: "whatsapp",
pluginId: "whatsapp",
meta: { label: "WhatsApp" },
install: {
clawhubSpec: "clawhub:@openclaw/whatsapp",
npmSpec: "@openclaw/whatsapp",
},
},
]);
mocks.installPluginFromClawHub.mockResolvedValue({
ok: false,
error: 'Plugin "@openclaw/whatsapp" requires plugin API >=2026.5.18.',
});
mocks.installPluginFromNpmSpec.mockResolvedValue({
ok: true,
pluginId: "whatsapp",
targetDir: packageDir,
version: "1.2.3",
npmResolution: {
name: "@openclaw/whatsapp",
version: "1.2.3",
resolvedSpec: "@openclaw/whatsapp@1.2.3",
integrity: "sha512-whatsapp",
resolvedAt: "2026-05-01T00:00:00.000Z",
},
});
const { repairMissingConfiguredPluginInstalls } =
await import("./missing-configured-plugin-install.js");
const result = await repairMissingConfiguredPluginInstalls({
cfg: {
plugins: {
entries: {
whatsapp: { enabled: true },
},
},
channels: {
whatsapp: { enabled: true },
},
},
env: {
OPENCLAW_UPDATE_POST_CORE_CONVERGENCE: "1",
},
});
expect(mocks.installPluginFromClawHub).not.toHaveBeenCalled();
expectRecordFields(mockCallArg(mocks.installPluginFromNpmSpec), {
spec: expectedNpmInstallSpec("@openclaw/whatsapp"),
npmDir: npmRoot,
mode: "install",
});
expect(result.warnings).toEqual([]);
expect(result.records.whatsapp?.installPath).toBe(packageDir);
});
it("repairs missing external payload during post-core convergence even with OPENCLAW_UPDATE_IN_PROGRESS=1", async () => {
const records = {
discord: {
@@ -1135,7 +1135,7 @@ async function repairMissingPluginInstalls(params: {
configChannel: normalizeUpdateChannel(params.cfg.update?.channel),
currentVersion: VERSION,
});
const preferNpmInstalls = isLegacyPackageUpdateDoctorPass(env);
const preferNpmInstalls = isLegacyPackageUpdateDoctorPass(env) || isPostCoreConvergencePass(env);
let nextRecords = records;
for (const [pluginId, record] of Object.entries(records)) {