/** * Permission Manager for handling tool permission checks * * This manager provides utilities for checking permissions before tool execution. * It implements the permission logic for different modes (default vs bypass) and * handles custom callback integration. */ import type { PermissionDecision, ToolPermissionContext, PermissionCallback, PermissionMode } from "../types/permissions.js"; import type { Logger } from "../types/index.js"; import { Container } from "../utils/container.js"; export interface PermissionManagerOptions { /** Configured permission mode from settings */ configuredPermissionMode?: PermissionMode; /** Allowed rules from settings */ allowedRules?: string[]; /** Denied rules from settings */ deniedRules?: string[]; /** Instance-specific allowed rules (from AgentOptions) */ instanceAllowedRules?: string[]; /** Instance-specific denied rules (from AgentOptions) */ instanceDeniedRules?: string[]; /** Additional directories considered part of the Safe Zone */ additionalDirectories?: string[]; /** System additional directories (persistent across reloads) */ systemAdditionalDirectories?: string[]; /** Path to the current plan file */ planFilePath?: string; /** Optional logger */ logger?: Logger; } export declare class PermissionManager { private container; private configuredPermissionMode?; private allowedRules; private deniedRules; private instanceAllowedRules; private instanceDeniedRules; private temporaryRules; private additionalDirectories; private systemAdditionalDirectories; private planFilePath?; private hasExitedPlanMode; private needsPlanModeExitAttachment; private workdir?; private worktreeName?; private mainRepoRoot?; private onConfiguredPermissionModeChange?; private _logger?; constructor(container: Container, options?: PermissionManagerOptions); /** * Resolve the working directory from the DI container */ private getWorkdir; /** * Set a callback to be notified when the effective permission mode changes due to configuration updates */ setOnConfiguredPermissionModeChange(callback: (mode: PermissionMode) => void): void; /** * Update the configured default mode (e.g., when configuration reloads) */ updateConfiguredPermissionMode(permissionMode?: PermissionMode): void; /** * Get the configured default mode */ getConfiguredPermissionMode(): PermissionMode | undefined; /** * Get all currently allowed rules (user-defined) */ getAllowedRules(): string[]; /** * Get all currently denied rules */ getDeniedRules(): string[]; /** * Get all instance-specific allowed rules */ getInstanceAllowedRules(): string[]; /** * Get all instance-specific denied rules */ getInstanceDeniedRules(): string[]; /** * Get all additional directories */ getAdditionalDirectories(): string[]; /** * Get all system additional directories */ getSystemAdditionalDirectories(): string[]; /** * Get all default allowed rules */ getDefaultAllowedRules(): string[]; /** * Update the allowed rules (e.g., when configuration reloads) */ updateAllowedRules(rules: string[]): void; /** * Update the denied rules (e.g., when configuration reloads) */ updateDeniedRules(rules: string[]): void; /** * Add temporary rules for the current session */ addTemporaryRules(rules: string[]): void; /** * Clear all temporary rules */ clearTemporaryRules(): void; /** * Update the additional directories (e.g., when configuration reloads) */ updateAdditionalDirectories(directories: string[]): void; /** * Add a system-level additional directory that is persistent across configuration reloads */ addSystemAdditionalDirectory(directory: string): void; /** * Set the current plan file path */ setPlanFilePath(path: string | undefined): void; /** * Get the current plan file path */ getPlanFilePath(): string | undefined; setHasExitedPlanMode(value: boolean): void; hasExitedPlanModeInSession(): boolean; setNeedsPlanModeExitAttachment(value: boolean): void; getNeedsPlanModeExitAttachment(): boolean; /** * Public wrapper for isInsideSafeZone to check if a path is in the safe zone */ isPathInSafeZone(targetPath: string): boolean; /** * Check if a path is inside the Safe Zone (workdir + additionalDirectories) */ private isInsideSafeZone; /** * Get the current effective permission mode for tool execution context */ getCurrentEffectiveMode(cliPermissionMode?: PermissionMode): PermissionMode; /** * Resolve the effective permission mode based on CLI override and configured default */ resolveEffectivePermissionMode(cliPermissionMode?: PermissionMode): PermissionMode; /** * Check if a tool execution requires permission and handle the authorization flow * Called by individual tools after validation/diff, before real operation */ checkPermission(context: ToolPermissionContext): Promise; /** * Determine if a tool requires permission checks based on its name */ isRestrictedTool(toolName: string): boolean; /** * Check if a tool is completely denied by name in instance or global rules */ isToolDenied(toolName: string): boolean; /** * Helper method to create a permission context for CLI integration */ createContext(toolName: string, permissionMode: PermissionMode, callback?: PermissionCallback, toolInput?: Record, toolCallId?: string, planContent?: string): ToolPermissionContext; /** * Check if a tool call matches a specific permission rule */ private matchesRule; /** * Check if a tool call is allowed by persistent or temporary rules */ private isAllowedByRule; /** * Expand a bash command into individual permission rules, filtering out safe commands. * Used when saving permissions to the allow list. * * @param command The full bash command string * @param workdir The working directory for path safety checks * @returns Array of permission rules in "Bash(cmd)" format */ expandBashRule(command: string, workdir: string): string[]; /** * Add a persistent permission rule * @param rule - The rule to add (e.g., "Bash(ls)") */ addPermissionRule(rule: string): Promise; }