UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

671 lines (670 loc) 36.4 kB
import { o as asDateTimestampMs } from "./number-coercion-CLj0HTDM.js"; import { r as normalizeProviderId } from "./provider-id-DMd-TDFp.js"; import { s as resolveOpenClawStateSqlitePath } from "./openclaw-state-db-schema-version-c1ZL6JGz.js"; import { n as captureAuthProfileOwnerScope, o as resolveSharedAuthStoreOwnership, s as resolveSharedAuthStorePath } from "./path-resolve-oRkRBkQd.js"; import { D as resolveLegacyAuthProfileSourceCandidates, h as resolveAuthProfileDatabasePath, t as closeAuthProfileReadPool } from "./sqlite-MN_7y26V.js"; import { b as setRuntimeExternalCliProfileIds, c as mergeAuthProfileStores, k as cloneAuthProfileStore, o as loadPersistedAuthProfileStoreAtDatabasePath, v as removePersonalAuthProfileReferences, w as isSafeToAdoptMainStoreOAuthIdentity } from "./persisted-B_qhhBlh.js"; import { a as assertAuthProfileMigrationStateAtDatabasePath, r as assertAuthProfileMigrationCandidates } from "./legacy-source-diagnostic-BNaogmw1.js"; import { isDeepStrictEqual } from "node:util"; import path from "node:path"; //#region src/agents/auth-profiles/ownership.ts function shouldUseMainOwnerForLocalOAuthCredential(params) { if (params.local.type !== "oauth" || params.main?.type !== "oauth") return false; if (!isSafeToAdoptMainStoreOAuthIdentity(params.local, params.main)) return false; if (isDeepStrictEqual(params.local, params.main)) return true; const mainExpires = asDateTimestampMs(params.main.expires); if (mainExpires === void 0) return false; const localExpires = asDateTimestampMs(params.local.expires); return localExpires === void 0 || mainExpires >= localExpires; } function isInheritedMainOAuthCredentialFromStores(params) { if (params.persistedStores.isMainStore || params.credential.type !== "oauth") return false; if (params.persistedStores.localStore?.profiles[params.profileId]) return false; const mainCredential = params.persistedStores.mainStore?.profiles[params.profileId]; return mainCredential?.type === "oauth" && (isDeepStrictEqual(mainCredential, params.credential) || shouldUseMainOwnerForLocalOAuthCredential({ local: params.credential, main: mainCredential })); } //#endregion //#region src/agents/auth-profiles/runtime-snapshot-owner.ts /** Canonical owner identity and nonpublishing auth snapshot composition. */ function createEmptyAuthProfileStore() { return { version: 1, profiles: {} }; } function stripRuntimeExternalProfileMetadata(store) { const stripped = { ...store }; delete stripped.runtimeExternalProfileIds; delete stripped.runtimeExternalProfileIdsAuthoritative; setRuntimeExternalCliProfileIds(stripped, []); return stripped; } function markRuntimePersistedProfiles(store, persistedStore = store) { const profileIds = Object.entries(persistedStore.profiles).flatMap(([profileId, credential]) => isDeepStrictEqual(store.profiles[profileId], credential) ? [profileId] : []).toSorted(); return { ...store, runtimePersistedProfileIds: profileIds.length > 0 ? profileIds : void 0 }; } function setRuntimeLocalProfileMetadata(store, localProfileIds, runtimeInheritsMainState = false) { return { ...store, runtimeLocalProfileIds: [...new Set(localProfileIds)].toSorted(), ...runtimeInheritsMainState ? { runtimeInheritsMainState: true } : {} }; } function runtimeStoreInheritsMainState(store, localStore) { const state = ({ order, lastGood, usageStats }) => ({ order, lastGood, usageStats }); return !isDeepStrictEqual(state(store), state(localStore)); } function listRuntimeLocalProfileIds(store, mainStore) { if (store.runtimeLocalProfileIds) return store.runtimeLocalProfileIds; return Object.entries(store.profiles).flatMap(([profileId, credential]) => mainStore && shouldUseMainOwnerForLocalOAuthCredential({ local: credential, main: mainStore.profiles[profileId] }) ? [] : [profileId]); } function mergeLocalAuthProfileStoreWithInheritedStore(localStore, inheritedStore) { const merged = mergeAuthProfileStores(inheritedStore, localStore, { preserveBaseRuntimeExternalProfiles: true }); return setRuntimeLocalProfileMetadata(stripRuntimeExternalProfileMetadata(merged), listRuntimeLocalProfileIds(localStore, inheritedStore), runtimeStoreInheritsMainState(merged, localStore)); } /** Compose the selected durable owner without publishing or discovering an ambient environment. */ function loadRuntimeAuthProfileOwnerSnapshot(owner, options = {}) { assertAuthProfileMigrationStateAtDatabasePath(owner.databasePath); assertAuthProfileMigrationStateAtDatabasePath(owner.sharedDatabasePath); const isShared = owner.databasePath === owner.sharedDatabasePath; const sharedKind = owner.location === "state-db" ? "shared-state" : "agent"; const sharedStore = isShared ? void 0 : options.inheritedStore ?? markRuntimePersistedProfiles(loadPersistedAuthProfileStoreAtDatabasePath(owner.sharedDatabasePath, sharedKind) ?? createEmptyAuthProfileStore()); if (options.candidates && sharedStore) assertAuthProfileMigrationCandidates({ databasePath: owner.sharedDatabasePath, candidates: options.candidates.shared, hasCredentials: () => Object.keys(sharedStore.profiles).length > 0 }); const localStore = markRuntimePersistedProfiles(loadPersistedAuthProfileStoreAtDatabasePath(owner.databasePath, isShared ? sharedKind : "agent") ?? createEmptyAuthProfileStore()); if (options.candidates) assertAuthProfileMigrationCandidates({ databasePath: owner.databasePath, candidates: isShared ? options.candidates.shared : options.candidates.local, hasCredentials: () => Object.keys(localStore.profiles).length > 0 }); return sharedStore ? mergeLocalAuthProfileStoreWithInheritedStore(localStore, sharedStore) : setRuntimeLocalProfileMetadata(localStore, listRuntimeLocalProfileIds(localStore)); } /** Diagnostic source facts never participate in canonical ownership decisions. */ function captureRuntimeAuthProfileLegacyCandidates(agentDir, env = process.env) { return { local: resolveLegacyAuthProfileSourceCandidates({ agentDir, env }), shared: resolveLegacyAuthProfileSourceCandidates({ env }) }; } function cloneRuntimeAuthProfileLegacyCandidates(candidates) { return candidates && { local: candidates.local.map((source) => ({ ...source })), shared: candidates.shared.map((source) => ({ ...source })) }; } function prepareRuntimeAuthProfileStoreSnapshots(entries, env = process.env) { if (entries.length === 0) return []; const owner = captureRuntimeAuthSharedOwner(env); return entries.map((entry) => { const databasePath = entry.databasePath ?? (entry.agentDir ? resolveAuthProfileDatabasePath(entry.agentDir) : owner.sharedDatabasePath); return { databasePath, agentDir: path.dirname(databasePath), store: cloneAuthProfileStore(entry.store), owner: cloneRuntimeAuthSharedOwner(owner), legacyCandidates: captureRuntimeAuthProfileLegacyCandidates(databasePath === owner.sharedDatabasePath ? void 0 : entry.agentDir ?? path.dirname(databasePath), env) }; }); } function cloneRuntimeAuthSharedOwner(owner) { return owner.kind === "unresolved" ? { ...owner, scope: { ...owner.scope } } : { ...owner }; } function captureRuntimeAuthSharedOwner(env = process.env) { return { kind: "resolved", sharedDatabasePath: resolveSharedAuthStorePath(env), location: resolveSharedAuthStoreOwnership(env).location }; } function runtimeAuthProfileSnapshotSharesOwner(snapshot, owner) { if (snapshot.kind === "resolved") return snapshot.sharedDatabasePath === owner.sharedDatabasePath; return (owner.location === "state-db" ? resolveOpenClawStateSqlitePath({ OPENCLAW_STATE_DIR: snapshot.scope.stateDir }) : path.join(snapshot.scope.sharedMainDir, "openclaw-agent.sqlite")) === owner.sharedDatabasePath; } function runtimeAuthSharedOwnerRebound(previous, next) { return next.kind === "resolved" ? !runtimeAuthProfileSnapshotSharesOwner(previous, next) : !isDeepStrictEqual(previous, next); } function runtimeAuthCredentialState(entries) { return Array.from(entries).filter(([, store]) => Object.keys(store.profiles).length > 0).map(([key, store]) => [key, store.profiles]).toSorted(([left], [right]) => left.localeCompare(right)); } function runtimeAuthOwnerState(store) { if (!store) return; return { order: store.order, profiles: store.profiles, runtimePersistedProfileIds: store.runtimePersistedProfileIds, runtimeExternalProfileIds: store.runtimeExternalProfileIds, runtimeExternalProfileIdsAuthoritative: store.runtimeExternalProfileIdsAuthoritative, runtimeExternalCliProfileIds: store.runtimeExternalCliProfileIds, runtimeLocalProfileIds: store.runtimeLocalProfileIds, runtimeInheritsMainState: store.runtimeInheritsMainState }; } //#endregion //#region src/agents/auth-profiles/mutation-lineage.ts const persistedMutationRecords = /* @__PURE__ */ new Map(); let persistedMutationRevision = 0; let evictedOwnerMutationFloor = 0; const MAX_PERSISTED_MUTATION_OWNERS = 256; const MAX_PERSISTED_MUTATION_PROFILES_PER_OWNER = 256; function resolveRuntimeStoreKey(agentDir) { return agentDir ? resolveAuthProfileDatabasePath(agentDir) : resolveSharedAuthStorePath(); } function maxMutationRevision(record) { return Math.max(record.credentialRevision, record.profileSetRevision, record.stateRevision, record.mutationFloor, ...record.profileRevisions.values()); } function getOrCreatePersistedMutationRecord(ownerKey) { const existing = persistedMutationRecords.get(ownerKey); if (existing) { persistedMutationRecords.delete(ownerKey); persistedMutationRecords.set(ownerKey, existing); return existing; } const record = { credentialRevision: evictedOwnerMutationFloor, credentialRevisionKnown: evictedOwnerMutationFloor === 0, profileSetRevision: evictedOwnerMutationFloor, profileSetRevisionKnown: evictedOwnerMutationFloor === 0, stateRevision: evictedOwnerMutationFloor, stateRevisionKnown: evictedOwnerMutationFloor === 0, mutationFloor: evictedOwnerMutationFloor, profileRevisions: /* @__PURE__ */ new Map() }; persistedMutationRecords.set(ownerKey, record); while (persistedMutationRecords.size > MAX_PERSISTED_MUTATION_OWNERS) { const oldestOwnerKey = persistedMutationRecords.keys().next().value; if (oldestOwnerKey === void 0) break; const oldest = persistedMutationRecords.get(oldestOwnerKey); persistedMutationRecords.delete(oldestOwnerKey); if (oldest) evictedOwnerMutationFloor = Math.max(evictedOwnerMutationFloor, maxMutationRevision(oldest)); } record.mutationFloor = Math.max(record.mutationFloor, evictedOwnerMutationFloor); return record; } function setProfileMutationRevision(record, profileId, revision) { record.profileRevisions.delete(profileId); record.profileRevisions.set(profileId, revision); while (record.profileRevisions.size > MAX_PERSISTED_MUTATION_PROFILES_PER_OWNER) { const oldestProfileId = record.profileRevisions.keys().next().value; if (oldestProfileId === void 0) break; const oldestRevision = record.profileRevisions.get(oldestProfileId) ?? 0; record.profileRevisions.delete(oldestProfileId); record.mutationFloor = Math.max(record.mutationFloor, oldestRevision); } } function getPersistedMutationRecord(ownerKey) { return persistedMutationRecords.get(ownerKey); } function recordRuntimeAuthProfileStorePersistedMutation(ownerKey, mutation) { persistedMutationRevision += 1; const record = getOrCreatePersistedMutationRecord(ownerKey); if (mutation.profileSetChanged) { record.profileSetRevision = persistedMutationRevision; record.profileSetRevisionKnown = true; } if (mutation.credentialsChanged) { record.credentialRevision = persistedMutationRevision; record.credentialRevisionKnown = true; for (const profileId of mutation.profileIds) setProfileMutationRevision(record, profileId, persistedMutationRevision); } if (mutation.stateChanged) { record.stateRevision = persistedMutationRevision; record.stateRevisionKnown = true; } } function combineMutationTokens(tokens) { return { revision: Math.max(0, ...tokens.map((token) => token.revision)), known: tokens.every((token) => token.known) }; } /** Bounded persisted credential lineage; unknown means its exact token was evicted. */ function getRuntimeAuthProfileStoreCredentialMutationToken(agentDir, profileId, options) { const requestedKey = options?.owner?.databasePath ?? resolveRuntimeStoreKey(agentDir); if (!profileId) { const record = getPersistedMutationRecord(requestedKey); return record ? { revision: record.credentialRevision, known: record.credentialRevisionKnown } : { revision: evictedOwnerMutationFloor, known: evictedOwnerMutationFloor === 0 }; } if (options?.includeMain && options.owner?.kind === "unresolved") return { revision: 0, known: false }; const mainKey = !options?.includeMain ? requestedKey : options.owner?.kind === "resolved" ? options.owner.sharedDatabasePath : resolveRuntimeStoreKey(void 0); return combineMutationTokens((requestedKey === mainKey || options?.includeMain !== true ? [requestedKey] : [requestedKey, mainKey]).map((key) => { const record = getPersistedMutationRecord(key); if (!record) return { revision: evictedOwnerMutationFloor, known: evictedOwnerMutationFloor === 0 }; const revision = record.profileRevisions.get(profileId); return revision === void 0 ? { revision: record.mutationFloor, known: record.mutationFloor === 0 } : { revision, known: true }; })); } /** Persisted token for profile-id additions and removals in one owner store. */ function getRuntimeAuthProfileStoreProfileSetMutationToken(agentDir, databasePath) { const record = getPersistedMutationRecord(databasePath ?? resolveRuntimeStoreKey(agentDir)); return record ? { revision: record.profileSetRevision, known: record.profileSetRevisionKnown } : { revision: evictedOwnerMutationFloor, known: evictedOwnerMutationFloor === 0 }; } /** Persisted mutation token for non-secret selection state in one owner store. */ function getRuntimeAuthProfileStoreStateMutationToken(agentDir, options) { const requestedKey = options?.owner?.databasePath ?? resolveRuntimeStoreKey(agentDir); if (options?.includeMain && options.owner?.kind === "unresolved") return { revision: 0, known: false }; const mainKey = !options?.includeMain ? requestedKey : options.owner?.kind === "resolved" ? options.owner.sharedDatabasePath : resolveRuntimeStoreKey(void 0); return combineMutationTokens((requestedKey === mainKey || options?.includeMain !== true ? [requestedKey] : [requestedKey, mainKey]).map((key) => { const record = getPersistedMutationRecord(key); return record ? { revision: record.stateRevision, known: record.stateRevisionKnown } : { revision: evictedOwnerMutationFloor, known: evictedOwnerMutationFloor === 0 }; })); } const testing = { MAX_PERSISTED_MUTATION_OWNERS, MAX_PERSISTED_MUTATION_PROFILES_PER_OWNER, getPersistedMutationRecordCounts() { return { owners: persistedMutationRecords.size, profiles: Math.max(0, ...Array.from(persistedMutationRecords.values(), (record) => record.profileRevisions.size)) }; }, resetPersistedMutationLineage() { persistedMutationRecords.clear(); persistedMutationRevision = 0; evictedOwnerMutationFloor = 0; } }; if (process.env.VITEST || false) globalThis[Symbol.for("openclaw.runtimeAuthSnapshotsTestApi")] = testing; //#endregion //#region src/agents/auth-profiles/runtime-materializations.ts const materializations = /* @__PURE__ */ new Map(); const listeners = /* @__PURE__ */ new Set(); function ownerKey(agentDir) { return agentDir ? resolveAuthProfileDatabasePath(agentDir) : resolveSharedAuthStorePath(); } function notify(agentDir) { const event = { ...agentDir ? { agentDir } : {}, affectsInheritedStores: agentDir === void 0 }; for (const listener of listeners) listener(event); } function registerRuntimeAuthMaterializationMutationListener(listener) { listeners.add(listener); return () => listeners.delete(listener); } /** Records successful auth at the boundary that proved one exact runtime route. */ function recordRuntimeAuthMaterialization(params) { const fact = { provider: normalizeProviderId(params.provider), modelId: params.modelId.trim().toLowerCase(), modelApi: params.modelApi.trim().toLowerCase(), modelBaseUrl: params.modelBaseUrl.trim(), requestTransportOverrides: params.requestTransportOverrides, authMode: params.authMode.trim().toLowerCase(), runtimeOwnerId: params.runtimeOwnerId.trim().toLowerCase(), ...params.authProfileId?.trim() ? { authProfileId: params.authProfileId.trim() } : {} }; if (Object.values(fact).some((value) => !value)) return false; const key = ownerKey(params.agentDir); const existing = materializations.get(key) ?? []; if (existing.some((candidate) => isDeepStrictEqual(candidate, fact))) return false; materializations.set(key, [...existing, fact].slice(-64)); notify(params.agentDir); return true; } /** Revokes all facts backed by one runtime owner after a classified auth failure. */ function revokeRuntimeAuthMaterializations(params) { const key = ownerKey(params.agentDir); const provider = normalizeProviderId(params.provider); const runtimeOwnerId = params.runtimeOwnerId.trim().toLowerCase(); const existing = materializations.get(key); if (!provider || !runtimeOwnerId || !existing) return false; const next = existing.filter((fact) => fact.provider !== provider || fact.runtimeOwnerId !== runtimeOwnerId); if (next.length === existing.length) return false; if (next.length) materializations.set(key, next); else materializations.delete(key); notify(params.agentDir); return true; } function getPreparedRuntimeAuthMaterializations(agentDir) { return materializations.get(ownerKey(agentDir)) ?? []; } /** Clears materializations for an already resolved canonical auth database owner. */ function clearRuntimeAuthMaterializationsAtDatabasePath(databasePath) { materializations.delete(databasePath); } function clearAllRuntimeAuthMaterializations() { materializations.clear(); } //#endregion //#region src/agents/auth-profiles/runtime-snapshots.ts /** * Process-local auth profile snapshots used by prepared runtimes and tests. * Snapshots are cloned at boundaries so callers cannot mutate shared state. */ const runtimeAuthStoreSnapshots = /* @__PURE__ */ new Map(); function runtimeStoreEntries() { return Array.from(runtimeAuthStoreSnapshots, ([key, entry]) => [key, entry.store]); } const runtimeAuthStoreMutationListeners = /* @__PURE__ */ new Set(); let runtimeAuthStoreCredentialsRevision = 0; let runtimeAuthStoreSnapshotsRevision = 0; const runtimeAuthStoreSnapshotRevisions = /* @__PURE__ */ new Map(); function advanceRuntimeAuthStoreSnapshotsRevision() { closeAuthProfileReadPool(); runtimeAuthStoreSnapshotsRevision += 1; } function snapshotOwnershipState(entries) { return Array.from(entries, ([key, entry]) => [key, { state: runtimeAuthOwnerState(entry.store), owner: entry.owner, legacyCandidates: entry.legacyCandidates }]).toSorted(([left], [right]) => left.localeCompare(right)); } function replaceChangesOwner(entries) { const next = new Map(entries.map((entry) => [entry.databasePath, entry])); return !isDeepStrictEqual(snapshotOwnershipState(runtimeAuthStoreSnapshots), snapshotOwnershipState(next)); } function replaceChangesCredentials(entries) { const next = new Map(entries.map((entry) => [resolveRuntimeSnapshotEntryKey(entry), entry.store])); return !isDeepStrictEqual(runtimeAuthCredentialState(runtimeStoreEntries()), runtimeAuthCredentialState(next)); } function recordChangedSnapshotRevisions(entries) { const next = new Map(entries.map((entry) => [entry.databasePath, { store: entry.store, owner: entry.owner, legacyCandidates: entry.legacyCandidates }])); const keys = /* @__PURE__ */ new Set([...runtimeAuthStoreSnapshots.keys(), ...next.keys()]); let changed = false; for (const key of keys) { if (isDeepStrictEqual(runtimeAuthStoreSnapshots.get(key), next.get(key))) continue; changed = true; advanceRuntimeAuthStoreSnapshotsRevision(); if (next.has(key)) runtimeAuthStoreSnapshotRevisions.set(key, runtimeAuthStoreSnapshotsRevision); else runtimeAuthStoreSnapshotRevisions.delete(key); } return changed; } function resolveRuntimeSnapshotEntryKey(entry) { return entry.databasePath ?? resolveRuntimeStoreKey(entry.agentDir); } function notifyRuntimeAuthStoreMutation(agentDir, profileSetChanged = false) { const event = { ...agentDir ? { agentDir } : {}, affectsInheritedStores: agentDir === void 0, profileSetChanged }; for (const listener of runtimeAuthStoreMutationListeners) listener(event); } function authProfilesChanged(previous, next) { return !isDeepStrictEqual(previous?.profiles ?? {}, next?.profiles ?? {}); } function authProfileSetChanged(previous, next) { return !isDeepStrictEqual(Object.keys(previous?.profiles ?? {}).toSorted(), Object.keys(next?.profiles ?? {}).toSorted()); } /** Observes credential snapshot changes at their lifecycle publication edge. */ function registerRuntimeAuthProfileStoreMutationListener(listener) { runtimeAuthStoreMutationListeners.add(listener); return () => runtimeAuthStoreMutationListeners.delete(listener); } /** Reads a cloned runtime auth profile store snapshot for an agent dir. */ function getRuntimeAuthProfileStoreSnapshotCore(agentDir) { return getRuntimeAuthProfileStoreSnapshotAtDatabasePath(resolveRuntimeStoreKey(agentDir)); } function getRuntimeAuthProfileStoreSnapshotAtDatabasePath(databasePath) { const store = runtimeAuthStoreSnapshots.get(databasePath)?.store; return store ? cloneAuthProfileStore(store) : void 0; } function getOwnedRuntimeAuthProfileStoreSnapshotAtDatabasePath(databasePath) { const entry = runtimeAuthStoreSnapshots.get(databasePath); return entry && { databasePath, agentDir: path.dirname(databasePath), store: cloneAuthProfileStore(entry.store), owner: cloneRuntimeAuthSharedOwner(entry.owner), legacyCandidates: cloneRuntimeAuthProfileLegacyCandidates(entry.legacyCandidates) }; } /** * Reads the effective prepared auth store without falling back to persisted storage. * Lifecycle consumers use this after auth publication so request paths never reopen SQLite. */ function getPreparedRuntimeAuthProfileStoreSnapshotCore(agentDir, inheritedAuthDir) { const inheritedKey = resolveRuntimeStoreKey(inheritedAuthDir); const requestedKey = resolveRuntimeStoreKey(agentDir); const inherited = getRuntimeAuthProfileStoreSnapshotAtDatabasePath(inheritedKey); if (requestedKey === inheritedKey) return inherited; const requested = getRuntimeAuthProfileStoreSnapshotAtDatabasePath(requestedKey); if (agentDir && inherited && requested) return mergeAuthProfileStores(inherited, requested, { preserveBaseRuntimeExternalProfiles: true }); return requested ?? inherited; } /** Lists cloned snapshots with their canonical database identity and producer ownership. */ function listOwnedRuntimeAuthProfileStoreSnapshots() { return Array.from(runtimeAuthStoreSnapshots, ([databasePath, entry]) => ({ databasePath, agentDir: path.dirname(databasePath), store: cloneAuthProfileStore(entry.store), owner: cloneRuntimeAuthSharedOwner(entry.owner), legacyCandidates: cloneRuntimeAuthProfileLegacyCandidates(entry.legacyCandidates) })); } /** Select derived snapshots by their producer's shared owner, never directory shape. */ function listRuntimeAuthProfileStoreSnapshotsForSharedOwner(owner) { return listOwnedRuntimeAuthProfileStoreSnapshots().filter((entry) => entry.databasePath !== owner.sharedDatabasePath && runtimeAuthProfileSnapshotSharesOwner(entry.owner, owner)); } /** Returns true when a runtime snapshot exists for an agent dir. */ function hasRuntimeAuthProfileStoreSnapshot(agentDir) { return runtimeAuthStoreSnapshots.has(resolveRuntimeStoreKey(agentDir)); } /** Checks the owned profile keys without copying private credential data out of the owner. */ function hasRuntimeAuthProfileStoreSource(agentDir) { const store = runtimeAuthStoreSnapshots.get(resolveRuntimeStoreKey(agentDir))?.store; return Boolean(store && Object.keys(store.profiles).length > 0); } /** Returns true when requested or main runtime snapshots contain profiles. */ function hasAnyRuntimeAuthProfileStoreSource(agentDir) { return hasRuntimeAuthProfileStoreSource(agentDir) || Boolean(agentDir) && hasRuntimeAuthProfileStoreSource(); } /** Replaces all runtime auth profile snapshots with cloned entries. */ function replaceRuntimeAuthProfileStoreSnapshots(entries) { replaceOwnedRuntimeAuthProfileStoreSnapshots(entries.map((entry) => { const databasePath = resolveRuntimeSnapshotEntryKey(entry); return { databasePath, agentDir: path.dirname(databasePath), store: cloneAuthProfileStore(entry.store), owner: cloneRuntimeAuthSharedOwner(runtimeAuthStoreSnapshots.get(databasePath)?.owner ?? { kind: "unresolved", scope: captureAuthProfileOwnerScope() }), legacyCandidates: cloneRuntimeAuthProfileLegacyCandidates(runtimeAuthStoreSnapshots.get(databasePath)?.legacyCandidates ?? captureRuntimeAuthProfileLegacyCandidates(entry.agentDir ?? (entry.databasePath ? path.dirname(databasePath) : void 0))) }; })); } function replaceOwnedRuntimeAuthProfileStoreSnapshots(entries) { const sharedEntries = entries.map((entry) => ({ ...entry, store: removePersonalAuthProfileReferences(entry.store) })); const reboundKeys = new Set(sharedEntries.filter((entry) => { const previous = runtimeAuthStoreSnapshots.get(entry.databasePath); return previous && runtimeAuthSharedOwnerRebound(previous.owner, entry.owner); }).map((entry) => entry.databasePath)); const credentialsChanged = replaceChangesCredentials(sharedEntries) || reboundKeys.size > 0; const ownerChanged = replaceChangesOwner(sharedEntries); if (credentialsChanged) runtimeAuthStoreCredentialsRevision += 1; const next = new Map(sharedEntries.map((entry) => [resolveRuntimeSnapshotEntryKey(entry), entry.store])); const profileSetChanged = [.../* @__PURE__ */ new Set([...runtimeAuthStoreSnapshots.keys(), ...next.keys()])].some((key) => authProfileSetChanged(runtimeAuthStoreSnapshots.get(key)?.store, next.get(key))); for (const key of /* @__PURE__ */ new Set([...runtimeAuthStoreSnapshots.keys(), ...next.keys()])) if (reboundKeys.has(key) || authProfilesChanged(runtimeAuthStoreSnapshots.get(key)?.store, next.get(key))) clearRuntimeAuthMaterializationsAtDatabasePath(key); recordChangedSnapshotRevisions(sharedEntries); const nextOwned = sharedEntries.map((entry) => { return [resolveRuntimeSnapshotEntryKey(entry), { store: cloneAuthProfileStore(entry.store), owner: cloneRuntimeAuthSharedOwner(entry.owner), legacyCandidates: cloneRuntimeAuthProfileLegacyCandidates(entry.legacyCandidates) }]; }); runtimeAuthStoreSnapshots.clear(); for (const [key, entry] of nextOwned) runtimeAuthStoreSnapshots.set(key, entry); if (ownerChanged) notifyRuntimeAuthStoreMutation(void 0, profileSetChanged); } /** Clears all runtime auth profile snapshots. */ function clearRuntimeAuthProfileStoreSnapshots() { const snapshotsChanged = runtimeAuthStoreSnapshots.size > 0; const credentialsChanged = runtimeAuthCredentialState(runtimeStoreEntries()).length > 0; const profileSetChanged = runtimeStoreEntries().some(([, store]) => Object.keys(store.profiles).length > 0); if (credentialsChanged) runtimeAuthStoreCredentialsRevision += 1; if (snapshotsChanged) advanceRuntimeAuthStoreSnapshotsRevision(); else closeAuthProfileReadPool(); runtimeAuthStoreSnapshots.clear(); clearAllRuntimeAuthMaterializations(); runtimeAuthStoreSnapshotRevisions.clear(); if (snapshotsChanged) notifyRuntimeAuthStoreMutation(void 0, profileSetChanged); } /** Clears one runtime auth-profile snapshot without disturbing other active agents. */ function clearRuntimeAuthProfileStoreSnapshotCore(agentDir) { return clearRuntimeAuthProfileStoreSnapshotAtDatabasePath(resolveRuntimeStoreKey(agentDir), agentDir); } function clearRuntimeAuthProfileStoreSnapshotAtDatabasePath(key, agentDir) { const store = runtimeAuthStoreSnapshots.get(key)?.store; if (!store) return false; if (Object.keys(store.profiles).length > 0) runtimeAuthStoreCredentialsRevision += 1; advanceRuntimeAuthStoreSnapshotsRevision(); runtimeAuthStoreSnapshots.delete(key); clearRuntimeAuthMaterializationsAtDatabasePath(key); runtimeAuthStoreSnapshotRevisions.delete(key); notifyRuntimeAuthStoreMutation(agentDir, Object.keys(store.profiles).length > 0); return true; } function setRuntimeAuthProfileStoreSnapshotAtKey(store, key, agentDir, owner, legacyCandidates) { const sharedStore = removePersonalAuthProfileReferences(store); const previous = runtimeAuthStoreSnapshots.get(key); const sharedOwnerChanged = !isDeepStrictEqual(previous?.owner, owner) || !isDeepStrictEqual(previous?.legacyCandidates, legacyCandidates); const credentialsChanged = !isDeepStrictEqual(runtimeAuthCredentialState(runtimeAuthStoreSnapshots.has(key) ? [[key, runtimeAuthStoreSnapshots.get(key).store]] : []), runtimeAuthCredentialState([[key, sharedStore]])); const sharedOwnerRebound = previous && runtimeAuthSharedOwnerRebound(previous.owner, owner); if (credentialsChanged || sharedOwnerRebound) runtimeAuthStoreCredentialsRevision += 1; const previousStore = previous?.store; const profileSetChanged = authProfileSetChanged(previousStore, sharedStore); if (sharedOwnerRebound || authProfilesChanged(previousStore, sharedStore)) clearRuntimeAuthMaterializationsAtDatabasePath(key); const ownerChanged = sharedOwnerChanged || !isDeepStrictEqual(runtimeAuthOwnerState(previousStore), runtimeAuthOwnerState(sharedStore)); if (sharedOwnerChanged || !isDeepStrictEqual(previousStore, sharedStore)) { advanceRuntimeAuthStoreSnapshotsRevision(); runtimeAuthStoreSnapshotRevisions.set(key, runtimeAuthStoreSnapshotsRevision); } runtimeAuthStoreSnapshots.set(key, { store: cloneAuthProfileStore(sharedStore), owner: cloneRuntimeAuthSharedOwner(owner), legacyCandidates: cloneRuntimeAuthProfileLegacyCandidates(legacyCandidates) }); if (ownerChanged) notifyRuntimeAuthStoreMutation(agentDir, profileSetChanged); } /** Stores a cloned runtime auth profile snapshot for an agent dir. */ function setRuntimeAuthProfileStoreSnapshot(store, agentDir) { setRuntimeAuthProfileStoreSnapshotAtKey(store, resolveRuntimeStoreKey(agentDir), agentDir, captureRuntimeAuthSharedOwner(), captureRuntimeAuthProfileLegacyCandidates(agentDir)); } /** Restore the captured runtime owner independently of the persistence transaction. */ function restoreOwnedRuntimeAuthProfileStoreSnapshot(entry, agentDir) { setRuntimeAuthProfileStoreSnapshotAtKey(entry.store, entry.databasePath, agentDir, entry.owner, entry.legacyCandidates); } /** Materialization changes contents, not the existing producer's shared ownership. */ function updateRuntimeAuthProfileStoreSnapshot(store, agentDir) { const key = resolveRuntimeStoreKey(agentDir); setRuntimeAuthProfileStoreSnapshotAtKey(store, key, agentDir, runtimeAuthStoreSnapshots.get(key)?.owner ?? captureRuntimeAuthSharedOwner(), runtimeAuthStoreSnapshots.get(key)?.legacyCandidates ?? captureRuntimeAuthProfileLegacyCandidates(agentDir)); } /** Stores a cloned snapshot under an already resolved canonical database owner. */ function setRuntimeAuthProfileStoreSnapshotAtDatabasePath(store, databasePath, agentDir, owner, legacyCandidates) { const existing = runtimeAuthStoreSnapshots.get(databasePath); const candidates = "env" in owner ? captureRuntimeAuthProfileLegacyCandidates(databasePath === owner.sharedDatabasePath ? void 0 : agentDir, owner.env) : legacyCandidates ?? (existing && runtimeAuthProfileSnapshotSharesOwner(existing.owner, owner) ? existing.legacyCandidates : void 0); setRuntimeAuthProfileStoreSnapshotAtKey(store, databasePath, agentDir, { kind: "resolved", sharedDatabasePath: owner.sharedDatabasePath, location: owner.location }, candidates); } /** * Invalidates prepared credential ownership after a persisted owner-store write. * Main-store credentials are inherited by custom-agent snapshots, so those * derived snapshots must be dropped even when no exact main snapshot exists. * State-only saves refresh them in the publisher without changing credential ownership. */ function noteRuntimeAuthProfileStorePersistedMutation(agentDir, mutation, owner) { if (!mutation.credentialsChanged && !mutation.profileSetChanged && !mutation.stateChanged) return; if (mutation.credentialsChanged) runtimeAuthStoreCredentialsRevision += 1; const ownerKey = owner?.databasePath ?? resolveRuntimeStoreKey(agentDir); if (mutation.credentialsChanged || mutation.profileSetChanged) clearRuntimeAuthMaterializationsAtDatabasePath(ownerKey); recordRuntimeAuthProfileStorePersistedMutation(ownerKey, mutation); const mainKey = owner?.sharedDatabasePath ?? resolveRuntimeStoreKey(void 0); if (ownerKey !== mainKey || !mutation.credentialsChanged && !mutation.profileSetChanged) return; let deletedDerivedSnapshot = false; const sharedOwner = owner ?? captureRuntimeAuthSharedOwner(); for (const [key, entry] of runtimeAuthStoreSnapshots) if (key !== mainKey && runtimeAuthProfileSnapshotSharesOwner(entry.owner, sharedOwner)) { runtimeAuthStoreSnapshots.delete(key); runtimeAuthStoreSnapshotRevisions.delete(key); deletedDerivedSnapshot = true; } if (deletedDerivedSnapshot) advanceRuntimeAuthStoreSnapshotsRevision(); if (mutation.credentialsChanged || mutation.profileSetChanged) notifyRuntimeAuthStoreMutation(agentDir, mutation.profileSetChanged === true); } /** Stable token for credential ownership without coupling to usage bookkeeping. */ function getRuntimeAuthProfileStoreCredentialsRevision() { return runtimeAuthStoreCredentialsRevision; } function getRuntimeAuthProfileStoreSnapshotsRevision() { return runtimeAuthStoreSnapshotsRevision; } /** Process-local generation for one exact runtime snapshot rollback owner. */ function getRuntimeAuthProfileStoreSnapshotRevision(agentDir) { return getRuntimeAuthProfileStoreSnapshotRevisionAtDatabasePath(resolveRuntimeStoreKey(agentDir)); } /** Process-local generation for an already resolved canonical snapshot owner. */ function getRuntimeAuthProfileStoreSnapshotRevisionAtDatabasePath(databasePath) { return runtimeAuthStoreSnapshotRevisions.get(databasePath) ?? runtimeAuthStoreSnapshotsRevision; } //#endregion export { getRuntimeAuthProfileStoreProfileSetMutationToken as A, runtimeStoreInheritsMainState as B, setRuntimeAuthProfileStoreSnapshotAtDatabasePath as C, registerRuntimeAuthMaterializationMutationListener as D, recordRuntimeAuthMaterialization as E, loadRuntimeAuthProfileOwnerSnapshot as F, stripRuntimeExternalProfileMetadata as H, markRuntimePersistedProfiles as I, mergeLocalAuthProfileStoreWithInheritedStore as L, captureRuntimeAuthProfileLegacyCandidates as M, createEmptyAuthProfileStore as N, revokeRuntimeAuthMaterializations as O, listRuntimeLocalProfileIds as P, prepareRuntimeAuthProfileStoreSnapshots as R, setRuntimeAuthProfileStoreSnapshot as S, getPreparedRuntimeAuthMaterializations as T, isInheritedMainOAuthCredentialFromStores as U, setRuntimeLocalProfileMetadata as V, shouldUseMainOwnerForLocalOAuthCredential as W, noteRuntimeAuthProfileStorePersistedMutation as _, getPreparedRuntimeAuthProfileStoreSnapshotCore as a, replaceRuntimeAuthProfileStoreSnapshots as b, getRuntimeAuthProfileStoreSnapshotCore as c, getRuntimeAuthProfileStoreSnapshotsRevision as d, hasAnyRuntimeAuthProfileStoreSource as f, listRuntimeAuthProfileStoreSnapshotsForSharedOwner as g, listOwnedRuntimeAuthProfileStoreSnapshots as h, getOwnedRuntimeAuthProfileStoreSnapshotAtDatabasePath as i, getRuntimeAuthProfileStoreStateMutationToken as j, getRuntimeAuthProfileStoreCredentialMutationToken as k, getRuntimeAuthProfileStoreSnapshotRevision as l, hasRuntimeAuthProfileStoreSource as m, clearRuntimeAuthProfileStoreSnapshotCore as n, getRuntimeAuthProfileStoreCredentialsRevision as o, hasRuntimeAuthProfileStoreSnapshot as p, clearRuntimeAuthProfileStoreSnapshots as r, getRuntimeAuthProfileStoreSnapshotAtDatabasePath as s, clearRuntimeAuthProfileStoreSnapshotAtDatabasePath as t, getRuntimeAuthProfileStoreSnapshotRevisionAtDatabasePath as u, registerRuntimeAuthProfileStoreMutationListener as v, updateRuntimeAuthProfileStoreSnapshot as w, restoreOwnedRuntimeAuthProfileStoreSnapshot as x, replaceOwnedRuntimeAuthProfileStoreSnapshots as y, runtimeAuthProfileSnapshotSharesOwner as z };