mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-02 08:31:33 +00:00
* refactor: remove gateway and channel dead exports * style: format config reload test * refactor: remove newly dead gateway exports * test: preserve approval audience coverage * refactor: preserve gateway contracts while pruning exports * test: retain gateway regression coverage * test: restore gateway policy coverage * test: close dead-export CI gaps * fix: reconcile dead exports with latest main * refactor: remove newly dead gateway runner export * test: remove private worker verifier coverage * test: preserve weak secret docs coverage * fix: avoid gateway health import cycle * fix: preserve node pairing type contract * style: format talk relay test * fix: preserve gateway protocol generation contract * chore: refresh dead export baseline * fix: preserve loaded target compatibility exports * fix: preserve plugin SDK declaration resolution * chore: refresh dead export baseline * chore: refresh dead export baseline * test(gateway): derive private worker service options
57 lines
1.9 KiB
TypeScript
57 lines
1.9 KiB
TypeScript
// Config path diff helper used by gateway mutation diagnostics.
|
|
import { isDeepStrictEqual } from "node:util";
|
|
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
|
import { isPlainObject } from "../utils.js";
|
|
|
|
/** Return dotted config paths whose values differ between two config snapshots. */
|
|
export function diffConfigPaths(prev: unknown, next: unknown, prefix = ""): string[] {
|
|
if (prev === next) {
|
|
return [];
|
|
}
|
|
if (isPlainObject(prev) && isPlainObject(next)) {
|
|
const keys = new Set([...Object.keys(prev), ...Object.keys(next)]);
|
|
const paths: string[] = [];
|
|
for (const key of keys) {
|
|
const prevValue = prev[key];
|
|
const nextValue = next[key];
|
|
if (prevValue === undefined && nextValue === undefined) {
|
|
continue;
|
|
}
|
|
const childPrefix = prefix ? `${prefix}.${key}` : key;
|
|
const childPaths = diffConfigPaths(prevValue, nextValue, childPrefix);
|
|
if (childPaths.length > 0) {
|
|
paths.push(...childPaths);
|
|
}
|
|
}
|
|
return paths;
|
|
}
|
|
if (Array.isArray(prev) && Array.isArray(next)) {
|
|
// Arrays can contain object entries (for example memory.qmd.paths/scope.rules);
|
|
// compare structurally so identical values are not reported as changed.
|
|
if (isDeepStrictEqual(prev, next)) {
|
|
return [];
|
|
}
|
|
}
|
|
return [prefix || "<root>"];
|
|
}
|
|
|
|
/** Preserve startup-only restart boundaries hidden by whole-object config changes. */
|
|
export function diffGatewayReloadPaths(
|
|
prevConfig: OpenClawConfig,
|
|
nextConfig: OpenClawConfig,
|
|
): string[] {
|
|
const changedPaths = diffConfigPaths(prevConfig, nextConfig);
|
|
if (!changedPaths.includes("mcp")) {
|
|
return changedPaths;
|
|
}
|
|
// Adding or removing the whole `mcp` object collapses to the broad `mcp`
|
|
// path. Preserve the Apps boundary so the listener still restarts.
|
|
return [
|
|
...changedPaths,
|
|
...diffConfigPaths(
|
|
{ mcp: { apps: prevConfig.mcp?.apps } },
|
|
{ mcp: { apps: nextConfig.mcp?.apps } },
|
|
),
|
|
];
|
|
}
|