refactor(agents): share glob matcher

This commit is contained in:
Peter Steinberger
2026-02-14 13:34:10 +00:00
parent fdc3a6a809
commit 60a7625f2a
4 changed files with 92 additions and 155 deletions

View File

@@ -5,67 +5,31 @@ import type {
SandboxToolPolicySource,
} from "./types.js";
import { resolveAgentConfig } from "../agent-scope.js";
import { compileGlobPatterns, matchesAnyGlobPattern } from "../glob-pattern.js";
import { expandToolGroups } from "../tool-policy.js";
import { DEFAULT_TOOL_ALLOW, DEFAULT_TOOL_DENY } from "./constants.js";
type CompiledPattern =
| { kind: "all" }
| { kind: "exact"; value: string }
| { kind: "regex"; value: RegExp };
function compilePattern(pattern: string): CompiledPattern {
const normalized = pattern.trim().toLowerCase();
if (!normalized) {
return { kind: "exact", value: "" };
}
if (normalized === "*") {
return { kind: "all" };
}
if (!normalized.includes("*")) {
return { kind: "exact", value: normalized };
}
const escaped = normalized.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
return {
kind: "regex",
value: new RegExp(`^${escaped.replaceAll("\\*", ".*")}$`),
};
}
function compilePatterns(patterns?: string[]): CompiledPattern[] {
if (!Array.isArray(patterns)) {
return [];
}
return expandToolGroups(patterns)
.map(compilePattern)
.filter((pattern) => pattern.kind !== "exact" || pattern.value);
}
function matchesAny(name: string, patterns: CompiledPattern[]): boolean {
for (const pattern of patterns) {
if (pattern.kind === "all") {
return true;
}
if (pattern.kind === "exact" && name === pattern.value) {
return true;
}
if (pattern.kind === "regex" && pattern.value.test(name)) {
return true;
}
}
return false;
function normalizeGlob(value: string) {
return value.trim().toLowerCase();
}
export function isToolAllowed(policy: SandboxToolPolicy, name: string) {
const normalized = name.trim().toLowerCase();
const deny = compilePatterns(policy.deny);
if (matchesAny(normalized, deny)) {
const normalized = normalizeGlob(name);
const deny = compileGlobPatterns({
raw: expandToolGroups(policy.deny ?? []),
normalize: normalizeGlob,
});
if (matchesAnyGlobPattern(normalized, deny)) {
return false;
}
const allow = compilePatterns(policy.allow);
const allow = compileGlobPatterns({
raw: expandToolGroups(policy.allow ?? []),
normalize: normalizeGlob,
});
if (allow.length === 0) {
return true;
}
return matchesAny(normalized, allow);
return matchesAnyGlobPattern(normalized, allow);
}
export function resolveSandboxToolPolicyForAgent(