diff --git a/src/plugins/loader.test.ts b/src/plugins/loader.test.ts index a4aea837757..ed053ac395e 100644 --- a/src/plugins/loader.test.ts +++ b/src/plugins/loader.test.ts @@ -1,11 +1,13 @@ import fs from "node:fs"; import os from "node:os"; import path from "node:path"; -import { afterAll, afterEach, describe, expect, it } from "vitest"; +import { afterAll, afterEach, describe, expect, it, vi } from "vitest"; import { withEnv } from "../test-utils/env.js"; import { getGlobalHookRunner, resetGlobalHookRunner } from "./hook-runner-global.js"; import { createHookRunner } from "./hooks.js"; -import { __testing, loadOpenClawPlugins } from "./loader.js"; + +vi.unmock("jiti"); +const { __testing, loadOpenClawPlugins } = await import("./loader.js"); type TempPlugin = { dir: string; file: string; id: string }; @@ -1335,7 +1337,7 @@ describe("loadOpenClawPlugins", () => { }); const record = registry.plugins.find((entry) => entry.id === "legacy-root-import"); - expect(record?.status).toBe("loaded"); + expect({ status: record?.status, error: record?.error }).toMatchObject({ status: "loaded" }); }); it("prefers dist plugin-sdk alias when loader runs from dist", () => { @@ -1362,6 +1364,20 @@ describe("loadOpenClawPlugins", () => { expect(resolved).toBe(srcFile); }); + it("falls back to src plugin-sdk alias when dist is missing in production", () => { + const { root, srcFile, distFile } = createPluginSdkAliasFixture(); + fs.rmSync(distFile); + + const resolved = withEnv({ NODE_ENV: "production", VITEST: undefined }, () => + __testing.resolvePluginSdkAliasFile({ + srcFile: "index.ts", + distFile: "index.js", + modulePath: path.join(root, "src", "plugins", "loader.ts"), + }), + ); + expect(resolved).toBe(srcFile); + }); + it("prefers dist root-alias shim when loader runs from dist", () => { const { root, distFile } = createPluginSdkAliasFixture({ srcFile: "root-alias.cjs", diff --git a/src/plugins/loader.ts b/src/plugins/loader.ts index 15051b25e81..f112fcb815c 100644 --- a/src/plugins/loader.ts +++ b/src/plugins/loader.ts @@ -55,19 +55,15 @@ const resolvePluginSdkAliasFile = (params: { try { const modulePath = params.modulePath ?? fileURLToPath(import.meta.url); const isProduction = process.env.NODE_ENV === "production"; - const isTest = process.env.VITEST || process.env.NODE_ENV === "test"; const normalizedModulePath = modulePath.replace(/\\/g, "/"); const isDistRuntime = normalizedModulePath.includes("/dist/"); let cursor = path.dirname(modulePath); for (let i = 0; i < 6; i += 1) { const srcCandidate = path.join(cursor, "src", "plugin-sdk", params.srcFile); const distCandidate = path.join(cursor, "dist", "plugin-sdk", params.distFile); - const orderedCandidates = isDistRuntime - ? [distCandidate, srcCandidate] - : isProduction - ? isTest - ? [distCandidate, srcCandidate] - : [distCandidate] + const orderedCandidates = + isDistRuntime || isProduction + ? [distCandidate, srcCandidate] : [srcCandidate, distCandidate]; for (const candidate of orderedCandidates) { if (fs.existsSync(candidate)) {