



























@@ -1,4 +1,5 @@
11import path from "node:path";
2+import type { OpenClawConfig } from "../../config/types.openclaw.js";
23import { formatErrorMessage } from "../../infra/errors.js";
34import { createSubsystemLogger } from "../../logging/subsystem.js";
45import type {
@@ -17,6 +18,7 @@ import {
1718} from "../../plugins/bundled-runtime-root.js";
1819import { unwrapDefaultModuleExport } from "../../plugins/module-export.js";
1920import type { PluginRuntime } from "../../plugins/runtime/types.js";
21+import { normalizeOptionalLowercaseString } from "../../shared/string-coerce.js";
2022import { resolveBundledChannelRootScope, type BundledChannelRootScope } from "./bundled-root.js";
2123import { normalizeChannelMeta } from "./meta-normalization.js";
2224import { isJavaScriptModulePath, loadChannelPluginModule } from "./module-loader.js";
@@ -44,8 +46,12 @@ type BundledChannelSetupEntryRuntimeContract = {
4446loadSetupSecrets?: (
4547options?: BundledEntryModuleLoadOptions,
4648) => ChannelPlugin["secrets"] | undefined;
47-loadLegacyStateMigrationDetector?: () => BundledChannelLegacyStateMigrationDetector;
48-loadLegacySessionSurface?: () => BundledChannelLegacySessionSurface;
49+loadLegacyStateMigrationDetector?: (
50+options?: BundledEntryModuleLoadOptions,
51+) => BundledChannelLegacyStateMigrationDetector;
52+loadLegacySessionSurface?: (
53+options?: BundledEntryModuleLoadOptions,
54+) => BundledChannelLegacySessionSurface;
4955features?: {
5056legacyStateMigrations?: boolean;
5157legacySessionSurfaces?: boolean;
@@ -347,15 +353,74 @@ function listBundledChannelPluginIdsForRoot(
347353.toSorted((left, right) => left.localeCompare(right));
348354}
349355356+function shouldIncludeBundledChannelSetupFeatureForConfig(params: {
357+metadata: BundledChannelPluginMetadata;
358+config?: OpenClawConfig;
359+}): boolean {
360+if (!params.config) {
361+return true;
362+}
363+const plugins = params.config.plugins;
364+if (plugins?.enabled === false) {
365+return false;
366+}
367+const pluginId = params.metadata.manifest.id;
368+if (plugins?.deny?.includes(pluginId)) {
369+return false;
370+}
371+if (plugins?.entries?.[pluginId]?.enabled === false) {
372+return false;
373+}
374+375+let hasExplicitChannelDisable = false;
376+for (const channelId of params.metadata.manifest.channels ?? [pluginId]) {
377+const normalizedChannelId = normalizeOptionalLowercaseString(channelId);
378+if (!normalizedChannelId) {
379+continue;
380+}
381+const channelConfig = (params.config.channels as Record<string, unknown> | undefined)?.[
382+normalizedChannelId
383+];
384+if (!channelConfig || typeof channelConfig !== "object" || Array.isArray(channelConfig)) {
385+continue;
386+}
387+if ((channelConfig as { enabled?: unknown }).enabled === false) {
388+hasExplicitChannelDisable = true;
389+continue;
390+}
391+return true;
392+}
393+394+return !hasExplicitChannelDisable;
395+}
396+350397function listBundledChannelPluginIdsForSetupFeature(
351398rootScope: BundledChannelRootScope,
352399feature: keyof NonNullable<BundledChannelSetupEntryRuntimeContract["features"]>,
400+options: { config?: OpenClawConfig } = {},
353401): readonly ChannelId[] {
354402const hinted = listBundledChannelMetadata(rootScope)
355-.filter((metadata) => metadata.packageManifest?.setupFeatures?.[feature] === true)
403+.filter(
404+(metadata) =>
405+metadata.packageManifest?.setupFeatures?.[feature] === true &&
406+shouldIncludeBundledChannelSetupFeatureForConfig({
407+ metadata,
408+config: options.config,
409+}),
410+)
356411.map((metadata) => metadata.manifest.id)
357412.toSorted((left, right) => left.localeCompare(right));
358-return hinted.length > 0 ? hinted : listBundledChannelPluginIdsForRoot(rootScope);
413+return hinted.length > 0
414+ ? hinted
415+ : listBundledChannelMetadata(rootScope)
416+.filter((metadata) =>
417+shouldIncludeBundledChannelSetupFeatureForConfig({
418+ metadata,
419+config: options.config,
420+}),
421+)
422+.map((metadata) => metadata.manifest.id)
423+.toSorted((left, right) => left.localeCompare(right));
359424}
360425361426export function listBundledChannelPluginIds(): readonly ChannelId[] {
@@ -626,9 +691,12 @@ export function listBundledChannelSetupPlugins(): readonly ChannelPlugin[] {
626691627692export function listBundledChannelSetupPluginsByFeature(
628693feature: keyof NonNullable<BundledChannelSetupEntryRuntimeContract["features"]>,
694+options: { config?: OpenClawConfig } = {},
629695): readonly ChannelPlugin[] {
630696const { rootScope, cacheContext } = resolveActiveBundledChannelCacheScope();
631-return listBundledChannelPluginIdsForSetupFeature(rootScope, feature).flatMap((id) => {
697+return listBundledChannelPluginIdsForSetupFeature(rootScope, feature, {
698+config: options.config,
699+}).flatMap((id) => {
632700const setupEntry = getLazyGeneratedBundledChannelSetupEntryForRoot(id, rootScope, cacheContext);
633701if (!hasSetupEntryFeature(setupEntry, feature)) {
634702return [];
@@ -638,50 +706,50 @@ export function listBundledChannelSetupPluginsByFeature(
638706});
639707}
640708641-export function listBundledChannelLegacySessionSurfaces(): readonly BundledChannelLegacySessionSurface[] {
709+export function listBundledChannelLegacySessionSurfaces(
710+options: {
711+config?: OpenClawConfig;
712+} = {},
713+): readonly BundledChannelLegacySessionSurface[] {
642714const { rootScope, cacheContext } = resolveActiveBundledChannelCacheScope();
643-return listBundledChannelPluginIdsForSetupFeature(rootScope, "legacySessionSurfaces").flatMap(
644-(id) => {
645-const setupEntry = getLazyGeneratedBundledChannelSetupEntryForRoot(
646-id,
647-rootScope,
648-cacheContext,
649-);
650-const surface = setupEntry?.loadLegacySessionSurface?.();
651-if (surface) {
652-return [surface];
653-}
654-if (!hasSetupEntryFeature(setupEntry, "legacySessionSurfaces")) {
655-return [];
656-}
657-const plugin = getBundledChannelSetupPluginForRoot(id, rootScope, cacheContext);
658-return plugin?.messaging ? [plugin.messaging] : [];
659-},
660-);
715+return listBundledChannelPluginIdsForSetupFeature(rootScope, "legacySessionSurfaces", {
716+config: options.config,
717+}).flatMap((id) => {
718+const setupEntry = getLazyGeneratedBundledChannelSetupEntryForRoot(id, rootScope, cacheContext);
719+const surface = setupEntry?.loadLegacySessionSurface?.({ installRuntimeDeps: false });
720+if (surface) {
721+return [surface];
722+}
723+if (!hasSetupEntryFeature(setupEntry, "legacySessionSurfaces")) {
724+return [];
725+}
726+const plugin = getBundledChannelSetupPluginForRoot(id, rootScope, cacheContext);
727+return plugin?.messaging ? [plugin.messaging] : [];
728+});
661729}
662730663-export function listBundledChannelLegacyStateMigrationDetectors(): readonly BundledChannelLegacyStateMigrationDetector[] {
731+export function listBundledChannelLegacyStateMigrationDetectors(
732+options: {
733+config?: OpenClawConfig;
734+} = {},
735+): readonly BundledChannelLegacyStateMigrationDetector[] {
664736const { rootScope, cacheContext } = resolveActiveBundledChannelCacheScope();
665-return listBundledChannelPluginIdsForSetupFeature(rootScope, "legacyStateMigrations").flatMap(
666-(id) => {
667-const setupEntry = getLazyGeneratedBundledChannelSetupEntryForRoot(
668-id,
669-rootScope,
670-cacheContext,
671-);
672-const detector = setupEntry?.loadLegacyStateMigrationDetector?.();
673-if (detector) {
674-return [detector];
675-}
676-if (!hasSetupEntryFeature(setupEntry, "legacyStateMigrations")) {
677-return [];
678-}
679-const plugin = getBundledChannelSetupPluginForRoot(id, rootScope, cacheContext);
680-return plugin?.lifecycle?.detectLegacyStateMigrations
681- ? [plugin.lifecycle.detectLegacyStateMigrations]
682- : [];
683-},
684-);
737+return listBundledChannelPluginIdsForSetupFeature(rootScope, "legacyStateMigrations", {
738+config: options.config,
739+}).flatMap((id) => {
740+const setupEntry = getLazyGeneratedBundledChannelSetupEntryForRoot(id, rootScope, cacheContext);
741+const detector = setupEntry?.loadLegacyStateMigrationDetector?.({ installRuntimeDeps: false });
742+if (detector) {
743+return [detector];
744+}
745+if (!hasSetupEntryFeature(setupEntry, "legacyStateMigrations")) {
746+return [];
747+}
748+const plugin = getBundledChannelSetupPluginForRoot(id, rootScope, cacheContext);
749+return plugin?.lifecycle?.detectLegacyStateMigrations
750+ ? [plugin.lifecycle.detectLegacyStateMigrations]
751+ : [];
752+});
685753}
686754687755export function hasBundledChannelEntryFeature(
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。