openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
603 lines (602 loc) • 25.4 kB
JavaScript
import { c as isRecord } from "./record-coerce-DItp3I4t.js";
import { c as resolveUserPath } from "./home-dir-BPhrG-aM.js";
import "./utils-P__uGsPB.js";
import { u as resolveAgentDir } from "./agent-scope-config-DcbEhP0R.js";
import { w as resolveStateDir } from "./paths-D2sRr1a_.js";
import { s as coerceSecretRef } from "./types.secrets-kC0nOetj.js";
import { c as normalizeProviderId } from "./model-ref-shared-Dz7QU0Lx.js";
import "./agent-scope-DbtJyKUL.js";
import { i as normalizePluginConfigId } from "./provider-auth-aliases-DhA9c2am.js";
import { r as listKnownSecretEnvVarNames } from "./provider-env-vars-B8XgJCSL.js";
import { o as writeTextFileAtomic, t as isNonEmptyString } from "./shared-CeAc-MzA.js";
import { f as assertExpectedResolvedSecretValue } from "./runtime-shared-CqbaocQu.js";
import { n as getPath, r as setPathCreateStrict, t as deletePathStrict } from "./path-utils-BSrJtisq.js";
import { r as replaceConfigFile } from "./mutate-ZNN4iFCn.js";
import "./config-Cs0XXL3x.js";
import { n as resolveSecretRefValue } from "./resolve-224YoYfx.js";
import { s as resolveSharedAuthStorePath } from "./path-resolve-oRkRBkQd.js";
import { h as resolveAuthProfileDatabasePath } from "./sqlite-MN_7y26V.js";
import { a as loadPersistedAuthProfileStore, i as coercePersistedAuthProfileStore, s as loadPersistedSharedAuthProfileStore } from "./persisted-B_qhhBlh.js";
import { b as saveAuthProfileStoreIfPersistenceSnapshotMatches, p as loadAuthProfileStoreForSecretsRuntime, t as captureAuthProfileStorePersistenceSnapshot, v as restoreAuthProfileStorePersistenceSnapshot } from "./store-F1B2duCT.js";
import "./auth-profiles-BdUEhE7u.js";
import "./model-selection-di2kjKCB.js";
import { t as getSkippedExecRefStaticError } from "./exec-resolution-policy-B4IeYZE3.js";
import { n as listSecretsDotEnvPaths, r as parseEnvAssignmentValue } from "./storage-scan-BMZL5YXA.js";
import { u as prepareSecretsRuntimeSnapshot } from "./runtime-C3AQ3lWb.js";
import { n as listAuthProfileStoreTargets$1, r as iterateAuthProfileCredentials, t as createSecretsConfigIO } from "./config-io-DIBeaezB.js";
import { n as normalizeSecretsPlanOptions, r as resolveValidatedPlanTarget } from "./plan-XE69l6qb.js";
import fs from "node:fs";
import { isDeepStrictEqual } from "node:util";
import os from "node:os";
//#region src/secrets/apply.ts
/** Applies secrets migration plans across config files, auth stores, and env files. */
function planContainsExecReferences(plan) {
if (plan.targets.some((target) => target.ref.source === "exec")) return true;
return Object.values(plan.providerUpserts ?? {}).some((provider) => provider.source === "exec");
}
function hasPluginPolicyId(list, pluginId) {
return Array.isArray(list) && list.some((entry) => normalizePluginConfigId(entry) === pluginId);
}
function findPluginEntry(entries, pluginId) {
if (!isRecord(entries)) return;
for (const [key, value] of Object.entries(entries)) {
if (normalizePluginConfigId(key) !== pluginId) continue;
return isRecord(value) ? value : {};
}
}
function resolveTarget(target) {
const resolved = resolveValidatedPlanTarget(target);
if (!resolved) throw new Error(`Invalid plan target path for ${target.type}: ${target.path}`);
return resolved;
}
function scrubEnvRaw(raw, migratedValues, allowedEnvKeys) {
if (migratedValues.size === 0 || allowedEnvKeys.size === 0) return {
nextRaw: raw,
removed: 0
};
const lines = raw.split(/\r?\n/);
const nextLines = [];
let removed = 0;
for (const line of lines) {
const match = line.match(/^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)$/);
if (!match) {
nextLines.push(line);
continue;
}
const envKey = match[1] ?? "";
if (!allowedEnvKeys.has(envKey)) {
nextLines.push(line);
continue;
}
const parsedValue = parseEnvAssignmentValue(match[2] ?? "");
if (migratedValues.has(parsedValue)) {
removed += 1;
continue;
}
nextLines.push(line);
}
const hadTrailingNewline = raw.endsWith("\n");
const joined = nextLines.join("\n");
return {
nextRaw: hadTrailingNewline || joined.length === 0 ? `${joined}${joined.endsWith("\n") ? "" : "\n"}` : joined,
removed
};
}
function applyProviderPlanMutations(params) {
const currentProviders = isRecord(params.config.secrets?.providers) ? structuredClone(params.config.secrets?.providers) : {};
let changed = false;
for (const providerAlias of params.deletes ?? []) {
if (!Object.hasOwn(currentProviders, providerAlias)) continue;
delete currentProviders[providerAlias];
changed = true;
}
for (const [providerAlias, providerConfig] of Object.entries(params.upserts ?? {})) {
const previous = currentProviders[providerAlias];
if (isDeepStrictEqual(previous, providerConfig)) continue;
currentProviders[providerAlias] = structuredClone(providerConfig);
changed = true;
}
for (const providerConfig of Object.values(params.upserts ?? {})) {
if (providerConfig.source !== "exec" || !("pluginIntegration" in providerConfig)) continue;
const pluginId = normalizePluginConfigId(providerConfig.pluginIntegration.pluginId);
params.config.plugins ??= {};
if (params.config.plugins.enabled === false) throw new Error(`Cannot apply plugin-managed SecretRef provider "${pluginId}" because plugins.enabled is false. Enable plugins before applying this plan.`);
if (hasPluginPolicyId(params.config.plugins.deny, pluginId)) throw new Error(`Cannot apply plugin-managed SecretRef provider "${pluginId}" because plugins.deny includes "${pluginId}". Remove the deny rule before applying this plan.`);
const previousEntry = findPluginEntry(params.config.plugins.entries, pluginId);
if (previousEntry?.enabled === false) throw new Error(`Cannot apply plugin-managed SecretRef provider "${pluginId}" because plugins.entries.${pluginId}.enabled is false. Enable the plugin explicitly before applying this plan.`);
if (Array.isArray(params.config.plugins.allow) && params.config.plugins.allow.length > 0 && !hasPluginPolicyId(params.config.plugins.allow, pluginId)) throw new Error(`Cannot apply plugin-managed SecretRef provider "${pluginId}" because plugins.allow does not include "${pluginId}". Add the plugin to plugins.allow before applying this plan.`);
params.config.plugins.entries ??= {};
if (previousEntry?.enabled === true) continue;
params.config.plugins.entries[pluginId] = {
...isRecord(previousEntry) ? previousEntry : {},
enabled: true
};
changed = true;
}
if (!changed) return false;
params.config.secrets ??= {};
if (Object.keys(currentProviders).length === 0) {
if ("providers" in params.config.secrets) delete params.config.secrets.providers;
return true;
}
params.config.secrets.providers = currentProviders;
return true;
}
async function projectPlanState(params) {
const { snapshot, writeOptions } = await createSecretsConfigIO({ env: params.env }).readConfigFileSnapshotForWrite();
if (!snapshot.valid) throw new Error("Cannot apply secrets plan: config is invalid.");
const options = normalizeSecretsPlanOptions(params.plan.options);
const nextConfig = structuredClone(snapshot.config);
const stateDir = resolveStateDir(params.env, os.homedir);
const authStoreEnv = {
...params.env,
OPENCLAW_STATE_DIR: stateDir
};
const changedFiles = /* @__PURE__ */ new Set();
const warnings = [];
const configPath = resolveUserPath(snapshot.path);
if (applyProviderPlanMutations({
config: nextConfig,
upserts: params.plan.providerUpserts,
deletes: params.plan.providerDeletes
})) changedFiles.add(configPath);
const targetMutations = applyConfigTargetMutations({
planTargets: params.plan.targets,
nextConfig,
stateDir,
env: params.env,
authStoreByPath: /* @__PURE__ */ new Map(),
authStoreTargetByPath: /* @__PURE__ */ new Map(),
changedFiles
});
if (targetMutations.configChanged) changedFiles.add(configPath);
const authStoreByPath = scrubAuthStoresForProviderTargets({
nextConfig,
stateDir,
env: params.env,
providerTargets: targetMutations.providerTargets,
scrubbedValues: targetMutations.scrubbedValues,
authStoreByPath: targetMutations.authStoreByPath,
authStoreTargetByPath: targetMutations.authStoreTargetByPath,
changedFiles,
warnings,
enabled: options.scrubAuthProfilesForProviderTargets
});
const envRawByPath = scrubEnvFiles({
configPath,
stateDir,
scrubbedValues: targetMutations.scrubbedValues,
changedFiles,
enabled: options.scrubEnv
});
const checkFullRuntime = params.write ? changedFiles.size > 0 : params.allowExecInDryRun;
const validation = await validateProjectedSecretsState({
env: params.env,
nextConfig,
resolvedTargets: targetMutations.resolvedTargets,
authStoreByPath,
write: params.write,
allowExecInDryRun: params.allowExecInDryRun,
checkFullRuntime
});
return {
nextConfig,
authStoreEnv,
configSnapshot: snapshot,
configPath,
configWriteOptions: writeOptions,
authStoreByPath,
authStoreTargetByPath: targetMutations.authStoreTargetByPath,
envRawByPath,
changedFiles,
warnings,
refsChecked: validation.refsChecked,
skippedExecRefs: validation.skippedExecRefs,
resolvabilityComplete: validation.resolvabilityComplete
};
}
function applyConfigTargetMutations(params) {
const resolvedTargets = params.planTargets.map((target) => ({
target,
resolved: resolveTarget(target)
}));
const scrubbedValues = /* @__PURE__ */ new Set();
const providerTargets = /* @__PURE__ */ new Set();
let configChanged = false;
for (const { target, resolved } of resolvedTargets) {
if (resolved.entry.configFile === "auth-profile-store") {
if (applyAuthProfileTargetMutation({
target,
resolved,
nextConfig: params.nextConfig,
stateDir: params.stateDir,
env: params.env,
authStoreByPath: params.authStoreByPath,
authStoreTargetByPath: params.authStoreTargetByPath,
scrubbedValues
})) {
const agentId = (target.agentId ?? "").trim();
if (!agentId) throw new Error(`Missing required agentId for auth-profiles target ${target.path}.`);
params.changedFiles.add(resolveAuthStoreTargetForAgent({
nextConfig: params.nextConfig,
stateDir: params.stateDir,
env: params.env,
agentId
}).path);
}
continue;
}
const targetPathSegments = resolved.pathSegments;
if (resolved.entry.secretShape === "sibling_ref") {
const previous = getPath(params.nextConfig, targetPathSegments);
if (isNonEmptyString(previous)) scrubbedValues.add(previous.trim());
const refPathTokens = resolved.refPathTokens;
if (!refPathTokens) throw new Error(`Missing sibling ref path for target ${target.type}.`);
const wroteRef = setPathCreateStrict(params.nextConfig, refPathTokens, target.ref);
const deletedLegacy = deletePathStrict(params.nextConfig, targetPathSegments);
if (wroteRef || deletedLegacy) configChanged = true;
continue;
}
const previous = getPath(params.nextConfig, targetPathSegments);
if (isNonEmptyString(previous)) scrubbedValues.add(previous.trim());
if (setPathCreateStrict(params.nextConfig, resolved.pathTokens, target.ref)) configChanged = true;
if (resolved.entry.trackProviderShadowing && resolved.providerId) providerTargets.add(normalizeProviderId(resolved.providerId));
}
return {
resolvedTargets,
scrubbedValues,
providerTargets,
configChanged,
authStoreByPath: params.authStoreByPath,
authStoreTargetByPath: params.authStoreTargetByPath
};
}
function scrubAuthStoresForProviderTargets(params) {
if (!params.enabled || params.providerTargets.size === 0) return params.authStoreByPath;
for (const target of listAuthProfileStoreTargets(params.nextConfig, params.stateDir, params.env)) {
const authStorePath = target.path;
const existing = params.authStoreByPath.get(authStorePath);
if (!existing && !fs.existsSync(authStorePath)) continue;
const parsed = existing ?? (target.kind === "shared" ? loadPersistedSharedAuthProfileStore(target.env) : loadPersistedAuthProfileStore(target.agentDir));
if (!parsed || !isRecord(parsed.profiles)) continue;
const nextStore = structuredClone(parsed);
const profiles = nextStore.profiles;
if (!isRecord(profiles)) continue;
let mutated = false;
for (const profile of iterateAuthProfileCredentials(profiles)) {
const provider = normalizeProviderId(profile.provider);
if (!params.providerTargets.has(provider)) continue;
if (profile.kind === "api_key" || profile.kind === "token") {
if (isNonEmptyString(profile.value)) params.scrubbedValues.add(profile.value.trim());
if (profile.valueField in profile.profile) {
delete profile.profile[profile.valueField];
mutated = true;
}
if (profile.refField in profile.profile && coerceSecretRef(profile.refValue, params.nextConfig.secrets?.defaults) === null) {
delete profile.profile[profile.refField];
mutated = true;
}
continue;
}
if (profile.kind === "oauth" && (profile.hasAccess || profile.hasRefresh)) params.warnings.push(`Provider "${provider}" has OAuth credentials in ${authStorePath}; those still take precedence and are out of scope for static SecretRef migration.`);
}
if (mutated) {
params.authStoreByPath.set(authStorePath, nextStore);
params.authStoreTargetByPath.set(authStorePath, target);
params.changedFiles.add(authStorePath);
}
}
return params.authStoreByPath;
}
function ensureMutableAuthStore(store) {
const next = store ? structuredClone(store) : {};
const profiles = isRecord(next.profiles) ? next.profiles : {};
if (typeof next.version !== "number" || !Number.isFinite(next.version)) next.version = 1;
return {
...next,
profiles
};
}
function resolveAuthStoreForTarget(params) {
const agentId = (params.target.agentId ?? "").trim();
if (!agentId) throw new Error(`Missing required agentId for auth-profiles target ${params.target.path}.`);
const authStoreTarget = resolveAuthStoreTargetForAgent({
nextConfig: params.nextConfig,
stateDir: params.stateDir,
env: params.env,
agentId
});
const authStorePath = authStoreTarget.path;
const loaded = params.authStoreByPath.get(authStorePath) ?? loadPersistedAuthProfileStore(authStoreTarget.agentDir);
const store = ensureMutableAuthStore(isRecord(loaded) ? loaded : void 0);
params.authStoreByPath.set(authStorePath, store);
params.authStoreTargetByPath.set(authStorePath, authStoreTarget);
return {
path: authStorePath,
store
};
}
function resolveAuthStoreTargetForAgent(params) {
const scopedEnv = {
...params.env,
OPENCLAW_STATE_DIR: params.stateDir,
OPENCLAW_AGENT_DIR: void 0
};
const agentDir = resolveAgentDir(params.nextConfig, params.agentId, scopedEnv);
return {
kind: "agent",
agentDir,
path: resolveAuthProfileDatabasePath(agentDir)
};
}
function listAuthProfileStoreTargets(config, stateDir, env) {
return listAuthProfileStoreTargets$1(config, stateDir, env);
}
function ensureAuthProfileContainer(params) {
let changed = false;
const profilePathSegments = params.resolved.pathSegments.slice(0, 2);
const profileId = profilePathSegments[1];
if (!profileId) throw new Error(`Invalid auth profile target path: ${params.target.path}`);
const current = getPath(params.store, profilePathSegments);
const expectedType = params.resolved.entry.authProfileType;
if (isRecord(current)) {
if (expectedType && typeof current.type === "string" && current.type !== expectedType) throw new Error(`Auth profile "${profileId}" type mismatch for ${params.target.path}: expected "${expectedType}", got "${current.type}".`);
if (!isNonEmptyString(current.provider) && isNonEmptyString(params.target.authProfileProvider)) {
const wroteProvider = setPathCreateStrict(params.store, [...profilePathSegments, "provider"], params.target.authProfileProvider);
changed = changed || wroteProvider;
}
return changed;
}
if (!expectedType) throw new Error(`Auth profile target ${params.target.path} is missing auth profile type metadata.`);
const provider = (params.target.authProfileProvider ?? "").trim();
if (!provider) throw new Error(`Cannot create auth profile "${profileId}" for ${params.target.path} without authProfileProvider.`);
const wroteProfile = setPathCreateStrict(params.store, profilePathSegments, {
type: expectedType,
provider
});
changed = changed || wroteProfile;
return changed;
}
function applyAuthProfileTargetMutation(params) {
if (params.resolved.entry.configFile !== "auth-profile-store") return false;
const { store } = resolveAuthStoreForTarget({
target: params.target,
nextConfig: params.nextConfig,
stateDir: params.stateDir,
env: params.env,
authStoreByPath: params.authStoreByPath,
authStoreTargetByPath: params.authStoreTargetByPath
});
let changed = ensureAuthProfileContainer({
target: params.target,
resolved: params.resolved,
store
});
const targetPathSegments = params.resolved.pathSegments;
if (params.resolved.entry.secretShape === "sibling_ref") {
const previous = getPath(store, targetPathSegments);
if (isNonEmptyString(previous)) params.scrubbedValues.add(previous.trim());
const refPathTokens = params.resolved.refPathTokens;
if (!refPathTokens) throw new Error(`Missing sibling ref path for auth-profiles target ${params.target.path}.`);
const wroteRef = setPathCreateStrict(store, refPathTokens, params.target.ref);
const deletedPlaintext = deletePathStrict(store, targetPathSegments);
changed = changed || wroteRef || deletedPlaintext;
return changed;
}
const previous = getPath(store, targetPathSegments);
if (isNonEmptyString(previous)) params.scrubbedValues.add(previous.trim());
const wroteRef = setPathCreateStrict(store, params.resolved.pathTokens, params.target.ref);
changed = changed || wroteRef;
return changed;
}
function scrubEnvFiles(params) {
const envRawByPath = /* @__PURE__ */ new Map();
if (!params.enabled || params.scrubbedValues.size === 0) return envRawByPath;
const knownSecretEnvVars = new Set(listKnownSecretEnvVarNames());
for (const envPath of listSecretsDotEnvPaths({
configPath: params.configPath,
stateDir: params.stateDir
})) {
if (!fs.existsSync(envPath)) continue;
const current = fs.readFileSync(envPath, "utf8");
const scrubbed = scrubEnvRaw(current, params.scrubbedValues, knownSecretEnvVars);
if (scrubbed.removed > 0 && scrubbed.nextRaw !== current) {
envRawByPath.set(envPath, scrubbed.nextRaw);
params.changedFiles.add(envPath);
}
}
return envRawByPath;
}
async function validateProjectedSecretsState(params) {
const cache = {};
let refsChecked = 0;
let skippedExecRefs = 0;
for (const { target, resolved: resolvedTarget } of params.resolvedTargets) {
if (!params.write && target.ref.source === "exec" && !params.allowExecInDryRun) {
skippedExecRefs += 1;
const staticError = getSkippedExecRefStaticError({
ref: target.ref,
config: params.nextConfig
});
if (staticError) throw new Error(staticError);
continue;
}
const resolved = await resolveSecretRefValue(target.ref, {
config: params.nextConfig,
env: params.env,
cache
});
refsChecked += 1;
assertExpectedResolvedSecretValue({
value: resolved,
expected: resolvedTarget.entry.expectedResolvedValue,
errorMessage: resolvedTarget.entry.expectedResolvedValue === "string" ? `Ref ${target.ref.source}:${target.ref.provider}:${target.ref.id} is not a non-empty string.` : `Ref ${target.ref.source}:${target.ref.provider}:${target.ref.id} is not string/object.`
});
}
const authStoreLookup = /* @__PURE__ */ new Map();
for (const [authStorePath, store] of params.authStoreByPath.entries()) authStoreLookup.set(resolveUserPath(authStorePath, params.env), store);
if (params.checkFullRuntime) await prepareSecretsRuntimeSnapshot({
config: params.nextConfig,
env: params.env,
includeAuthStoreRefs: params.write || params.authStoreByPath.size > 0,
loadAuthStore: (agentDir) => {
const storePath = resolveUserPath(agentDir ? resolveAuthProfileDatabasePath(agentDir) : resolveSharedAuthStorePath(params.env), params.env);
const override = authStoreLookup.get(storePath);
if (override) return coercePersistedAuthProfileStore(structuredClone(override)) ?? {
version: 1,
profiles: {}
};
return loadAuthProfileStoreForSecretsRuntime(agentDir);
}
});
return {
refsChecked,
skippedExecRefs,
resolvabilityComplete: params.write || params.allowExecInDryRun || skippedExecRefs === 0
};
}
function captureFileSnapshot(pathname) {
if (!fs.existsSync(pathname)) return {
existed: false,
content: "",
mode: 384
};
const stat = fs.statSync(pathname);
return {
existed: true,
content: fs.readFileSync(pathname, "utf8"),
mode: stat.mode & 511
};
}
function restoreFileSnapshot(pathname, snapshot) {
if (!snapshot.existed) {
if (fs.existsSync(pathname)) fs.rmSync(pathname, { force: true });
return;
}
writeTextFileAtomic(pathname, snapshot.content, snapshot.mode || 384);
}
/** Applies or dry-runs a validated secrets plan across config, auth stores, and scrub targets. */
/** Applies a normalized secrets plan, or reports file/auth-store changes in dry-run mode. */
async function runSecretsApply(params) {
const env = params.env ?? process.env;
const write = params.write === true;
const allowExec = Boolean(params.allowExec);
if (write && planContainsExecReferences(params.plan) && !allowExec) throw new Error("Plan contains exec SecretRefs/providers. Re-run with --allow-exec.");
const allowExecInDryRun = write ? true : allowExec;
const projected = await projectPlanState({
plan: params.plan,
env,
write,
allowExecInDryRun
});
const changedFiles = [...projected.changedFiles].toSorted();
if (!write) return {
mode: "dry-run",
changed: changedFiles.length > 0,
changedFiles,
checks: {
resolvability: true,
resolvabilityComplete: projected.resolvabilityComplete
},
refsChecked: projected.refsChecked,
skippedExecRefs: projected.skippedExecRefs,
warningCount: projected.warnings.length,
warnings: projected.warnings
};
if (changedFiles.length === 0) return {
mode: "write",
changed: false,
changedFiles: [],
checks: {
resolvability: true,
resolvabilityComplete: true
},
refsChecked: projected.refsChecked,
skippedExecRefs: 0,
warningCount: projected.warnings.length,
warnings: projected.warnings
};
const io = createSecretsConfigIO({ env });
const snapshots = /* @__PURE__ */ new Map();
const authStoreSnapshots = /* @__PURE__ */ new Map();
const capture = (pathname) => {
if (!snapshots.has(pathname)) snapshots.set(pathname, captureFileSnapshot(pathname));
};
const captureAuthStore = (pathname, target) => {
if (!authStoreSnapshots.has(pathname)) authStoreSnapshots.set(pathname, {
target,
persistence: captureAuthProfileStorePersistenceSnapshot(target.kind === "agent" ? target.agentDir : void 0, { env: target.kind === "shared" ? target.env : projected.authStoreEnv })
});
};
capture(projected.configPath);
const writes = [];
for (const [pathname, raw] of projected.envRawByPath.entries()) {
capture(pathname);
writes.push({
path: pathname,
content: raw,
mode: 384
});
}
for (const [pathname, target] of projected.authStoreTargetByPath.entries()) captureAuthStore(pathname, target);
try {
await replaceConfigFile({
nextConfig: projected.nextConfig,
snapshot: projected.configSnapshot,
writeOptions: projected.configWriteOptions,
io,
afterWrite: { mode: "auto" }
});
for (const writeLocal of writes) writeTextFileAtomic(writeLocal.path, writeLocal.content, writeLocal.mode);
for (const [pathname, value] of projected.authStoreByPath.entries()) {
const target = projected.authStoreTargetByPath.get(pathname);
const store = coercePersistedAuthProfileStore(value);
if (target && store) {
const snapshot = authStoreSnapshots.get(pathname);
if (!snapshot) throw new Error(`missing captured auth profile store for ${pathname}`);
const committed = saveAuthProfileStoreIfPersistenceSnapshotMatches({
store,
snapshot: snapshot.persistence,
agentDir: target.kind === "agent" ? target.agentDir : void 0,
...target.kind === "shared" ? { stateDir: target.stateDir } : {}
});
snapshot.owned = committed.owned;
if (!committed.publishRuntimeSnapshots()) throw new Error(`auth profile runtime publication failed for ${pathname}`);
}
}
} catch (err) {
for (const [pathname, snapshot] of snapshots.entries()) try {
restoreFileSnapshot(pathname, snapshot);
} catch {}
for (const snapshot of authStoreSnapshots.values()) {
if (!snapshot.owned) continue;
try {
restoreAuthProfileStorePersistenceSnapshot(snapshot.persistence, snapshot.owned, snapshot.target.kind === "agent" ? snapshot.target.agentDir : void 0, snapshot.target.kind === "shared" ? { stateDir: snapshot.target.stateDir } : {});
} catch {}
}
throw new Error(`Secrets apply failed: ${String(err)}`, { cause: err });
}
return {
mode: "write",
changed: changedFiles.length > 0,
changedFiles,
checks: {
resolvability: true,
resolvabilityComplete: true
},
refsChecked: projected.refsChecked,
skippedExecRefs: 0,
warningCount: projected.warnings.length,
warnings: projected.warnings
};
}
const testing = { async projectConfigForTest(params) {
return (await projectPlanState({
plan: params.plan,
env: params.env ?? process.env,
write: false,
allowExecInDryRun: false
})).nextConfig;
} };
//#endregion
export { testing as n, runSecretsApply as t };