/** * Unified approval gate — deferral predicates. The byte-exact vs loose glob * split: LOOSE (case-insensitive, trimmed) identifies dialogs for the gate; * BYTE-EXACT governs deferral, so a command is only passed through when the * host dialog is GUARANTEED to fire. Split out of the former monolithic * envprotect.ts; behavior unchanged. */ import type { EnvProtectMode } from "./patterns.js"; /** True when `text` matches ANY of the given ask globs (LOOSE, host-style). */ export declare function commandMatchesAnyAskPattern(text: unknown, patterns: readonly string[]): boolean; /** * True when a built-in-bash command is an environment read in a form the * host is configured to ASK about (and therefore the dialog governs it). * The hook then lets it proceed WITHOUT throwing, so a human approval is * meaningful. Kept deliberately narrower than classifyBashCommand: every * form it accepts is a head-anchored single statement that matches one of * R6_ENV_BASH_ASK BYTE-EXACTLY (so the dialog WILL fire under any host * grammar at least as greedy as ours — no case/trim leniency, see * commandMatchesAnyAskPatternExact), and every hazard that breaks that * alignment (compound statements, substitutions, `${…}`, `$ALLCAPS`, * assignment prefixes, `time`/subshell/escaped heads, user extra-deny, path * heads like `/usr/bin/env`, `cmd /c …`, and the PowerShell env-drive forms * with intervening flags or quotes that the globs miss) returns false → the * classifier keeps hard-throwing. tm_* channels are hard-blocked separately * (the dialog never opens for them). */ export declare function isAskGatedEnvCommand(command: string, mode: EnvProtectMode, extra?: RegExp[]): boolean; /** * Coarse category for a host permission-event payload, used ONLY to gate the * timer, to register the deferral session, and to tag the audit (never the * pattern text itself). Returns null for anything that is not one of OUR * injected bash asks, so the gate leaves other tools' dialogs (edit, * webfetch, host-native rules) alone. * * Real 1.18.29 `permission.asked` props carry NO `type` field: the tool name * rides in `permission` and the concrete command segments in `patterns[]` * (plus `metadata.command` with the raw line). Inference order, defensive * across builds: * 1. explicit tool field (`type` || `permission`) — non-bash is a hard no; * 2. absent tool field → bash evidence = `metadata.command` present, or a * candidate that is COMMAND-SHAPED (contains whitespace: our command * globs all need an embedded space except bare keys, and bare-key * patterns like a file named `set` cannot prove bash without the * command metadata beside them). * Matching here is the LOOSE glob (case-insensitive): over-matching can only * arm a timer for a dialog the host already opened, never run a command — * the deferral side keeps the byte-exact matcher (isAskGatedEnvCommand). */ export declare function categorizePermission(props: { type?: string; permission?: string; pattern?: string | string[]; patterns?: string | string[]; title?: string; metadata?: Record; } | null | undefined): "env" | "danger" | null; //# sourceMappingURL=gate-predicates.d.ts.map