




















@@ -1,4 +1,5 @@
1-import { fileURLToPath } from "node:url";
1+import path from "node:path";
2+import { fileURLToPath, pathToFileURL } from "node:url";
23import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../../agents/agent-scope.js";
34import type { OpenClawConfig } from "../../config/types.openclaw.js";
45import { isBlockedObjectKey } from "../../infra/prototype-keys.js";
@@ -25,9 +26,13 @@ import {
2526import { listChannelPlugins } from "./registry.js";
2627import type { ChannelPlugin } from "./types.plugin.js";
272828-const LOADER_MODULE_CANDIDATES = [
29-new URL("../../plugins/loader.js", import.meta.url),
30-new URL("../../plugins/loader.ts", import.meta.url),
29+const SOURCE_PLUGIN_LOADER_MODULE_CANDIDATES = [
30+"../../plugins/loader.js",
31+"../../plugins/loader.ts",
32+] as const;
33+const BUILT_PLUGIN_LOADER_MODULE_CANDIDATES = [
34+"plugins/loader.js",
35+"plugins/build-smoke-entry.js",
3136] as const;
3237const jitiLoaders: PluginJitiLoaderCache = new Map();
3338@@ -53,11 +58,39 @@ type PluginLoaderModule = {
53585459let pluginLoaderModule: PluginLoaderModule | undefined;
556061+function listBuiltPluginLoaderModuleCandidateUrls(importerUrl: string): URL[] {
62+let importerPath: string;
63+try {
64+importerPath = fileURLToPath(importerUrl);
65+} catch {
66+return [];
67+}
68+const distMarker = `${path.sep}dist${path.sep}`;
69+const distMarkerIndex = importerPath.lastIndexOf(distMarker);
70+if (distMarkerIndex < 0) {
71+return [];
72+}
73+// Bundled read-only chunks live under dist/ with hashed names. Source-relative
74+// ../../plugins candidates would escape the installed openclaw package there.
75+const distRoot = importerPath.slice(0, distMarkerIndex + distMarker.length - 1);
76+return BUILT_PLUGIN_LOADER_MODULE_CANDIDATES.map((candidate) =>
77+pathToFileURL(path.join(distRoot, candidate)),
78+);
79+}
80+81+export function listPluginLoaderModuleCandidateUrls(importerUrl = import.meta.url): URL[] {
82+const builtCandidates = listBuiltPluginLoaderModuleCandidateUrls(importerUrl);
83+if (builtCandidates.length > 0) {
84+return builtCandidates;
85+}
86+return SOURCE_PLUGIN_LOADER_MODULE_CANDIDATES.map((candidate) => new URL(candidate, importerUrl));
87+}
88+5689function loadPluginLoaderModule(): PluginLoaderModule {
5790if (pluginLoaderModule) {
5891return pluginLoaderModule;
5992}
60-for (const candidate of LOADER_MODULE_CANDIDATES) {
93+for (const candidate of listPluginLoaderModuleCandidateUrls()) {
6194const modulePath = fileURLToPath(candidate);
6295try {
6396const jiti = getCachedPluginJitiLoader({
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。