import type { Context } from '../core/context.js'; import type { InputReader } from '../types/input-reader.js'; import type { PermissionDecision, PermissionPolicy, PermissionTrace } from '../types/permission.js'; import type { Tool } from '../types/tool.js'; import { type TrustPolicyDiagnostic } from './permission-policy-schema.js'; export interface PermissionPolicyOptions { trustFile: string; yolo?: boolean | undefined; promptDelegate?: (tool: Tool, input: unknown, suggestedPattern: string) => Promise<'yes' | 'no' | 'always' | 'deny'>; inputReader?: InputReader | undefined; } export declare class DefaultPermissionPolicy implements PermissionPolicy { private policy; private loaded; private readonly trustFile; private yolo; /** * Session-scoped "soft deny" map. When the user presses 'n' (block once), * the tool+pattern is added here. If the LLM retries in the same session, * we return deny directly without asking again. * * Cleared on reload() since reload = fresh trust file snapshot. */ private sessionDenied; /** * Session-scoped one-shot "soft trust" map. When the user presses 'y', the * tool+pattern is added here so the immediate confirm re-run can proceed. * The entry is consumed on first use; future calls must ask again unless the * user chose persistent trust. * * Cleared on reload(). */ private sessionAllowed; /** * Interactive prompt delegate. When set, `evaluate()` calls it to get a * user decision synchronously (CLI REPL path). When cleared (TUI / WebUI), * `evaluate()` returns `confirm` so the caller can emit * `tool.confirm_needed` for the UI layer to handle. * * Mutable so the host can switch from CLI-prompt to event-driven * confirmation at runtime (e.g. when `--goal` forces TUI mode after * the agent was already constructed). */ private promptDelegate?; /** Pre-compiled wildcard patterns — rebuilt on reload for O(1) lookup. */ private wildcardEntries; /** * Evaluate-result cache. Keyed by `tool.name::subject` so repeated calls * with the same tool+input skip namespace matching, subject computation, * and pattern matching (matchAny). * * Cleared on any state change (reload, trust, deny, yolo toggle) because * the result depends on the full policy state. The write-tool smart-bypass * (step 7 in `evaluate()`) is not cached since `ctx.hasRead()` changes * dynamically within a session. * * P3 #17 (before-release.md): capped at 500 entries via LRU eviction. An * iteration that evaluates thousands of unique tool+subject combinations * (e.g. repeated `tool-help` or `bash` with different commands) can grow * the cache without bound. 500 is far more than any single iteration needs; * the LRU evicts the least-recently-used entries first. */ private _evalCache; private policyDiagnostics; private policyInvalid; constructor(opts: PermissionPolicyOptions); /** * Replace (or clear) the interactive prompt delegate at runtime. * Used by the CLI to switch from inline prompts (REPL) to event-driven * confirmation (TUI) when the run mode is determined after the policy * was constructed (e.g. `--goal` auto-flipping to TUI). */ setPromptDelegate(delegate: PermissionPolicyOptions['promptDelegate']): void; /** Toggle YOLO (auto-approve) mode at runtime. */ setYolo(enabled: boolean): void; /** Check whether YOLO mode is currently active. */ getYolo(): boolean; /** Read-only diagnostics for policy inspector/editor surfaces. */ getPolicyDiagnostics(): readonly TrustPolicyDiagnostic[]; reload(): Promise; private _logDeny; evaluate(tool: Tool, input: unknown, ctx: Context): Promise; private isSensitiveReadCall; trust(rule: { tool: string; pattern: string; }): Promise; /** Persist a deny rule — this tool+pattern pair is permanently blocked. */ deny(rule: { tool: string; pattern: string; }): Promise; /** Block this tool+pattern for the rest of this session (no trust file). */ denyOnce(rule: { tool: string; pattern: string; }): void; /** Auto-approve this tool+pattern once (no trust file). */ allowOnce(rule: { tool: string; pattern: string; }): void; /** * Side-effect-free permission evaluation trace. Mirrors `evaluate()` * step-by-step without prompting the user, writing to trust files, or * mutating session state. Returns the full ordered trace and winner. */ explain(tool: Tool, input: unknown, ctx: Context): Promise; private findNamespaceEntry; } /** * Auto-approving PermissionPolicy used for subagents. Subagents run * non-interactively under a director — they cannot answer permission * prompts, so a non-YOLO policy on the leader would silently hang the * delegated run on the first sensitive tool call. The user already * authorized the delegation when they invoked the leader; subagents * inherit that authorization automatically. * * Tool defaults of `permission: 'deny'` are still honored (this is a * subagent capability override, not a deny-bypass). * * 2026-06+: Primary decision is now based on declared `Tool.capabilities` * (capability allowlist / denylist model). The legacy name-based DENY set * is kept only for backward compatibility with tools that have not yet * declared capabilities. * * 2026-06-13+: Switched to allowlist-by-default. Only tools with explicitly * allowed capabilities are auto-approved. Everything else is denied. * Default allowed: fs.read, net.outbound (read-only, safe operations). */ export declare class AutoApprovePermissionPolicy implements PermissionPolicy { private readonly allowedCapabilities; constructor(allowedCapabilities?: readonly string[]); private static isMcpTool; evaluate(tool: Tool): Promise; trust(): Promise; deny(): Promise; denyOnce(): void; allowOnce(): void; explain(tool: Tool): Promise; reload(): Promise; } //# sourceMappingURL=permission-policy.d.ts.map