openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
216 lines (215 loc) • 8.21 kB
JavaScript
import { c as normalizeOptionalLowercaseString } from "./string-coerce-CIXf7egm.js";
//#region src/infra/exec-approvals-core.ts
const EXEC_TARGET_VALUES = [
"auto",
"sandbox",
"gateway",
"node"
];
function normalizeExecHost(value) {
const normalized = normalizeOptionalLowercaseString(value);
if (normalized === "sandbox" || normalized === "gateway" || normalized === "node") return normalized;
return null;
}
function normalizeExecTarget(value) {
const normalized = normalizeOptionalLowercaseString(value);
if (normalized === "auto") return normalized;
return normalizeExecHost(normalized);
}
function requireValidExecTarget(value) {
if (value == null) return null;
if (typeof value !== "string") throw new Error(`Invalid exec host value type ${typeof value}. Allowed values: ${EXEC_TARGET_VALUES.join(", ")}.`);
const normalized = normalizeOptionalLowercaseString(value);
if (!normalized) return null;
const target = normalizeExecTarget(normalized);
if (target) return target;
throw new Error(`Invalid exec host "${value}". Allowed values: ${EXEC_TARGET_VALUES.join(", ")}.`);
}
function normalizeExecSecurity(value) {
const normalized = normalizeOptionalLowercaseString(value);
if (normalized === "deny" || normalized === "allowlist" || normalized === "full") return normalized;
return null;
}
function normalizeExecAsk(value) {
const normalized = normalizeOptionalLowercaseString(value);
if (normalized === "off" || normalized === "on-miss" || normalized === "always") return normalized;
return null;
}
function normalizeExecMode(value) {
const normalized = normalizeOptionalLowercaseString(value);
if (normalized === "deny" || normalized === "allowlist" || normalized === "ask" || normalized === "auto" || normalized === "full") return normalized;
return null;
}
function resolveExecModeFromPolicy(params) {
if (params.security === "deny") return "deny";
if (params.security === "allowlist" && params.ask === "off") return "allowlist";
if (params.security === "full" && params.ask !== "always") return "full";
return "ask";
}
function resolveExecPolicyForMode(mode) {
switch (mode) {
case "deny": return {
security: "deny",
ask: "off",
autoReview: false
};
case "allowlist": return {
security: "allowlist",
ask: "off",
autoReview: false
};
case "ask": return {
security: "allowlist",
ask: "on-miss",
autoReview: false
};
case "auto": return {
security: "allowlist",
ask: "on-miss",
autoReview: true
};
case "full": return {
security: "full",
ask: "off",
autoReview: false
};
}
throw new Error(`Unsupported exec mode: ${String(mode)}`);
}
function resolveExecModePolicy(params) {
if (!params.mode) return {
mode: resolveExecModeFromPolicy({
security: params.security,
ask: params.ask
}),
security: params.security,
ask: params.ask,
autoReview: false
};
return {
mode: params.mode,
...resolveExecPolicyForMode(params.mode)
};
}
const DEFAULT_EXEC_APPROVAL_TIMEOUT_MS = 18e5;
//#endregion
//#region src/infra/exec-approvals-policy.ts
function requiresExecApproval(params) {
if (params.ask === "always") return true;
if (params.durableApprovalSatisfied === true) return false;
return params.ask === "on-miss" && params.security === "allowlist" && (!params.analysisOk || !params.allowlistSatisfied);
}
function normalizeCommandName(value) {
return (value ?? "").split(/[\\/]/).pop()?.toLowerCase() ?? "";
}
function textMentionsSecurityAuditSuppressions(value) {
const normalized = value.toLowerCase();
return normalized.includes("security.audit.suppressions") || /["']?security["']?[\s\S]{0,200}["']?audit["']?[\s\S]{0,200}["']?suppressions["']?/.test(normalized);
}
function isReadOnlySecurityAuditSuppressionInspection(argv) {
let offset = normalizeCommandName(argv[0]) === "pnpm" && argv[1] === "openclaw" ? 1 : 0;
if (normalizeCommandName(argv[offset]) !== "openclaw") return false;
offset += 1;
while (offset < argv.length) {
const arg = argv[offset];
if (["--dev", "--no-color"].includes(arg ?? "")) {
offset += 1;
continue;
}
if ([
"--profile",
"--container",
"--log-level"
].includes(arg ?? "")) {
offset += 2;
continue;
}
if (arg?.startsWith("--profile=") || arg?.startsWith("--container=") || arg?.startsWith("--log-level=")) {
offset += 1;
continue;
}
break;
}
return argv[offset] === "config" && [
"get",
"schema",
"validate"
].includes(argv[offset + 1] ?? "");
}
function removeParsedSegmentText(command, segments) {
let remaining = command;
for (const segment of segments) {
const raw = (segment.raw ?? segment.argv?.join(" "))?.trim();
if (!raw) continue;
remaining = remaining.replace(raw, " ");
}
return remaining;
}
function commandRequiresSecurityAuditSuppressionApproval(params) {
let sawSegmentMention = false;
for (const segment of params.segments) {
if (!textMentionsSecurityAuditSuppressions(`${segment.raw ?? ""} ${segment.argv.join(" ")}`)) continue;
sawSegmentMention = true;
if (!isReadOnlySecurityAuditSuppressionInspection(segment.argv)) return true;
}
if (sawSegmentMention) {
if (textMentionsSecurityAuditSuppressions(removeParsedSegmentText(params.command, params.segments))) return true;
return false;
}
return textMentionsSecurityAuditSuppressions(params.command);
}
function minSecurity(a, b) {
const order = {
deny: 0,
allowlist: 1,
full: 2
};
return order[a] <= order[b] ? a : b;
}
function maxAsk(a, b) {
const order = {
off: 0,
"on-miss": 1,
always: 2
};
return order[a] >= order[b] ? a : b;
}
const DEFAULT_EXEC_APPROVAL_DECISIONS = [
"allow-once",
"allow-always",
"deny"
];
const OPTIONAL_EXEC_APPROVAL_DECISIONS = ["allow-always"];
const OPTIONAL_EXEC_APPROVAL_DECISION_SET = new Set(OPTIONAL_EXEC_APPROVAL_DECISIONS);
function isOptionalExecApprovalDecision(decision) {
return OPTIONAL_EXEC_APPROVAL_DECISION_SET.has(decision);
}
function collectExecApprovalUnavailableDecisionSet(decisions) {
const unavailable = /* @__PURE__ */ new Set();
if (!Array.isArray(decisions)) return unavailable;
for (const decision of decisions) if (isOptionalExecApprovalDecision(decision)) unavailable.add(decision);
return unavailable;
}
function normalizeExecApprovalUnavailableDecisions(decisions) {
const unavailable = collectExecApprovalUnavailableDecisionSet(decisions);
return OPTIONAL_EXEC_APPROVAL_DECISIONS.filter((decision) => unavailable.has(decision));
}
function resolveExecApprovalAllowedDecisions(params) {
if (normalizeExecAsk(params?.ask) === "always" || params?.allowAlwaysPersistence?.kind === "one-shot") return ["allow-once", "deny"];
return DEFAULT_EXEC_APPROVAL_DECISIONS;
}
function resolveExecApprovalUnavailableDecisions(params) {
const allowed = new Set(resolveExecApprovalAllowedDecisions(params));
return OPTIONAL_EXEC_APPROVAL_DECISIONS.filter((decision) => !allowed.has(decision));
}
function resolveExecApprovalRequestAllowedDecisions(params) {
const policyDecisions = resolveExecApprovalAllowedDecisions({ ask: params?.ask });
const unavailableDecisions = collectExecApprovalUnavailableDecisionSet(params?.unavailableDecisions);
if (unavailableDecisions.size === 0) return policyDecisions;
return policyDecisions.filter((decision) => !isOptionalExecApprovalDecision(decision) || !unavailableDecisions.has(decision));
}
function isExecApprovalDecisionAllowed(params) {
return resolveExecApprovalAllowedDecisions({ ask: params.ask }).includes(params.decision);
}
//#endregion
export { resolveExecPolicyForMode as S, normalizeExecSecurity as _, maxAsk as a, resolveExecModeFromPolicy as b, requiresExecApproval as c, resolveExecApprovalUnavailableDecisions as d, DEFAULT_EXEC_APPROVAL_TIMEOUT_MS as f, normalizeExecMode as g, normalizeExecHost as h, isExecApprovalDecisionAllowed as i, resolveExecApprovalAllowedDecisions as l, normalizeExecAsk as m, OPTIONAL_EXEC_APPROVAL_DECISIONS as n, minSecurity as o, EXEC_TARGET_VALUES as p, commandRequiresSecurityAuditSuppressionApproval as r, normalizeExecApprovalUnavailableDecisions as s, DEFAULT_EXEC_APPROVAL_DECISIONS as t, resolveExecApprovalRequestAllowedDecisions as u, normalizeExecTarget as v, resolveExecModePolicy as x, requireValidExecTarget as y };