openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
198 lines (197 loc) • 7.65 kB
JavaScript
import { o as isRecord } from "./record-coerce-DHZ4bFlT.js";
import { i as formatErrorMessage } from "./errors-BXgSefBE.js";
import { c as isRecord$1, p as resolveUserPath } from "./utils-CCC-BEJH.js";
import "./agent-scope-MrLta7Pq.js";
import { a as resolveAgentDir, n as listAgentIds } from "./agent-scope-config-CgCYpZfK.js";
import { n as isNonEmptyString, o as parseEnvValue } from "./shared-CuqTS6Vs.js";
import { a as listAuthProfileSecretTargetEntries } from "./target-registry-0k0oK6Ia.js";
import { r as createConfigIO } from "./io-Gi7-pyU-.js";
import "./config-C9RxTsn1.js";
import "./sqlite-nSLfAcoh.js";
import fs from "node:fs";
import path from "node:path";
//#region src/secrets/auth-profiles-scan.ts
/** Scans auth-profile stores for plaintext credentials, SecretRefs, and OAuth tokens. */
function getAuthProfileFieldName(pathPattern) {
const segments = pathPattern.split(".").filter(Boolean);
return segments[segments.length - 1] ?? "";
}
const AUTH_PROFILE_FIELD_SPEC_BY_TYPE = (() => {
const defaults = {
api_key: {
valueField: "key",
refField: "keyRef"
},
token: {
valueField: "token",
refField: "tokenRef"
}
};
for (const target of listAuthProfileSecretTargetEntries()) {
if (!target.authProfileType) continue;
defaults[target.authProfileType] = {
valueField: getAuthProfileFieldName(target.pathPattern),
refField: target.refPathPattern !== void 0 ? getAuthProfileFieldName(target.refPathPattern) : defaults[target.authProfileType].refField
};
}
return defaults;
})();
/** Returns the value/ref field names for one auth-profile credential type. */
function getAuthProfileFieldSpec(type) {
return AUTH_PROFILE_FIELD_SPEC_BY_TYPE[type];
}
function toSecretCredentialVisit(params) {
const spec = getAuthProfileFieldSpec(params.kind);
return {
kind: params.kind,
profileId: params.profileId,
provider: params.provider,
profile: params.profile,
valueField: spec.valueField,
refField: spec.refField,
value: params.profile[spec.valueField],
refValue: params.profile[spec.refField]
};
}
/** Iterates credential-bearing auth profiles with normalized field metadata for audit/apply. */
function* iterateAuthProfileCredentials(profiles) {
for (const [profileId, value] of Object.entries(profiles)) {
if (!isRecord$1(value) || !isNonEmptyString(value.provider)) continue;
const provider = value.provider;
if (value.type === "api_key" || value.type === "token") {
yield toSecretCredentialVisit({
kind: value.type,
profileId,
provider,
profile: value
});
continue;
}
if (value.type === "oauth") yield {
kind: "oauth",
profileId,
provider,
profile: value,
hasAccess: isNonEmptyString(value.access),
hasRefresh: isNonEmptyString(value.refresh)
};
}
}
//#endregion
//#region src/secrets/config-io.ts
/** Config IO adapter used by secrets apply/configure flows. */
const silentConfigIoLogger = {
error: () => {},
warn: () => {}
};
/**
* Creates config I/O for secrets commands with config-loader logging suppressed.
*/
function createSecretsConfigIO(params) {
return createConfigIO({
env: params.env,
logger: silentConfigIoLogger
});
}
//#endregion
//#region src/secrets/auth-store-paths.ts
/** Discovers auth-profile store paths that may contain secret refs. */
/**
* Lists deduplicated auth-profile store agent dirs that may contain SecretRefs.
* Covers implicit main, discovered state-dir agents, and config-declared agent dirs.
*/
function listAuthProfileStoreAgentDirs$1(config, stateDir) {
const paths = /* @__PURE__ */ new Set();
paths.add(path.join(resolveUserPath(stateDir), "agents", "main", "agent"));
const agentsRoot = path.join(resolveUserPath(stateDir), "agents");
if (fs.existsSync(agentsRoot)) for (const entry of fs.readdirSync(agentsRoot, { withFileTypes: true })) {
if (!entry.isDirectory()) continue;
paths.add(path.join(agentsRoot, entry.name, "agent"));
}
for (const agentId of listAgentIds(config)) {
if (agentId === "main") {
paths.add(path.join(resolveUserPath(stateDir), "agents", "main", "agent"));
continue;
}
const agentDir = resolveAgentDir(config, agentId);
paths.add(resolveUserPath(agentDir));
}
return [...paths];
}
//#endregion
//#region src/secrets/storage-scan.ts
/** Filesystem discovery and bounded JSON readers for local secret storage audits. */
/** Parses one .env assignment value using the shared shell-ish env parser. */
function parseEnvAssignmentValue(raw) {
return parseEnvValue(raw);
}
/** Lists agent directories that own canonical auth-profile stores. */
function listAuthProfileStoreAgentDirs(config, stateDir) {
return listAuthProfileStoreAgentDirs$1(config, stateDir);
}
/** Lists legacy per-agent auth.json stores that can contain static credentials. */
function listLegacyAuthJsonPaths(stateDir) {
const out = [];
const agentsRoot = path.join(resolveUserPath(stateDir), "agents");
if (!fs.existsSync(agentsRoot)) return out;
for (const entry of fs.readdirSync(agentsRoot, { withFileTypes: true })) {
if (!entry.isDirectory()) continue;
const candidate = path.join(agentsRoot, entry.name, "agent", "auth.json");
if (fs.existsSync(candidate)) out.push(candidate);
}
return out;
}
function resolveActiveAgentDir(stateDir, env = process.env) {
const override = env.OPENCLAW_AGENT_DIR?.trim() || env.PI_CODING_AGENT_DIR?.trim();
if (override) return resolveUserPath(override, env);
return path.join(resolveUserPath(stateDir), "agents", "main", "agent");
}
/**
* Lists deduplicated models.json paths that may contain materialized provider credentials.
* Includes active env override, implicit main agent, discovered state dirs, and configured agents.
*/
function listAgentModelsJsonPaths(config, stateDir, env = process.env) {
const resolvedStateDir = resolveUserPath(stateDir);
const paths = /* @__PURE__ */ new Set();
paths.add(path.join(resolvedStateDir, "agents", "main", "agent", "models.json"));
paths.add(path.join(resolveActiveAgentDir(stateDir, env), "models.json"));
const agentsRoot = path.join(resolvedStateDir, "agents");
if (fs.existsSync(agentsRoot)) for (const entry of fs.readdirSync(agentsRoot, { withFileTypes: true })) {
if (!entry.isDirectory()) continue;
paths.add(path.join(agentsRoot, entry.name, "agent", "models.json"));
}
for (const agentId of listAgentIds(config)) {
if (agentId === "main") {
paths.add(path.join(resolvedStateDir, "agents", "main", "agent", "models.json"));
continue;
}
const agentDir = resolveAgentDir(config, agentId);
paths.add(path.join(resolveUserPath(agentDir), "models.json"));
}
return [...paths];
}
function readJsonObjectIfExists(filePath, options = {}) {
if (!fs.existsSync(filePath)) return { value: null };
try {
const stats = fs.statSync(filePath);
if (options.requireRegularFile && !stats.isFile()) return {
value: null,
error: `Refusing to read non-regular file: ${filePath}`
};
if (typeof options.maxBytes === "number" && Number.isFinite(options.maxBytes) && options.maxBytes >= 0 && stats.size > options.maxBytes) return {
value: null,
error: `Refusing to read oversized JSON (${stats.size} bytes): ${filePath}`
};
const raw = fs.readFileSync(filePath, "utf8");
const parsed = JSON.parse(raw);
if (!isRecord(parsed)) return { value: null };
return { value: parsed };
} catch (err) {
return {
value: null,
error: formatErrorMessage(err)
};
}
}
//#endregion
export { readJsonObjectIfExists as a, parseEnvAssignmentValue as i, listAuthProfileStoreAgentDirs as n, createSecretsConfigIO as o, listLegacyAuthJsonPaths as r, iterateAuthProfileCredentials as s, listAgentModelsJsonPaths as t };