diff --git a/scripts/install.mjs b/scripts/install.mjs index 7478e94..271f72c 100755 --- a/scripts/install.mjs +++ b/scripts/install.mjs @@ -113,6 +113,39 @@ function setJson(pathKey, value) { runOpenclaw(["config", "set", pathKey, JSON.stringify(value), "--json"]); } +function isPlainObject(value) { + return !!value && typeof value === "object" && !Array.isArray(value); +} + +function mergePreservingExisting(base, updates) { + if (!isPlainObject(updates)) return updates; + const out = isPlainObject(base) ? { ...base } : {}; + for (const [key, nextValue] of Object.entries(updates)) { + const currentValue = out[key]; + if (nextValue === undefined) continue; + if (isPlainObject(nextValue)) { + out[key] = mergePreservingExisting(currentValue, nextValue); + continue; + } + if (nextValue === null) { + if (currentValue === undefined) out[key] = null; + continue; + } + if (typeof nextValue === "string") { + if (nextValue === "" && currentValue !== undefined) continue; + out[key] = nextValue; + continue; + } + if (Array.isArray(nextValue)) { + if (nextValue.length === 0 && Array.isArray(currentValue) && currentValue.length > 0) continue; + out[key] = nextValue; + continue; + } + out[key] = nextValue; + } + return out; +} + function unsetPath(pathKey) { runOpenclaw(["config", "unset", pathKey], true); } @@ -185,7 +218,8 @@ if (mode === "install") { plugins.load.paths = loadPaths; plugins.entries = plugins.entries || {}; - plugins.entries.dirigent = { + const existingDirigentEntry = isPlainObject(plugins.entries.dirigent) ? plugins.entries.dirigent : {}; + const desiredDirigentEntry = { enabled: true, config: { enabled: true, @@ -201,6 +235,7 @@ if (mode === "install") { noReplyPort: NO_REPLY_PORT, }, }; + plugins.entries.dirigent = mergePreservingExisting(existingDirigentEntry, desiredDirigentEntry); setJson("plugins", plugins); step(5, 6, "configure no-reply provider");