openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
927 lines (926 loc) • 48.7 kB
JavaScript
import "./src-vebZIeLe.js";
import { t as expectDefined } from "./expect-CyE8FADM.js";
import { c as isRecord } from "./record-coerce-DItp3I4t.js";
import { t as isBlockedObjectKey } from "./prototype-keys-CuYw53fZ.js";
import { x as containsEnvVarReference } from "./redact-BtvPPfTi.js";
import "./utils-P__uGsPB.js";
import { n as normalizeAgentId } from "./agent-id-CeT3w4ap.js";
import { S as toAgentEntriesRecord, a as listAgentEntriesWithSource, i as listAgentEntries, n as hasAgentRosterProperty, s as readAgentRosterProperty } from "./agent-scope-config-DcbEhP0R.js";
import "./session-key-BnWWjqNc.js";
import { t as parseConfigPathArrayIndex } from "./path-array-index-CvEcUJa-.js";
import { n as parseLegacyAgentRoster, r as projectLegacyAgentRosterEntries } from "./legacy.roster-CQ9vDbV2.js";
import { n as createMergePatch, t as applyMergePatch } from "./merge-patch-DCMj2JVh.js";
import { c as hasUnresolvedConfigPath, l as hasUnresolvedConfigPathInSubtree, o as getConfigResolutionFacts } from "./resolution-facts-Dks1tbik.js";
import { n as projectSourceOntoRuntimeShape } from "./runtime-source-projection-DOHmC11j.js";
import { n as normalizeAgentModelRefForConfig, t as normalizeAgentModelMapForConfig } from "./model-input-BuGMCNOz.js";
import { t as coerceConfig } from "./io.read-helpers-ZKp-UiGx.js";
import { n as configIncludeOwnsAgentRosterValues } from "./agent-roster-provenance-TGrT9xta.js";
import { t as isSecretRefShape } from "./redact-snapshot.secret-ref-NJzUnCLU.js";
import { isDeepStrictEqual } from "node:util";
//#region src/config/io.write-prepare.ts
const AGENT_ROSTER_PATHS = [["agents", "entries"], ["agents", "list"]];
var DuplicateAgentRosterIdError = class extends Error {
constructor(agentId) {
super(`Config write cannot canonicalize duplicate normalized agent id "${agentId}".`);
this.name = "DuplicateAgentRosterIdError";
}
};
function assertUniqueNormalizedLegacyRosterIds(value) {
const normalizedIds = /* @__PURE__ */ new Set();
for (const entry of value) {
if (!isRecord(entry) || typeof entry.id !== "string") continue;
const agentId = normalizeAgentId(entry.id);
if (normalizedIds.has(agentId)) throw new DuplicateAgentRosterIdError(agentId);
normalizedIds.add(agentId);
}
}
function hasOwnValidIncludeDirective(value) {
if (!isRecord(value) || !Object.hasOwn(value, "$include")) return false;
const includeValue = value.$include;
return typeof includeValue === "string" || Array.isArray(includeValue) && includeValue.every((entry) => typeof entry === "string");
}
function collectIncludeOwnedPaths(value, path = []) {
if (Array.isArray(value)) return value.flatMap((child, index) => collectIncludeOwnedPaths(child, [...path, String(index)]));
if (!isRecord(value)) return [];
if (hasOwnValidIncludeDirective(value)) return [path];
return Object.entries(value).flatMap(([key, child]) => collectIncludeOwnedPaths(child, [...path, key]));
}
function collectMutableSiblingPathsAtInclude(rootAuthoredConfig, includePath) {
const includeValue = getPathValue(rootAuthoredConfig, includePath);
if (!hasOwnValidIncludeDirective(includeValue)) return [];
return Object.keys(includeValue).flatMap((key) => key === "$include" || isBlockedObjectKey(key) ? [] : [[...includePath, key]]);
}
function isMutableSiblingPathAtInclude(rootAuthoredConfig, includePath, path) {
return collectMutableSiblingPathsAtInclude(rootAuthoredConfig, includePath).some((siblingPath) => {
if (!pathStartsWith(path, siblingPath)) return false;
return !collectIncludeOwnedPaths(getPathValue(rootAuthoredConfig, siblingPath), siblingPath).some((nestedIncludePath) => pathStartsWith(path, nestedIncludePath) || pathStartsWith(nestedIncludePath, path));
});
}
function formatConfigPath(path) {
return path.length > 0 ? path.join(".") : "<root>";
}
function findContainingArrayPath(root, path) {
let current = root;
const currentPath = [];
for (const segment of path) {
if (Array.isArray(current)) return currentPath;
if (!isRecord(current)) return;
current = current[segment];
currentPath.push(segment);
}
}
function hasChangedEquivalentArraySibling(value, nextValue, index) {
if (!Array.isArray(value) || !Array.isArray(nextValue) || index >= value.length) return false;
return value.some((item, itemIndex) => itemIndex !== index && isDeepStrictEqual(item, value[index]) && !isDeepStrictEqual(nextValue[itemIndex], item));
}
function hasNewEquivalentArraySibling(value, nextValue, index) {
if (!Array.isArray(value) || !Array.isArray(nextValue) || index >= value.length) return false;
const includedValue = value[index];
if (!isDeepStrictEqual(nextValue[index], includedValue)) return false;
return nextValue.some((item, itemIndex) => itemIndex !== index && isDeepStrictEqual(item, includedValue) && !isDeepStrictEqual(value[itemIndex], includedValue));
}
function getPathValue(value, path) {
let current = value;
for (const segment of path) {
if (Array.isArray(current)) {
const index = parseArrayIndexPathSegment(segment);
if (index === void 0 || index >= current.length) return;
current = current[index];
continue;
}
if (!isRecord(current)) return;
current = current[segment];
}
return current;
}
function setPathValue(value, path, nextValue) {
if (path.length === 0) return structuredClone(nextValue);
const head = expectDefined(path[0], "config path head");
const tail = path.slice(1);
if (Array.isArray(value)) {
const index = parseArrayIndexPathSegment(head);
if (index === void 0 || index >= value.length) return value;
const next = [...value];
next[index] = setPathValue(value[index], tail, nextValue);
return next;
}
if (!isRecord(value)) return value;
return {
...value,
[head]: setPathValue(value[head], tail, nextValue)
};
}
function pathStartsWith(path, prefix) {
return prefix.length <= path.length && prefix.every((segment, index) => path[index] === segment);
}
function pathOverlapsAny(path, candidates) {
return Boolean(candidates?.some((candidate) => pathStartsWith(path, candidate) || pathStartsWith(candidate, path)));
}
function isIncludeOwnedPath(rootAuthoredConfig, path) {
return collectIncludeOwnedPaths(rootAuthoredConfig).some((includePath) => {
if (!(pathStartsWith(path, includePath) || pathStartsWith(includePath, path))) return false;
return !isMutableSiblingPathAtInclude(rootAuthoredConfig, includePath, path);
});
}
function findOverlappingIncludeOwnedPath(rootAuthoredConfig, path) {
return collectIncludeOwnedPaths(rootAuthoredConfig).find((includePath) => {
if (!(pathStartsWith(path, includePath) || pathStartsWith(includePath, path))) return false;
return !isMutableSiblingPathAtInclude(rootAuthoredConfig, includePath, path);
});
}
function setPathValueCreatingParents(value, path, nextValue) {
if (path.length === 0) return structuredClone(nextValue);
const head = expectDefined(path[0], "config path head");
const tail = path.slice(1);
if (Array.isArray(value) || isNumericPathSegment(head)) {
const index = parseArrayIndexPathSegment(head);
if (index === void 0) return value;
const next = Array.isArray(value) ? [...value] : [];
next[index] = setPathValueCreatingParents(next[index], tail, nextValue);
return next;
}
const record = isRecord(value) ? value : {};
return {
...record,
[head]: setPathValueCreatingParents(record[head], tail, nextValue)
};
}
function deletePathValue(value, path) {
if (path.length === 0) return value;
const head = expectDefined(path[0], "config path head");
const tail = path.slice(1);
if (Array.isArray(value)) {
const index = parseArrayIndexPathSegment(head);
if (index === void 0 || index >= value.length || tail.length === 0) return value;
const next = [...value];
next[index] = deletePathValue(value[index], tail);
return next;
}
if (!isRecord(value) || !Object.hasOwn(value, head)) return value;
const next = { ...value };
if (tail.length === 0) {
delete next[head];
return next;
}
next[head] = deletePathValue(value[head], tail);
return next;
}
function normalizeTouchedAgentModelMapEntries(params) {
const touchedMaps = /* @__PURE__ */ new Map();
const addKey = (path, modelId) => {
const serialized = path.join("\0");
const target = touchedMaps.get(serialized) ?? {
path,
canonicalKeys: /* @__PURE__ */ new Set()
};
target.canonicalKeys.add(normalizeAgentModelRefForConfig(modelId));
touchedMaps.set(serialized, target);
};
const defaultsModelsPatch = getPathValue(params.patch, [
"agents",
"defaults",
"models"
]);
if (isRecord(defaultsModelsPatch)) for (const modelId of Object.keys(defaultsModelsPatch)) addKey([
"agents",
"defaults",
"models"
], modelId);
const entriesPatch = getPathValue(params.patch, ["agents", "entries"]);
if (isRecord(entriesPatch)) {
for (const [agentId, entryPatch] of Object.entries(entriesPatch)) if (isRecord(entryPatch) && isRecord(entryPatch.models)) for (const modelId of Object.keys(entryPatch.models)) addKey([
"agents",
"entries",
agentId,
"models"
], modelId);
}
const explicitModelMaps = [[
"agents",
"defaults",
"models"
]];
const explicitEntries = getPathValue(params.explicitSetValueSource, ["agents", "entries"]);
if (isRecord(explicitEntries)) for (const agentId of Object.keys(explicitEntries)) explicitModelMaps.push([
"agents",
"entries",
agentId,
"models"
]);
for (const modelMapPath of explicitModelMaps) for (const explicitPath of params.explicitSetPaths ?? []) {
if (pathStartsWith(explicitPath, modelMapPath) && explicitPath.length > modelMapPath.length) {
const modelId = explicitPath[modelMapPath.length];
if (modelId) addKey(modelMapPath, modelId);
continue;
}
if (!pathStartsWith(explicitPath, modelMapPath) && !pathStartsWith(modelMapPath, explicitPath)) continue;
const explicitModels = getPathValue(params.explicitSetValueSource, modelMapPath);
if (!isRecord(explicitModels)) continue;
for (const modelId of Object.keys(explicitModels)) addKey(modelMapPath, modelId);
}
let next = params.projectedSource;
for (const { path, canonicalKeys } of touchedMaps.values()) {
const models = getPathValue(next, path);
if (!isRecord(models)) continue;
const touchedEntries = [];
const untouchedEntries = [];
let hasRetiredTouchedKey = false;
for (const [modelId, entry] of Object.entries(models)) {
const normalizedModelId = normalizeAgentModelRefForConfig(modelId);
if (!canonicalKeys.has(normalizedModelId)) {
untouchedEntries.push([modelId, entry]);
continue;
}
touchedEntries.push([modelId, entry]);
hasRetiredTouchedKey ||= normalizedModelId !== modelId;
}
if (hasRetiredTouchedKey) {
const normalizedTouchedEntries = normalizeAgentModelMapForConfig(Object.fromEntries(touchedEntries));
next = setPathValue(next, path, Object.fromEntries([...untouchedEntries, ...Object.entries(normalizedTouchedEntries)]));
}
}
return next;
}
function preserveSourceValueAtPath(params) {
if (pathOverlapsAny(params.path, params.unsetPaths)) return params.persistedCandidate;
if (isIncludeOwnedPath(params.rootAuthoredConfig, params.path)) return params.persistedCandidate;
if (getPathValue(params.nextConfig, params.path) !== void 0) return params.persistedCandidate;
const sourceValue = params.sourceValue ?? getPathValue(params.sourceConfig, params.path);
if (sourceValue === void 0 || getPathValue(params.persistedCandidate, params.path) !== void 0) return params.persistedCandidate;
return setPathValueCreatingParents(params.persistedCandidate, params.path, sourceValue);
}
function preserveAuthoredAgentParams(params) {
const defaults = getPathValue(params.sourceConfig, ["agents", "defaults"]);
if (!isRecord(defaults)) return params.persistedCandidate;
let next = params.persistedCandidate;
if (Object.hasOwn(defaults, "params")) next = preserveSourceValueAtPath({
...params,
persistedCandidate: next,
path: [
"agents",
"defaults",
"params"
],
sourceValue: defaults.params
});
const models = defaults.models;
if (!isRecord(models)) return next;
const nextModels = getPathValue(params.nextConfig, [
"agents",
"defaults",
"models"
]);
for (const [modelId, modelEntry] of Object.entries(models)) {
if (!isRecord(modelEntry) || !Object.hasOwn(modelEntry, "params")) continue;
const modelPath = [
"agents",
"defaults",
"models",
normalizeAgentModelRefForConfig(modelId) || modelId
];
const normalizedModelId = modelPath.at(-1);
if (isRecord(nextModels) && normalizedModelId && !Object.hasOwn(nextModels, normalizedModelId)) continue;
const paramsPath = [...modelPath, "params"];
if (modelPath.at(-1) !== modelId) next = deletePathValue(next, [
"agents",
"defaults",
"models",
modelId
]);
if (getPathValue(next, modelPath) === void 0) {
next = preserveSourceValueAtPath({
...params,
persistedCandidate: next,
path: modelPath,
sourceValue: modelEntry
});
continue;
}
next = preserveSourceValueAtPath({
...params,
persistedCandidate: next,
path: paramsPath,
sourceValue: modelEntry.params
});
}
return next;
}
function projectRootAuthoredIncludeSibling(params) {
if (params.nextPresent && params.baselinePresent && isDeepStrictEqual(params.next, params.baseline)) return {
ok: true,
present: true,
value: structuredClone(params.authored)
};
if (!params.nextPresent) return collectIncludeOwnedPaths(params.authored).length > 0 ? { ok: false } : {
ok: true,
present: false
};
if (!params.baselinePresent) return {
ok: true,
present: true,
value: structuredClone(params.next)
};
if (hasOwnValidIncludeDirective(params.authored)) return { ok: false };
if (Array.isArray(params.authored)) return Array.isArray(params.next) ? { ok: false } : {
ok: true,
present: true,
value: structuredClone(params.next)
};
if (!isRecord(params.authored)) return {
ok: true,
present: true,
value: structuredClone(params.next)
};
if (!isRecord(params.next)) return collectIncludeOwnedPaths(params.authored).length > 0 ? { ok: false } : {
ok: true,
present: true,
value: structuredClone(params.next)
};
if (!isRecord(params.baseline)) return {
ok: true,
present: true,
value: structuredClone(params.next)
};
const value = structuredClone(params.authored);
const keys = /* @__PURE__ */ new Set([
...Object.keys(params.authored),
...Object.keys(params.baseline),
...Object.keys(params.next)
]);
for (const key of keys) {
if (isBlockedObjectKey(key)) continue;
const authoredPresent = Object.hasOwn(params.authored, key);
const baselinePresent = Object.hasOwn(params.baseline, key);
const nextPresent = Object.hasOwn(params.next, key);
if (!authoredPresent) {
if (baselinePresent && nextPresent && isDeepStrictEqual(params.baseline[key], params.next[key])) continue;
if (!nextPresent) return { ok: false };
if (baselinePresent && Array.isArray(params.baseline[key]) && Array.isArray(params.next[key])) return { ok: false };
}
const projected = projectRootAuthoredIncludeSibling({
authored: authoredPresent ? params.authored[key] : {},
baseline: params.baseline[key],
next: params.next[key],
baselinePresent,
nextPresent
});
if (!projected.ok) return projected;
if (projected.present) value[key] = projected.value;
else delete value[key];
}
return {
ok: true,
present: true,
value
};
}
function preserveUntouchedIncludes(params) {
let next = params.persistedCandidate;
for (const includePath of collectIncludeOwnedPaths(params.rootAuthoredConfig)) {
const containingArrayPath = findContainingArrayPath(params.rootAuthoredConfig, includePath);
const includeIsArrayEntry = containingArrayPath !== void 0 && includePath.length === containingArrayPath.length + 1;
const comparisonPath = includeIsArrayEntry ? includePath : containingArrayPath ?? includePath;
const mutableSiblingPaths = collectMutableSiblingPathsAtInclude(params.rootAuthoredConfig, includePath);
const relativeMutableSiblingPaths = mutableSiblingPaths.map((path) => path.slice(comparisonPath.length));
const omitMutableSiblingValues = (value) => relativeMutableSiblingPaths.reduce((current, path) => deletePathValue(current, path), value);
const nextValue = omitMutableSiblingValues(getPathValue(params.nextConfig, comparisonPath));
const sourceValue = omitMutableSiblingValues(getPathValue(params.sourceConfig, comparisonPath));
const runtimeValue = omitMutableSiblingValues(getPathValue(params.runtimeConfig, comparisonPath));
if (!isDeepStrictEqual(nextValue, sourceValue) && !isDeepStrictEqual(nextValue, runtimeValue)) throw new Error(`Config write would flatten $include-owned config at ${formatConfigPath(includePath)}; edit that include file directly or remove the $include first.`);
if (includeIsArrayEntry) {
const index = parseArrayIndexPathSegment(includePath.at(-1) ?? "");
const nextArray = getPathValue(params.nextConfig, containingArrayPath);
const sourceArray = getPathValue(params.sourceConfig, containingArrayPath);
const runtimeArray = getPathValue(params.runtimeConfig, containingArrayPath);
if (index !== void 0 && (hasChangedEquivalentArraySibling(sourceArray, nextArray, index) || hasChangedEquivalentArraySibling(runtimeArray, nextArray, index) || hasNewEquivalentArraySibling(sourceArray, nextArray, index) || hasNewEquivalentArraySibling(runtimeArray, nextArray, index))) throw new Error(`Config write would flatten $include-owned config at ${formatConfigPath(includePath)}; edit that include file directly or remove the $include first.`);
}
let authoredIncludeValue = getPathValue(params.rootAuthoredConfig, includePath);
for (const siblingPath of mutableSiblingPaths) {
const relativeSiblingPath = siblingPath.slice(includePath.length);
const nextPresent = hasPathValue(params.nextConfig, siblingPath);
const projectAgainst = (baselineConfig) => projectRootAuthoredIncludeSibling({
authored: getPathValue(params.rootAuthoredConfig, siblingPath),
baseline: getPathValue(baselineConfig, siblingPath),
next: getPathValue(params.nextConfig, siblingPath),
baselinePresent: hasPathValue(baselineConfig, siblingPath),
nextPresent
});
const sourceProjection = projectAgainst(params.sourceConfig);
const projection = sourceProjection.ok ? sourceProjection : projectAgainst(params.runtimeConfig);
if (!projection.ok) throw new Error(`Config write would flatten $include-owned config at ${formatConfigPath(includePath)}; edit that include file directly or remove the $include first.`);
authoredIncludeValue = projection.present ? setPathValue(authoredIncludeValue, relativeSiblingPath, projection.value) : deletePathValue(authoredIncludeValue, relativeSiblingPath);
}
next = setPathValue(next, includePath, authoredIncludeValue);
}
return next;
}
function hasPathValue(value, path) {
if (path.length === 0) return true;
const head = expectDefined(path[0], "config path head");
const tail = path.slice(1);
if (Array.isArray(value)) {
const index = parseArrayIndexPathSegment(head);
if (index === void 0 || index >= value.length) return false;
return tail.length === 0 || hasPathValue(value[index], tail);
}
if (!isRecord(value)) return false;
if (isBlockedObjectKey(head) || !Object.hasOwn(value, head)) return false;
return tail.length === 0 || hasPathValue(value[head], tail);
}
function mergeMissingExplicitValues(currentValue, explicitValue) {
if (!isRecord(currentValue) || !isRecord(explicitValue)) {
if (!Array.isArray(currentValue) || !Array.isArray(explicitValue)) return {
changed: false,
value: currentValue
};
let changed = false;
const next = [...currentValue];
for (const [key, childExplicitValue] of Object.entries(explicitValue)) {
const index = parseArrayIndexPathSegment(key);
if (index === void 0) continue;
if (index >= next.length || next[index] === void 0) {
next[index] = structuredClone(childExplicitValue);
changed = true;
continue;
}
const childMerged = mergeMissingExplicitValues(next[index], childExplicitValue);
if (childMerged.changed) {
next[index] = childMerged.value;
changed = true;
}
}
return {
changed,
value: changed ? next : currentValue
};
}
let changed = false;
const next = { ...currentValue };
for (const [key, childExplicitValue] of Object.entries(explicitValue)) {
if (isBlockedObjectKey(key)) continue;
if (!Object.hasOwn(next, key)) {
next[key] = structuredClone(childExplicitValue);
changed = true;
continue;
}
const childMerged = mergeMissingExplicitValues(next[key], childExplicitValue);
if (childMerged.changed) {
next[key] = childMerged.value;
changed = true;
}
}
return {
changed,
value: changed ? next : currentValue
};
}
function injectExplicitlySetPaths(params) {
if (!params.explicitSetPaths || params.explicitSetPaths.length === 0) return params.persistedCandidate;
let next = params.persistedCandidate;
for (const path of params.explicitSetPaths) {
if (path.length === 0 || path.some(isBlockedObjectKey)) continue;
const includeOwnedPath = params.rootAuthoredConfig ? findOverlappingIncludeOwnedPath(params.rootAuthoredConfig, [...path]) : void 0;
const preserveDescendantInclude = includeOwnedPath && params.preserveDescendantIncludes === true && includeOwnedPath.length > path.length && pathStartsWith(includeOwnedPath, path);
const allowIncludeAncestorOverride = includeOwnedPath !== void 0 && includeOwnedPath.length < path.length && pathStartsWith(path, includeOwnedPath) && params.allowIncludeAncestorExplicitSetPaths === true;
if (includeOwnedPath && !preserveDescendantInclude && !allowIncludeAncestorOverride) throw new Error(`Config write would flatten $include-owned config at ${formatConfigPath(includeOwnedPath)}; edit that include file directly or remove the $include first.`);
const nextValue = getPathValue(params.valueSource, [...path]);
if (nextValue === void 0) continue;
if (!hasPathValue(next, path)) {
next = setPathValueCreatingParents(next, [...path], nextValue);
continue;
}
const merged = mergeMissingExplicitValues(getPathValue(next, [...path]), nextValue);
if (merged.changed) next = setPathValue(next, [...path], merged.value);
}
return next;
}
function pathTouchesAgentRoster(path) {
return AGENT_ROSTER_PATHS.some((rosterPath) => pathStartsWith(path, rosterPath) || pathStartsWith(rosterPath, path));
}
function pathTargetsAgentRoster(path) {
return AGENT_ROSTER_PATHS.some((rosterPath) => pathStartsWith(path, rosterPath));
}
function canCanonicalizeAgentRoster(value) {
const roster = readAgentRosterProperty(value);
if (!roster) return false;
if (roster.kind === "list") {
if (!Array.isArray(roster.value) || !roster.value.every((entry) => isRecord(entry) && typeof entry.id === "string")) return false;
assertUniqueNormalizedLegacyRosterIds(roster.value);
return true;
}
return isRecord(roster.value) && Object.values(roster.value).every(isRecord);
}
function shouldPersistCanonicalAgentRoster(params) {
if (!canCanonicalizeAgentRoster(params.nextConfig)) return false;
if (params.persistCanonicalAgentRoster === true || params.explicitSetPaths?.some(pathTouchesAgentRoster) || params.unsetPaths?.some(pathTouchesAgentRoster)) return true;
const runtimeRoster = toAgentEntriesRecord(listAgentEntries(params.runtimeConfig));
const sourceRoster = toAgentEntriesRecord(listAgentEntries(params.sourceConfig));
const nextRoster = toAgentEntriesRecord(listAgentEntries(params.nextConfig));
return !isDeepStrictEqual(runtimeRoster, nextRoster) && !isDeepStrictEqual(sourceRoster, nextRoster);
}
function assertCanonicalAgentRosterRetainsEntries(params) {
const allowedRemovals = new Set((params.allowedRemovals ?? []).map((agentId) => normalizeAgentId(agentId)));
const canonicalIds = new Set(listAgentEntries(params.canonicalConfig).map((entry) => normalizeAgentId(entry.id)));
const currentRoster = readAgentRosterProperty(params.currentConfig);
const droppedIds = (currentRoster?.kind === "list" && Array.isArray(currentRoster.value) ? projectLegacyAgentRosterEntries(currentRoster.value).entries : listAgentEntries(params.currentConfig)).filter((entry) => {
const agentId = normalizeAgentId(entry.id);
return !canonicalIds.has(agentId) && !allowedRemovals.has(agentId);
}).map((entry) => entry.id).toSorted();
if (droppedIds.length === 0) return;
throw new Error(`Config write would drop agent roster entries without an explicit deletion: ${droppedIds.join(", ")}.`);
}
function containsAuthoredRosterReference(value, includeEnvStrings) {
if (typeof value === "string") return includeEnvStrings && containsEnvVarReference(value);
if (Array.isArray(value)) return value.some((entry) => containsAuthoredRosterReference(entry, includeEnvStrings));
if (!isRecord(value)) return false;
return isSecretRefShape(value) || Object.values(value).some((entry) => containsAuthoredRosterReference(entry, includeEnvStrings));
}
function indexAgentRosterSourcePaths(config, legacyIdsByIndex) {
return new Map(listAgentEntriesWithSource(config).flatMap(({ entry, source }) => {
const id = source.kind === "list" ? legacyIdsByIndex.get(source.index) : entry.id;
return id === void 0 ? [] : [[normalizeAgentId(id), source.kind === "list" ? `agents.list[${source.index}]` : `agents.entries.${source.key}`]];
}));
}
function projectAuthoredRosterValue(params) {
if (!params.nextPresent) return { present: false };
const explicitlySet = params.explicitPaths.some((path) => pathStartsWith(params.path, path));
if (isRecord(params.next)) {
const authored = isRecord(params.authored) ? params.authored : {};
const explicit = isRecord(params.explicit) ? params.explicit : {};
const runtime = isRecord(params.runtime) ? params.runtime : {};
const source = isRecord(params.source) ? params.source : {};
const value = {};
for (const [key, nextValue] of Object.entries(params.next)) {
if (isBlockedObjectKey(key)) continue;
const projected = projectAuthoredRosterValue({
authored: authored[key],
authoredPresent: Object.hasOwn(authored, key),
explicit: explicit[key],
explicitPresent: Object.hasOwn(explicit, key),
explicitPaths: params.explicitPaths,
path: [...params.path, key],
runtime: runtime[key],
runtimePresent: Object.hasOwn(runtime, key),
source: source[key],
sourcePresent: Object.hasOwn(source, key),
next: nextValue,
nextPresent: true
});
if (projected.present) value[key] = projected.value;
}
return {
present: true,
value
};
}
if (Array.isArray(params.next)) {
if (explicitlySet && params.explicitPresent && Array.isArray(params.explicit)) return {
present: true,
value: structuredClone(params.explicit)
};
const authored = Array.isArray(params.authored) ? params.authored : [];
const explicit = Array.isArray(params.explicit) ? params.explicit : [];
const runtime = Array.isArray(params.runtime) ? params.runtime : [];
const source = Array.isArray(params.source) ? params.source : [];
const usedRuntimeIndexes = /* @__PURE__ */ new Set();
const usedSourceIndexes = /* @__PURE__ */ new Set();
const findMatchingIndex = (values, used, nextValue, preferredIndex) => {
if (preferredIndex < values.length && !used.has(preferredIndex) && isDeepStrictEqual(values[preferredIndex], nextValue)) return preferredIndex;
const index = values.findIndex((value, candidate) => !used.has(candidate) && isDeepStrictEqual(value, nextValue));
return index >= 0 ? index : void 0;
};
return {
present: true,
value: params.next.map((nextValue, index) => {
const runtimeIndex = findMatchingIndex(runtime, usedRuntimeIndexes, nextValue, index);
if (runtimeIndex !== void 0) usedRuntimeIndexes.add(runtimeIndex);
const sourceIndex = findMatchingIndex(source, usedSourceIndexes, nextValue, index);
if (sourceIndex !== void 0) usedSourceIndexes.add(sourceIndex);
const fallbackIndexAvailable = !usedRuntimeIndexes.has(index) && !usedSourceIndexes.has(index);
const authoredIndex = runtimeIndex ?? sourceIndex ?? (fallbackIndexAvailable ? index : void 0);
const projected = projectAuthoredRosterValue({
authored: authoredIndex === void 0 ? void 0 : authored[authoredIndex],
authoredPresent: authoredIndex !== void 0 && authoredIndex < authored.length,
explicit: explicit[index],
explicitPresent: index < explicit.length,
explicitPaths: params.explicitPaths,
path: [...params.path, String(index)],
runtime: runtimeIndex === void 0 ? fallbackIndexAvailable ? runtime[index] : void 0 : runtime[runtimeIndex],
runtimePresent: runtimeIndex !== void 0 || fallbackIndexAvailable && index < runtime.length,
source: sourceIndex === void 0 ? fallbackIndexAvailable ? source[index] : void 0 : source[sourceIndex],
sourcePresent: sourceIndex !== void 0 || fallbackIndexAvailable && index < source.length,
next: nextValue,
nextPresent: true
});
return projected.present ? projected.value : nextValue;
})
};
}
if (explicitlySet && params.explicitPresent) return {
present: true,
value: structuredClone(params.explicit)
};
const unchangedFromRuntime = params.runtimePresent && isDeepStrictEqual(params.runtime, params.next);
const unchangedFromSource = params.sourcePresent && isDeepStrictEqual(params.source, params.next);
return {
present: true,
value: params.authoredPresent && (unchangedFromRuntime || unchangedFromSource) ? structuredClone(params.authored) : structuredClone(params.next)
};
}
function indexAgentRosterForWrite(config, legacyIdsByIndex) {
const roster = readAgentRosterProperty(config);
if (roster?.kind !== "list" || !Array.isArray(roster.value)) return toAgentEntriesRecord(listAgentEntries(config));
return Object.fromEntries(roster.value.flatMap((entry, index) => {
const id = legacyIdsByIndex.get(index);
if (!isRecord(entry) || id === void 0) return [];
const { id: _legacyId, ...value } = entry;
return [[id, value]];
}));
}
function canonicalizeAgentRosterForExplicitWrite(params) {
const authoredRoster = readAgentRosterProperty(params.rootAuthoredConfig);
const preMigrationRoster = readAgentRosterProperty(params.sourceConfigBeforeMigrations);
const resolvedLegacyList = preMigrationRoster?.kind === "list" && Array.isArray(preMigrationRoster.value) ? preMigrationRoster.value : void 0;
const legacyIdsByIndex = new Map(projectLegacyAgentRosterEntries(resolvedLegacyList ?? (authoredRoster?.kind === "list" && Array.isArray(authoredRoster.value) ? authoredRoster.value : [])).entries.map(({ sourceIndex, id }) => [sourceIndex, id]));
const authoredEntries = indexAgentRosterForWrite(params.rootAuthoredConfig, legacyIdsByIndex);
const runtimeEntries = indexAgentRosterForWrite(params.runtimeConfig, legacyIdsByIndex);
const sourceEntries = indexAgentRosterForWrite(params.sourceConfig, legacyIdsByIndex);
const nextEntries = toAgentEntriesRecord(listAgentEntries(params.nextConfig));
const explicitRoster = readAgentRosterProperty(params.valueSource);
const rosterFactOwner = coerceConfig(params.sourceConfigBeforeMigrations ?? params.rootAuthoredConfig);
const sourcePathsByAgentId = indexAgentRosterSourcePaths(rosterFactOwner, legacyIdsByIndex);
const resolutionEvaluated = getConfigResolutionFacts(rosterFactOwner) !== null;
const renamedLegacyIndexes = new Set((params.explicitSetPaths ?? []).flatMap((path) => {
if (path[0] !== "agents" || path[1] !== "list" || path.length !== 4 || path[3] !== "id") return [];
const index = parseArrayIndexPathSegment(path[2] ?? "");
return index === void 0 ? [] : [index];
}));
const structurallyExplicitLegacyIndexes = new Set(renamedLegacyIndexes);
for (const path of params.explicitSetPaths ?? []) {
if (path[0] !== "agents" || path[1] !== "list") continue;
if (path.length === 2 && explicitRoster?.kind === "list" && Array.isArray(explicitRoster.value)) {
explicitRoster.value.forEach((_entry, index) => structurallyExplicitLegacyIndexes.add(index));
continue;
}
if (path.length === 3) {
const index = parseArrayIndexPathSegment(path[2] ?? "");
if (index !== void 0) structurallyExplicitLegacyIndexes.add(index);
}
}
for (const index of renamedLegacyIndexes) {
const entry = explicitRoster?.kind === "list" && Array.isArray(explicitRoster.value) ? explicitRoster.value[index] : void 0;
if (isRecord(entry) && typeof entry.id === "string" && (hasUnresolvedConfigPath(rosterFactOwner, `agents.list[${index}].id`) || !resolutionEvaluated && containsEnvVarReference(entry.id))) throw new Error("Config write cannot safely resolve an env-backed renamed agent id; set the resolved literal id or rename the authored entry directly.");
}
const resolveExplicitLegacyEntryId = (entry, index) => {
const explicitId = entry.id;
if (typeof explicitId !== "string") return;
if (renamedLegacyIndexes.has(index) || Object.hasOwn(nextEntries, explicitId)) return explicitId;
if (authoredRoster?.kind === "list" && Array.isArray(authoredRoster.value)) {
const authoredIndex = authoredRoster.value.findIndex((authoredEntry) => isRecord(authoredEntry) && authoredEntry.id === explicitId);
const resolvedEntry = authoredIndex < 0 ? void 0 : resolvedLegacyList?.[authoredIndex];
if (isRecord(resolvedEntry) && typeof resolvedEntry.id === "string") return resolvedEntry.id;
}
return hasUnresolvedConfigPath(rosterFactOwner, `agents.list[${index}].id`) || containsEnvVarReference(explicitId) ? void 0 : explicitId;
};
if (explicitRoster?.kind === "list" && Array.isArray(explicitRoster.value)) {
const normalizedIds = /* @__PURE__ */ new Set();
for (const [index, entry] of explicitRoster.value.entries()) {
if (!isRecord(entry)) continue;
const resolvedId = resolveExplicitLegacyEntryId(entry, index);
if (resolvedId === void 0) continue;
const agentId = normalizeAgentId(resolvedId);
if (normalizedIds.has(agentId)) throw new DuplicateAgentRosterIdError(agentId);
normalizedIds.add(agentId);
}
}
const explicitEntries = explicitRoster?.kind === "list" && Array.isArray(explicitRoster.value) ? Object.fromEntries(explicitRoster.value.flatMap((entry, index) => {
if (!isRecord(entry)) return [];
const id = structurallyExplicitLegacyIndexes.has(index) ? resolveExplicitLegacyEntryId(entry, index) : legacyIdsByIndex.get(index) ?? entry.id;
if (typeof id !== "string") {
if (structurallyExplicitLegacyIndexes.has(index) && typeof entry.id === "string") throw new Error(`Config write cannot safely resolve an explicitly replaced agent list slot for id "${entry.id}"; use a resolved literal id before writing the roster.`);
return [];
}
const { id: _explicitId, ...config } = entry;
return [[id, config]];
})) : toAgentEntriesRecord(listAgentEntries(params.valueSource));
const explicitPaths = (params.explicitSetPaths ?? []).flatMap((path) => {
if (path[0] !== "agents") return [];
if (path.length === 1) return [[]];
if (path[1] === "entries") return [path.slice(2)];
if (path[1] !== "list") return [];
if (path.length === 2) return [[]];
const index = parseArrayIndexPathSegment(path[2] ?? "");
const explicitEntry = explicitRoster?.kind === "list" && Array.isArray(explicitRoster.value) && index !== void 0 ? explicitRoster.value[index] : void 0;
const id = index !== void 0 && (renamedLegacyIndexes.has(index) || path.length === 3 && structurallyExplicitLegacyIndexes.has(index)) && isRecord(explicitEntry) ? explicitEntry.id : index === void 0 ? void 0 : legacyIdsByIndex.get(index);
return typeof id === "string" ? [[id, ...path.slice(3)]] : [];
});
const entryIdentityByNextId = /* @__PURE__ */ new Map();
for (const id of Object.keys(nextEntries)) if (Object.hasOwn(runtimeEntries, id) || Object.hasOwn(sourceEntries, id)) entryIdentityByNextId.set(id, id);
if (authoredRoster?.kind === "list" && Array.isArray(authoredRoster.value) && explicitRoster?.kind === "list" && Array.isArray(explicitRoster.value)) for (const path of params.explicitSetPaths ?? []) {
if (path[0] !== "agents" || path[1] !== "list" || path.length !== 4 || path[3] !== "id") continue;
const index = parseArrayIndexPathSegment(path[2] ?? "");
const explicitEntry = index === void 0 ? void 0 : explicitRoster.value[index];
const oldId = index === void 0 ? void 0 : legacyIdsByIndex.get(index);
const nextId = isRecord(explicitEntry) ? explicitEntry.id : void 0;
if (typeof oldId === "string" && typeof nextId === "string") entryIdentityByNextId.set(nextId, oldId);
}
const priorIds = /* @__PURE__ */ new Set([...Object.keys(runtimeEntries), ...Object.keys(sourceEntries)]);
const removedIds = [...priorIds].filter((id) => !Object.hasOwn(nextEntries, id));
const addedIds = Object.keys(nextEntries).filter((id) => !priorIds.has(id));
const claimedPriorIds = new Set(entryIdentityByNextId.values());
for (const nextId of addedIds) {
if (entryIdentityByNextId.has(nextId)) continue;
const candidates = removedIds.filter((oldId) => !claimedPriorIds.has(oldId) && (isDeepStrictEqual(nextEntries[nextId], runtimeEntries[oldId]) || isDeepStrictEqual(nextEntries[nextId], sourceEntries[oldId])));
if (candidates.length === 1) {
const oldId = candidates[0];
entryIdentityByNextId.set(nextId, oldId);
claimedPriorIds.add(oldId);
}
}
const ambiguousAddedIds = addedIds.filter((id) => !entryIdentityByNextId.has(id));
const ambiguousRemovedIds = removedIds.filter((id) => !claimedPriorIds.has(id));
if (ambiguousAddedIds.length > 0 && ambiguousRemovedIds.some((id) => {
const sourcePath = sourcePathsByAgentId.get(normalizeAgentId(id));
return containsAuthoredRosterReference(authoredEntries[id], !resolutionEvaluated) || Boolean(sourcePath && hasUnresolvedConfigPathInSubtree(rosterFactOwner, sourcePath));
})) throw new Error("Config write cannot safely match renamed agent entries with authored references; rename agents one at a time.");
let entries = Object.fromEntries(Object.entries(nextEntries).map(([id, nextEntry]) => {
const priorId = entryIdentityByNextId.get(id) ?? id;
const projected = projectAuthoredRosterValue({
authored: authoredEntries[priorId],
authoredPresent: Object.hasOwn(authoredEntries, priorId),
explicit: explicitEntries[id],
explicitPresent: Object.hasOwn(explicitEntries, id),
explicitPaths,
path: [id],
runtime: runtimeEntries[priorId],
runtimePresent: Object.hasOwn(runtimeEntries, priorId),
source: sourceEntries[priorId],
sourcePresent: Object.hasOwn(sourceEntries, priorId),
next: nextEntry,
nextPresent: true
});
const value = projected.present ? projected.value : nextEntry;
if (isRecord(value) && isRecord(nextEntry)) {
if (Object.hasOwn(nextEntry, "default")) {
const sourcePath = sourcePathsByAgentId.get(normalizeAgentId(priorId));
if (!(Object.hasOwn(value, "default") && (containsAuthoredRosterReference(value.default, !resolutionEvaluated) || Boolean(sourcePath && hasUnresolvedConfigPathInSubtree(rosterFactOwner, `${sourcePath}.default`))) && (Object.hasOwn(runtimeEntries, priorId) && isRecord(runtimeEntries[priorId]) && isDeepStrictEqual(runtimeEntries[priorId].default, nextEntry.default) || Object.hasOwn(sourceEntries, priorId) && isRecord(sourceEntries[priorId]) && isDeepStrictEqual(sourceEntries[priorId].default, nextEntry.default)))) value.default = structuredClone(nextEntry.default);
} else delete value.default;
}
return [id, value];
}));
if (authoredRoster?.kind === "list" && Array.isArray(authoredRoster.value)) {
const nextIdByPriorId = new Map([...entryIdentityByNextId].map(([nextId, priorId]) => [priorId, nextId]));
const resolveExplicitLegacyIdCandidate = (index) => {
if (explicitRoster?.kind !== "list" || !Array.isArray(explicitRoster.value)) return;
const explicitEntry = explicitRoster.value[index];
if (!isRecord(explicitEntry)) return;
const id = resolveExplicitLegacyEntryId(explicitEntry, index);
return id === void 0 ? void 0 : normalizeAgentId(id);
};
const resolveExplicitLegacyId = (index) => {
const resolvedId = resolveExplicitLegacyIdCandidate(index);
if (!resolvedId || explicitRoster?.kind !== "list" || !Array.isArray(explicitRoster.value)) throw new Error("Config write cannot safely resolve an explicitly replaced agent list slot for unset.");
for (const [candidateIndex] of explicitRoster.value.entries()) {
if (candidateIndex === index) continue;
const candidateId = resolveExplicitLegacyIdCandidate(candidateIndex);
if (!candidateId) throw new Error("Config write cannot safely resolve every explicit agent id across an indexed list unset.");
if (candidateId === resolvedId) throw new Error("Config write cannot safely resolve duplicate agent ids across an indexed list unset.");
}
return resolvedId;
};
for (const unsetPath of params.unsetPaths ?? []) {
if (unsetPath[0] !== "agents" || unsetPath[1] !== "list") continue;
if (unsetPath.length === 2) {
entries = void 0;
break;
}
if (unsetPath.length === 4 && unsetPath[3] === "id") throw new Error("Config write cannot unset an agent id; delete the complete roster entry instead.");
const index = parseArrayIndexPathSegment(unsetPath[2] ?? "");
const explicitResolvedId = index !== void 0 && structurallyExplicitLegacyIndexes.has(index) && index !== void 0 ? resolveExplicitLegacyId(index) : void 0;
const id = explicitResolvedId !== void 0 ? explicitResolvedId : index === void 0 ? void 0 : legacyIdsByIndex.get(index);
if (typeof id !== "string") continue;
const targetId = explicitResolvedId !== void 0 ? id : nextIdByPriorId.get(id) ?? id;
entries = deletePathValue(entries, [targetId, ...unsetPath.slice(3)]);
}
}
const withoutLegacyList = deletePathValue(params.valueSource, ["agents", "list"]);
return entries === void 0 ? deletePathValue(withoutLegacyList, ["agents", "entries"]) : setPathValueCreatingParents(withoutLegacyList, ["agents", "entries"], entries);
}
function restoreAuthoredAgentRoster(value, rootAuthoredConfig) {
let next = deletePathValue(value, ["agents", "entries"]);
next = deletePathValue(next, ["agents", "list"]);
const authoredRoster = readAgentRosterProperty(rootAuthoredConfig);
if (authoredRoster) return setPathValueCreatingParents(next, ["agents", authoredRoster.kind], authoredRoster.value);
return !hasPathValue(rootAuthoredConfig, ["agents"]) && isDeepStrictEqual(getPathValue(next, ["agents"]), {}) ? deletePathValue(next, ["agents"]) : next;
}
function projectAuthoredAgentRosterForWrite(params) {
const authoredRoster = readAgentRosterProperty(params.rootAuthoredConfig);
if (authoredRoster?.kind !== "list" || !Array.isArray(authoredRoster.value)) return params.rootAuthoredConfig;
const preMigrationRoster = readAgentRosterProperty(params.sourceConfigBeforeMigrations);
const resolvedLegacyList = preMigrationRoster?.kind === "list" && Array.isArray(preMigrationRoster.value) ? preMigrationRoster.value : void 0;
if (collectIncludeOwnedPaths(authoredRoster.value).length > 0 && !parseLegacyAgentRoster(resolvedLegacyList ?? authoredRoster.value)) throw new Error("Config write cannot safely match $include-owned legacy agent entries; repair their ids in the authored config first.");
const legacyIdsByIndex = new Map(projectLegacyAgentRosterEntries(resolvedLegacyList ?? authoredRoster.value).entries.map(({ sourceIndex, id }) => [sourceIndex, id]));
const entries = indexAgentRosterForWrite(params.rootAuthoredConfig, legacyIdsByIndex);
return setPathValueCreatingParents(deletePathValue(deletePathValue(params.rootAuthoredConfig, ["agents", "list"]), ["agents", "entries"]), ["agents", "entries"], entries);
}
function resolvePersistCandidateForWrite(params) {
const patch = createMergePatch(params.runtimeConfig, params.nextConfig);
const projectedSource = normalizeTouchedAgentModelMapEntries({
projectedSource: projectSourceOntoRuntimeShape(params.sourceConfig, params.runtimeConfig),
patch,
explicitSetPaths: params.explicitSetPaths,
explicitSetValueSource: params.explicitSetValueSource ?? params.nextConfig
});
const rootAuthoredConfig = params.rootAuthoredConfig ?? params.sourceConfig;
const persistCanonicalRoster = shouldPersistCanonicalAgentRoster(params);
if (persistCanonicalRoster && configIncludeOwnsAgentRosterValues({
parsed: rootAuthoredConfig,
sourceConfigBeforeMigrations: params.sourceConfigBeforeMigrations ?? params.sourceConfig,
includeContributesRoster: params.agentRosterIncludeOwned
})) throw new Error("Config write would flatten $include-owned config at agents; edit that include file directly or remove the $include first.");
const projectedAuthoredRoster = persistCanonicalRoster ? projectAuthoredAgentRosterForWrite({
rootAuthoredConfig,
sourceConfigBeforeMigrations: params.sourceConfigBeforeMigrations
}) : rootAuthoredConfig;
const includeProjectionRootAuthoredConfig = persistCanonicalRoster && !hasAgentRosterProperty(projectedAuthoredRoster) ? setPathValueCreatingParents(projectedAuthoredRoster, ["agents", "entries"], toAgentEntriesRecord(listAgentEntries(params.sourceConfig))) : projectedAuthoredRoster;
let persistedBase = preserveUntouchedIncludes({
runtimeConfig: params.runtimeConfig,
sourceConfig: params.sourceConfig,
nextConfig: params.nextConfig,
rootAuthoredConfig: includeProjectionRootAuthoredConfig,
persistedCandidate: applyMergePatch(projectedSource, patch)
});
const explicitSetPaths = persistCanonicalRoster ? [...(params.explicitSetPaths ?? []).filter((path) => !pathTargetsAgentRoster(path)), ["agents", "entries"]] : params.explicitSetPaths;
const explicitSetValueSource = persistCanonicalRoster ? canonicalizeAgentRosterForExplicitWrite({
valueSource: params.explicitSetValueSource ?? params.nextConfig,
rootAuthoredConfig,
runtimeConfig: params.runtimeConfig,
sourceConfig: params.sourceConfig,
sourceConfigBeforeMigrations: params.sourceConfigBeforeMigrations,
nextConfig: params.nextConfig,
explicitSetPaths: params.explicitSetPaths,
unsetPaths: params.unsetPaths
}) : params.explicitSetValueSource ?? params.nextConfig;
if (persistCanonicalRoster) {
persistedBase = deletePathValue(persistedBase, ["agents", "entries"]);
persistedBase = deletePathValue(persistedBase, ["agents", "list"]);
}
const persisted = injectExplicitlySetPaths({
valueSource: explicitSetValueSource,
persistedCandidate: persistedBase,
explicitSetPaths,
rootAuthoredConfig: includeProjectionRootAuthoredConfig,
preserveDescendantIncludes: persistCanonicalRoster,
allowIncludeAncestorExplicitSetPaths: params.allowIncludeAncestorExplicitSetPaths
});
const withPreservedIncludes = persistCanonicalRoster ? preserveUntouchedIncludes({
runtimeConfig: params.runtimeConfig,
sourceConfig: params.sourceConfig,
nextConfig: params.nextConfig,
rootAuthoredConfig: includeProjectionRootAuthoredConfig,
persistedCandidate: persisted
}) : persisted;
const preserveAuthoredRoster = canCanonicalizeAgentRoster(params.nextConfig) || params.preserveLegacyAgentRoster === true;
const withAuthoredRoster = persistCanonicalRoster || !preserveAuthoredRoster ? withPreservedIncludes : restoreAuthoredAgentRoster(withPreservedIncludes, rootAuthoredConfig);
if (persistCanonicalRoster) assertCanonicalAgentRosterRetainsEntries({
currentConfig: params.sourceConfig,
canonicalConfig: withAuthoredRoster,
allowedRemovals: params.allowedAgentRosterRemovals
});
const withSchema = preserveRootSchemaUri({
rootAuthoredConfig,
nextConfig: params.nextConfig,
persistedCandidate: withAuthoredRoster
});
return params.sourceConfigValid === false ? withSchema : preserveAuthoredAgentParams({
sourceConfig: params.sourceConfig,
nextConfig: params.nextConfig,
rootAuthoredConfig,
persistedCandidate: withSchema,
unsetPaths: params.unsetPaths
});
}
function readRootSchemaUri(value) {
if (!isRecord(value) || typeof value.$schema !== "string") return;
return value.$schema;
}
function hasOwnRootSchemaKey(value) {
return isRecord(value) && Object.hasOwn(value, "$schema");
}
function preserveRootSchemaUri(params) {
if (hasOwnRootSchemaKey(params.nextConfig)) return params.persistedCandidate;
const sourceSchema = readRootSchemaUri(params.rootAuthoredConfig);
if (sourceSchema === void 0 || !isRecord(params.persistedCandidate)) return params.persistedCandidate;
return {
...params.persistedCandidate,
$schema: sourceSchema
};
}
function isNumericPathSegment(raw) {
return parseArrayIndexPathSegment(raw) !== void 0;
}
function parseArrayIndexPathSegment(raw) {
return parseConfigPathArrayIndex(raw);
}
//#endregion
export { resolvePersistCandidateForWrite as n, projectAuthoredAgentRosterForWrite as t };