/** * Directory-scoped permission policy wrapper. * * Adds per-directory rules on top of an inner `PermissionPolicy`. The * inner policy is the existing `DefaultPermissionPolicy` (or any other * `PermissionPolicy` implementation); this wrapper consults * `.wrongstack/directory-rules.json` BEFORE delegating to the inner * policy. When a rule applies to the tool call's target path, the * wrapper's decision is final; otherwise it is a transparent * pass-through. * * Rule precedence (most-restrictive wins): * 1. `allowOnlyTools` — when declared, deny tools not in the list. * An empty list denies every tool. This is the strictest form: it * cannot be widened by an inner-policy allow. * 2. `denyTools` — deny if the tool name matches. This is also * strict: a directory-level ban overrides an inner-policy allow. * 3. `denyProviders` — deny if the active `ctx.provider.id` matches. * Provider bans are enforced at tool-call time (the tool itself * is not a provider, but the active session provider is). * 4. No match — pass through to the inner policy. * * "Most-specific match wins" among multiple matching rules: the rule * with the longest non-wildcard path component (i.e. the most literal * prefix) wins. Ties fall back to first-declared order. * * Path resolution: target paths are extracted from explicit filesystem * input keys (for example `path`, `file`, `directory`, `outputPath`, and * `worktreePath`) and resolved against `ctx.workingDir` (NOT `projectRoot`) * so a sub-agent that has changed directory still gets the right rule. * The resolved absolute path is then normalized to forward slashes. * * When none of those filesystem keys is present, the wrapper passes through; * URLs, shell command strings, and logical resource names are not interpreted * as filesystem paths by this directory-scoped policy. * * Session-level toggle: `ctx.meta['directoryRules'] = false` disables * the wrapper entirely (returns inner policy result unchanged) so * callers can flip the layer off without re-instantiating the policy. */ import type { Context } from '../core/context.js'; import type { DirectoryPolicy, DirectoryRule, PermissionDecision, PermissionPolicy, PermissionTrace } from '../types/permission.js'; import type { Tool } from '../types/tool.js'; export interface DirectoryPermissionPolicyOptions { /** * The directory policy to enforce. Pass an empty policy * (`{ schemaVersion: 1, rules: [] }`) to disable enforcement while * keeping the wrapper installed — useful as a default-allow stance. */ policy: DirectoryPolicy; } /** * Resolve the first tool-input target path against `ctx.workingDir` and * normalize it to forward slashes. Multi-target enforcement uses every path * internally; this helper retains its historical first-target public contract. */ export declare function resolveTargetPath(input: unknown, ctx: Context): string | undefined; /** * Find the most-specific rule that matches the target path. Returns * undefined when no rule matches. Specificity is computed as the * pattern's literal-character length with a small bonus for trailing * `/**`. Ties resolve to first-declared order. */ export declare function matchRule(policy: DirectoryPolicy, targetPath: string): DirectoryRule | undefined; export declare class DirectoryPermissionPolicy implements PermissionPolicy { private readonly inner; private policy; constructor(inner: PermissionPolicy, options: DirectoryPermissionPolicyOptions); /** Replace the in-memory directory policy. Does NOT reload from disk. */ setPolicy(policy: DirectoryPolicy): void; /** Read-only access to the current directory policy for diagnostics. */ getPolicy(): DirectoryPolicy; evaluate(tool: Tool, input: unknown, ctx: Context): Promise; getYolo(): boolean; setYolo(enabled: boolean): void; getYoloDestructive(): boolean; setYoloDestructive(enabled: boolean): void; getConfirmDestructive(): boolean; setConfirmDestructive(enabled: boolean): void; setPromptDelegate(delegate: ((tool: Tool, input: unknown, suggestedPattern: string) => Promise<'yes' | 'no' | 'always' | 'deny'>) | undefined): void; trust(rule: { tool: string; pattern: string; }): Promise; deny(rule: { tool: string; pattern: string; }): Promise; denyOnce(rule: { tool: string; pattern: string; }): void; allowOnce(rule: { tool: string; pattern: string; }): void; reload(): Promise; explain(tool: Tool, input: unknown, ctx: Context): Promise; } //# sourceMappingURL=directory-permission-policy.d.ts.map