fix(gateway): only sync configured channel plugins and cleanup unconfigured extensions (#898)

This commit is contained in:
paisley
2026-04-23 17:30:53 +08:00
committed by GitHub
parent 956e943072
commit 1b75fec71c
4 changed files with 130 additions and 87 deletions

View File

@@ -164,6 +164,31 @@ function ensureConfiguredPluginsUpgraded(configuredChannels: string[]): void {
}
}
/**
* Remove channel plugin extensions from ~/.openclaw/extensions/ when their
* corresponding channel is no longer configured. This prevents the Gateway
* from scanning residual plugin manifests that were installed by a previous
* configuration but are no longer needed.
*/
function cleanupUnconfiguredChannelPlugins(configuredChannels: string[]): void {
const configuredSet = new Set(configuredChannels);
for (const [channelType, pluginInfo] of Object.entries(CHANNEL_PLUGIN_MAP)) {
if (configuredSet.has(channelType)) continue;
const { dirName } = pluginInfo;
const targetDir = join(homedir(), '.openclaw', 'extensions', dirName);
if (!existsSync(fsPath(targetDir))) continue;
logger.info(`[plugin] Removing unconfigured channel plugin: ${channelType} (${dirName})`);
try {
rmSync(fsPath(targetDir), { recursive: true, force: true });
} catch (err) {
logger.warn(`[plugin] Failed to remove unconfigured channel plugin ${channelType}:`, err);
}
}
}
/**
* Ensure extension-specific packages are resolvable from shared dist/ chunks.
*
@@ -280,36 +305,14 @@ export async function syncGatewayConfigBeforeLaunch(
// Auto-upgrade installed plugins before Gateway starts so that
// the plugin manifest ID matches what sanitize wrote to the config.
// Read config once and reuse for both listConfiguredChannels and plugins.allow.
// Only install/upgrade plugins for channels that are actually configured
// in openclaw.json — do NOT expand the list from plugins.allow.
try {
const rawCfg = await readOpenClawConfig();
const configuredChannels = await listConfiguredChannelsFromConfig(rawCfg);
// Also ensure plugins referenced in plugins.allow are installed even if
// they have no channels.X section yet (e.g. qqbot added via plugins.allow
// but never fully saved through ClawX UI).
try {
const allowList = Array.isArray(rawCfg.plugins?.allow) ? (rawCfg.plugins!.allow as string[]) : [];
const pluginIdToChannel: Record<string, string> = {};
for (const [channelType, info] of Object.entries(CHANNEL_PLUGIN_MAP)) {
pluginIdToChannel[info.dirName] = channelType;
}
pluginIdToChannel['openclaw-lark'] = 'feishu';
pluginIdToChannel['feishu-openclaw-plugin'] = 'feishu';
for (const pluginId of allowList) {
const channelType = pluginIdToChannel[pluginId] ?? pluginId;
if (CHANNEL_PLUGIN_MAP[channelType] && !configuredChannels.includes(channelType)) {
configuredChannels.push(channelType);
}
}
} catch (err) {
logger.warn('[plugin] Failed to augment channel list from plugins.allow:', err);
}
ensureConfiguredPluginsUpgraded(configuredChannels);
cleanupUnconfiguredChannelPlugins(configuredChannels);
} catch (err) {
logger.warn('Failed to auto-upgrade plugins:', err);
}