mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 09:40:43 +00:00
Summary: - The PR changes Gateway reload planning, CLI plugin install-index writes, plugin runtime/cache cleanup, docs, changelog, and tests so plugin enable/disable hot reloads while install/update/uninstall stay restart-backed. - Reproducibility: yes. The earlier blocker has a source-level reproduction: run an external plugin install/up ... watches config and only the managed plugin index changes; the PR now tests that path and queues a restart. ClawSweeper fixups: - Included follow-up commit: fix: hot reload plugin management changes - Included follow-up commit: fix(clawsweeper): address review for automerge-openclaw-openclaw-7597… - Ran the ClawSweeper repair loop before final review. Validation: - ClawSweeper review passed for head860594f722. - Required merge gates passed before the squash merge. Prepared head SHA:860594f722Review: https://github.com/openclaw/openclaw/pull/75976#issuecomment-4363168379 Co-authored-by: Peter Steinberger <steipete@gmail.com> Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
59 lines
2.3 KiB
TypeScript
59 lines
2.3 KiB
TypeScript
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
|
import { formatErrorMessage } from "../infra/errors.js";
|
|
import { loadInstalledPluginIndexInstallRecords } from "../plugins/installed-plugin-index-records.js";
|
|
import type { InstalledPluginIndexRefreshReason } from "../plugins/installed-plugin-index.js";
|
|
import { tracePluginLifecyclePhaseAsync } from "../plugins/plugin-lifecycle-trace.js";
|
|
import { refreshPluginRegistry } from "../plugins/plugin-registry.js";
|
|
|
|
export type PluginRegistryRefreshLogger = {
|
|
warn?: (message: string) => void;
|
|
};
|
|
|
|
export async function refreshPluginRegistryAfterConfigMutation(params: {
|
|
config: OpenClawConfig;
|
|
reason: InstalledPluginIndexRefreshReason;
|
|
workspaceDir?: string;
|
|
env?: NodeJS.ProcessEnv;
|
|
installRecords?: Awaited<ReturnType<typeof loadInstalledPluginIndexInstallRecords>>;
|
|
policyPluginIds?: readonly string[];
|
|
traceCommand?: string;
|
|
logger?: PluginRegistryRefreshLogger;
|
|
}): Promise<void> {
|
|
try {
|
|
const installRecords =
|
|
params.installRecords ??
|
|
(await tracePluginLifecyclePhaseAsync(
|
|
"install records load",
|
|
() => loadInstalledPluginIndexInstallRecords(params.env ? { env: params.env } : {}),
|
|
{ command: params.traceCommand ?? "registry-refresh" },
|
|
));
|
|
await tracePluginLifecyclePhaseAsync(
|
|
"registry refresh",
|
|
() =>
|
|
refreshPluginRegistry({
|
|
config: params.config,
|
|
reason: params.reason,
|
|
installRecords,
|
|
...(params.policyPluginIds ? { policyPluginIds: params.policyPluginIds } : {}),
|
|
...(params.workspaceDir ? { workspaceDir: params.workspaceDir } : {}),
|
|
...(params.env ? { env: params.env } : {}),
|
|
}),
|
|
{ command: params.traceCommand ?? "registry-refresh", reason: params.reason },
|
|
);
|
|
} catch (error) {
|
|
params.logger?.warn?.(`Plugin registry refresh failed: ${formatErrorMessage(error)}`);
|
|
}
|
|
await invalidatePluginRuntimeDiscoveryAfterConfigMutation(params);
|
|
}
|
|
|
|
async function invalidatePluginRuntimeDiscoveryAfterConfigMutation(params: {
|
|
logger?: PluginRegistryRefreshLogger;
|
|
}): Promise<void> {
|
|
try {
|
|
const { clearPluginRegistryLoadCache } = await import("../plugins/loader.js");
|
|
clearPluginRegistryLoadCache();
|
|
} catch (error) {
|
|
params.logger?.warn?.(`Plugin runtime cache invalidation failed: ${formatErrorMessage(error)}`);
|
|
}
|
|
}
|