























@@ -112,6 +112,7 @@ import {
112112getCachedPluginSourceModuleLoader,
113113type PluginModuleLoaderCache,
114114} from "./plugin-module-loader-cache.js";
115+import type { PluginOrigin } from "./plugin-origin.types.js";
115116import {
116117createPluginIdScopeSet,
117118hasExplicitPluginIdScope,
@@ -180,6 +181,11 @@ export type PluginLoadOptions = {
180181 * via package metadata because their setup entry covers the pre-listen startup surface.
181182 */
182183preferSetupRuntimeForChannelPlugins?: boolean;
184+/**
185+ * For hot startup paths, prefer bundled plugin JS artifacts over source TS
186+ * entrypoints when both are present in a source checkout.
187+ */
188+preferBuiltPluginArtifacts?: boolean;
183189toolDiscovery?: boolean;
184190activate?: boolean;
185191loadModules?: boolean;
@@ -275,6 +281,7 @@ function createPluginCandidatesFromManifestRegistry(
275281idHint: record.id,
276282rootDir: record.rootDir,
277283source: record.source,
284+ ...(record.setupSource !== undefined ? { setupSource: record.setupSource } : {}),
278285origin: record.origin,
279286 ...(record.workspaceDir !== undefined ? { workspaceDir: record.workspaceDir } : {}),
280287 ...(record.format !== undefined ? { format: record.format } : {}),
@@ -517,6 +524,52 @@ function resolveCanonicalDistRuntimeSource(source: string): string {
517524return fs.existsSync(candidate) ? candidate : source;
518525}
519526527+function rewriteBundledRuntimeArtifactRelativePath(relativePath: string): string {
528+return relativePath.replace(/\.[^.]+$/u, ".js");
529+}
530+531+function resolvePreferredBuiltBundledRuntimeArtifact(params: {
532+source: string;
533+rootDir: string;
534+origin: PluginOrigin;
535+preferBuiltPluginArtifacts: boolean;
536+}): { source: string; rootDir: string } {
537+const rootDir = safeRealpathOrResolve(params.rootDir);
538+const source = safeRealpathOrResolve(params.source);
539+if (!params.preferBuiltPluginArtifacts || params.origin !== "bundled") {
540+return { source, rootDir };
541+}
542+const extensionsDir = path.dirname(rootDir);
543+if (path.basename(extensionsDir) !== "extensions") {
544+return { source, rootDir };
545+}
546+const packageRoot = path.dirname(extensionsDir);
547+if (path.basename(packageRoot) === "dist" || path.basename(packageRoot) === "dist-runtime") {
548+return { source, rootDir };
549+}
550+const relativeSource = path.relative(rootDir, source);
551+if (relativeSource === "" || relativeSource.startsWith("..") || path.isAbsolute(relativeSource)) {
552+return { source, rootDir };
553+}
554+const artifactRelativePath = rewriteBundledRuntimeArtifactRelativePath(relativeSource);
555+for (const artifactRootName of ["dist-runtime", "dist"] as const) {
556+const artifactRoot = path.join(
557+packageRoot,
558+artifactRootName,
559+"extensions",
560+path.basename(rootDir),
561+);
562+const artifactSource = path.join(artifactRoot, artifactRelativePath);
563+if (fs.existsSync(artifactSource)) {
564+return {
565+source: safeRealpathOrResolve(artifactSource),
566+rootDir: safeRealpathOrResolve(artifactRoot),
567+};
568+}
569+}
570+return { source, rootDir };
571+}
572+520573export const __testing = {
521574 buildPluginLoaderJitiOptions,
522575 buildPluginLoaderAliasMap,
@@ -682,6 +735,7 @@ function buildCacheKey(params: {
682735forceSetupOnlyChannelPlugins?: boolean;
683736requireSetupEntryForSetupOnlyChannelPlugins?: boolean;
684737preferSetupRuntimeForChannelPlugins?: boolean;
738+preferBuiltPluginArtifacts?: boolean;
685739toolDiscovery?: boolean;
686740loadModules?: boolean;
687741runtimeSubagentMode?: "default" | "explicit" | "gateway-bindable";
@@ -722,6 +776,8 @@ function buildCacheKey(params: {
722776 : "allow-full-fallback";
723777const startupChannelMode =
724778params.preferSetupRuntimeForChannelPlugins === true ? "prefer-setup" : "full";
779+const bundledArtifactMode =
780+params.preferBuiltPluginArtifacts === true ? "prefer-built-artifacts" : "source-default";
725781const moduleLoadMode = params.loadModules === false ? "manifest-only" : "load-modules";
726782const discoveryMode = params.toolDiscovery === true ? "tool-discovery" : "default-discovery";
727783const runtimeSubagentMode = params.runtimeSubagentMode ?? "default";
@@ -734,7 +790,7 @@ function buildCacheKey(params: {
734790 installs,
735791 loadPaths,
736792 activationMetadataKey: params.activationMetadataKey ?? "",
737- })}::${scopeKey}::${setupOnlyKey}::${setupOnlyModeKey}::${setupOnlyRequirementKey}::${startupChannelMode}::${moduleLoadMode}::${discoveryMode}::${runtimeSubagentMode}::${params.pluginSdkResolution ?? "auto"}::${gatewayMethodsKey}::${activationMode}`;
793+ })}::${scopeKey}::${setupOnlyKey}::${setupOnlyModeKey}::${setupOnlyRequirementKey}::${startupChannelMode}::${bundledArtifactMode}::${moduleLoadMode}::${discoveryMode}::${runtimeSubagentMode}::${params.pluginSdkResolution ?? "auto"}::${gatewayMethodsKey}::${activationMode}`;
738794}
739795740796function matchesScopedPluginRequest(params: {
@@ -812,6 +868,7 @@ function hasExplicitCompatibilityInputs(options: PluginLoadOptions): boolean {
812868options.forceSetupOnlyChannelPlugins === true ||
813869options.requireSetupEntryForSetupOnlyChannelPlugins === true ||
814870options.preferSetupRuntimeForChannelPlugins === true ||
871+options.preferBuiltPluginArtifacts === true ||
815872options.loadModules === false
816873);
817874}
@@ -1011,6 +1068,7 @@ function resolvePluginLoadCacheContext(options: PluginLoadOptions = {}) {
10111068const requireSetupEntryForSetupOnlyChannelPlugins =
10121069options.requireSetupEntryForSetupOnlyChannelPlugins === true;
10131070const preferSetupRuntimeForChannelPlugins = options.preferSetupRuntimeForChannelPlugins === true;
1071+const preferBuiltPluginArtifacts = options.preferBuiltPluginArtifacts === true;
10141072const runtimeSubagentMode = resolveRuntimeSubagentMode(options.runtimeOptions);
10151073const coreGatewayMethodNames = resolveCoreGatewayMethodNames(options);
10161074const installRecords = {
@@ -1031,6 +1089,7 @@ function resolvePluginLoadCacheContext(options: PluginLoadOptions = {}) {
10311089 forceSetupOnlyChannelPlugins,
10321090 requireSetupEntryForSetupOnlyChannelPlugins,
10331091 preferSetupRuntimeForChannelPlugins,
1092+ preferBuiltPluginArtifacts,
10341093toolDiscovery: options.toolDiscovery,
10351094loadModules: options.loadModules,
10361095 runtimeSubagentMode,
@@ -1050,6 +1109,7 @@ function resolvePluginLoadCacheContext(options: PluginLoadOptions = {}) {
10501109 forceSetupOnlyChannelPlugins,
10511110 requireSetupEntryForSetupOnlyChannelPlugins,
10521111 preferSetupRuntimeForChannelPlugins,
1112+ preferBuiltPluginArtifacts,
10531113shouldActivate: options.activate !== false,
10541114shouldLoadModules: options.loadModules !== false,
10551115 runtimeSubagentMode,
@@ -1375,6 +1435,7 @@ export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegi
13751435 forceSetupOnlyChannelPlugins,
13761436 requireSetupEntryForSetupOnlyChannelPlugins,
13771437 preferSetupRuntimeForChannelPlugins,
1438+ preferBuiltPluginArtifacts,
13781439 shouldActivate,
13791440 shouldLoadModules,
13801441 cacheKey,
@@ -1697,13 +1758,20 @@ export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegi
16971758});
16981759};
16991760const pluginRoot = safeRealpathOrResolve(candidate.rootDir);
1700-let runtimePluginRoot = pluginRoot;
1701-let runtimeCandidateSource =
1702-candidate.origin === "bundled" ? safeRealpathOrResolve(candidate.source) : candidate.source;
1703-let runtimeSetupSource =
1704-candidate.origin === "bundled" && manifestRecord.setupSource
1705- ? safeRealpathOrResolve(manifestRecord.setupSource)
1706- : manifestRecord.setupSource;
1761+const runtimeCandidateEntry = resolvePreferredBuiltBundledRuntimeArtifact({
1762+source: candidate.source,
1763+rootDir: pluginRoot,
1764+origin: candidate.origin,
1765+ preferBuiltPluginArtifacts,
1766+});
1767+const runtimeSetupEntry = manifestRecord.setupSource
1768+ ? resolvePreferredBuiltBundledRuntimeArtifact({
1769+source: manifestRecord.setupSource,
1770+rootDir: pluginRoot,
1771+origin: candidate.origin,
1772+ preferBuiltPluginArtifacts,
1773+})
1774+ : undefined;
1707177517081776const scopedSetupOnlyChannelPluginRequested =
17091777includeSetupOnlyChannelPlugins &&
@@ -1883,12 +1951,12 @@ export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegi
18831951continue;
18841952}
188519531886-const loadSource =
1887-registrationPlan.loadSetupEntry && runtimeSetupSource
1888- ? runtimeSetupSource
1889- : runtimeCandidateSource;
1890-const moduleLoadSource = resolveCanonicalDistRuntimeSource(loadSource);
1891-const moduleRoot = resolveCanonicalDistRuntimeSource(runtimePluginRoot);
1954+const loadEntry =
1955+registrationPlan.loadSetupEntry && runtimeSetupEntry
1956+ ? runtimeSetupEntry
1957+ : runtimeCandidateEntry;
1958+const moduleLoadSource = resolveCanonicalDistRuntimeSource(loadEntry.source);
1959+const moduleRoot = resolveCanonicalDistRuntimeSource(loadEntry.rootDir);
18921960const opened = openBoundaryFileSync({
18931961absolutePath: moduleLoadSource,
18941962rootPath: moduleRoot,
@@ -1972,11 +2040,17 @@ export function loadOpenClawPlugins(options: PluginLoadOptions = {}): PluginRegi
19722040if (
19732041registrationPlan.loadSetupRuntimeEntry &&
19742042setupRegistration.usesBundledSetupContract &&
1975-runtimeCandidateSource !== safeSource
2043+resolveCanonicalDistRuntimeSource(runtimeCandidateEntry.source) !== safeSource
19762044) {
2045+const runtimeModuleSource = resolveCanonicalDistRuntimeSource(
2046+runtimeCandidateEntry.source,
2047+);
2048+const runtimeModuleRoot = resolveCanonicalDistRuntimeSource(
2049+runtimeCandidateEntry.rootDir,
2050+);
19772051const runtimeOpened = openBoundaryFileSync({
1978-absolutePath: runtimeCandidateSource,
1979-rootPath: runtimePluginRoot,
2052+absolutePath: runtimeModuleSource,
2053+rootPath: runtimeModuleRoot,
19802054boundaryLabel: "plugin root",
19812055rejectHardlinks: candidate.origin !== "bundled",
19822056skipLexicalRootCheck: true,
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。