import inquirer from "@inquirer/prompts" import chalk from "chalk" export type PermissionBehavior = "allow" | "deny" | "ask" export interface PermissionCheckResult { behavior: PermissionBehavior message?: string suggestion?: string updatedInput?: Record } export interface PermissionConfig { allowedTools: Set deniedTools: Set sessionTrust: Map } export class PermissionManager { private config: PermissionConfig constructor() { this.config = { allowedTools: new Set(), deniedTools: new Set(), sessionTrust: new Map(), } } trustTool(toolName: string): void { this.config.sessionTrust.set(toolName, true) } isTrusted(toolName: string): boolean { return this.config.sessionTrust.get(toolName) === true } async check( toolName: string, input: Record, isDestructive: boolean ): Promise { if (this.isTrusted(toolName)) { return { behavior: "allow" } } if (this.config.deniedTools.has(toolName)) { return { behavior: "deny", message: `Tool '${toolName}' is denied` } } if (isDestructive) { const command = toolName === "bash" ? (input.command as string) : "" const preview = command ? command.slice(0, 80) + (command.length > 80 ? "..." : "") : JSON.stringify(input).slice(0, 100) console.log(chalk.yellow(`\n⚠ ${toolName} wants to execute:`)) console.log(chalk.dim(preview)) const confirmed = await inquirer.confirm({ message: `Allow ${toolName}? (y/N)`, default: false, }) if (!confirmed) { return { behavior: "deny", message: "User denied" } } const alwaysTrust = await inquirer.confirm({ message: `Trust ${toolName} for this session? (y/N)`, default: false, }) if (alwaysTrust) { this.trustTool(toolName) } return { behavior: "allow" } } return { behavior: "allow" } } }