/** * Tool-level permissions - Explicit approval for specific tools * * Permissions provide fine-grained control over which tools can execute * and when user approval is required. */ /** * Permission levels for tool execution * * - 'always': Tool can execute without asking (trusted tools) * - 'session': Ask once per session, then allow for remainder * - 'once': Ask every time the tool is invoked * - 'deny': Never allow execution (blocked tools) */ export type PermissionLevel = 'always' | 'session' | 'once' | 'deny'; /** * Permission rule for a specific tool */ export interface ToolPermission { /** * Tool name or pattern (supports wildcards like 'bash*', '*_file') */ toolName: string; /** * Permission level for this tool */ level: PermissionLevel; /** * Human-readable description of why permission is needed */ description?: string; /** * Tags for grouping permissions */ tags?: string[]; } /** * Permission request passed to the handler */ export interface PermissionRequest { /** * Name of the tool requesting permission */ toolName: string; /** * Input arguments for the tool */ input: Record; /** * Permission level that triggered the request */ level: PermissionLevel; /** * Description of why permission is needed */ description?: string; /** * Formatted preview of what the tool will do */ preview?: string; } /** * Result of a permission check */ export interface PermissionCheckResult { /** * Whether execution is allowed */ allowed: boolean; /** * The permission level that applied */ level: PermissionLevel; /** * Whether user confirmation was required */ askedUser: boolean; /** * The tool permission rule that matched (if any) */ rule?: ToolPermission; /** * Reason for denial (if not allowed) */ reason?: string; } /** * Response shape from a permission handler. * * Either a plain boolean (legacy — backward compatible) OR a structured * object that can carry an optional reason. The reason is delivered to * the agent inline with the tool's permission-denied error so the agent * sees the user's context immediately, in the same turn. * * @example * ```typescript * // Legacy (still supported): * return true; * return false; * * // With reason: * return { allowed: false, reason: 'Use project_document_add instead' }; * return { allowed: true }; * ``` */ export type PermissionHandlerResponse = boolean | { allowed: boolean; reason?: string; }; /** * Handler called when permission is needed * * @param request - Information about the permission request * @returns true to allow / false to deny — or { allowed, reason? } to * carry context (especially useful when denying with a message) * * @example * ```typescript * const handler: PermissionHandler = async (request) => { * // Show UI prompt to user * const result = await showConfirmDialog( * `Allow ${request.toolName}?`, * request.description * ); * if (!result.allowed && result.message) { * return { allowed: false, reason: result.message }; * } * return result.allowed; * }; * ``` */ export type PermissionHandler = (request: PermissionRequest) => PermissionHandlerResponse | Promise; /** * Preview generator for permission requests * * @param toolName - Name of the tool * @param input - Tool input arguments * @returns Human-readable preview of the operation */ export type PreviewGenerator = (toolName: string, input: Record) => string | undefined; /** * Configuration for the PermissionManager */ export interface PermissionManagerOptions { /** * Enable permission checking (default: true) */ enabled?: boolean; /** * Default permission level for tools not explicitly configured * @default 'always' */ defaultLevel?: PermissionLevel; /** * Handler called when permission is needed (for 'session' and 'once' levels) */ onPermissionRequest?: PermissionHandler; /** * Tool-specific permission rules */ rules?: ToolPermission[]; /** * Custom preview generator for permission requests */ previewGenerator?: PreviewGenerator; /** * Whether to include default permission rules for dangerous tools * @default false */ includeDefaults?: boolean; } /** * Event types for permission operations */ export type PermissionEventType = 'permission:granted' | 'permission:denied' | 'permission:asked' | 'permission:session_granted'; /** * Permission event payload */ export interface PermissionEvent { type: PermissionEventType; toolName: string; level: PermissionLevel; input?: Record; rule?: ToolPermission; } /** * Event handler for permission events */ export type PermissionEventHandler = (event: PermissionEvent) => void;