import { isAbsolute, relative, resolve } from 'node:path';
import { classifyShellCommandPolicy, DEFAULT_MUTATE_RULES, } from '../../core/tools/toolkits/shell-process/shell-policy.js';
import { AutonomyPolicyService } from './autonomy/index.js';
/**
 * Owns reusable approval policy constructors and the default policy chain.
 */
export class ToolApprovalPolicies {
    static default() {
        return [
            ToolApprovalPolicies.toolRequiresApproval(),
            ToolApprovalPolicies.outsideWorkspaceInspection(),
        ];
    }
    static toolRequiresApproval() {
        return ({ tool }) => tool.requiresApproval ? { type: 'request', reason: `${tool.name} requires approval` } : undefined;
    }
    static outsideWorkspaceInspection() {
        return ({ call, workspaceRoot }) => ToolApprovalPolicies.isOutsideWorkspaceInspectionCall({ call, workspaceRoot }) ?
            { type: 'request', reason: `${call.tool} targets a path outside the workspace` }
            : undefined;
    }
    static rememberedProjectRule(args) {
        return (context) => args.isApproved(context) ?
            { type: 'allow', reason: args.reason ?? 'Approved by saved project rule' }
            : undefined;
    }
    static humanSurface(surface) {
        return async (context) => {
            const decision = await surface(context);
            return decision.approved ?
                { type: 'allow', reason: decision.reason }
                : { type: 'deny', reason: decision.reason };
        };
    }
    static unattendedLocalAutomation() {
        return ({ call }) => {
            if (['read_file', 'list_files', 'search_files', 'edit_file'].includes(call.tool)) {
                return { type: 'allow', reason: 'Allowed for unattended local automation' };
            }
            const command = ToolApprovalPolicies.getShellCommand(call);
            if (!command) {
                return undefined;
            }
            const policy = classifyShellCommandPolicy(command, {
                toolName: 'run_shell_mutate',
                rules: DEFAULT_MUTATE_RULES,
                allowUnknown: true,
            });
            return 'error' in policy
                ? { type: 'deny', reason: policy.error }
                : { type: 'allow', reason: policy.reason };
        };
    }
    static autopilot(args) {
        return (context) => AutonomyPolicyService.toApprovalDecision(AutonomyPolicyService.evaluate({
            context,
            profile: args.profile,
        }));
    }
    static isOutsideWorkspaceInspectionCall(args) {
        const { call, workspaceRoot = process.cwd() } = args;
        if (!['read_file', 'list_files', 'search_files', 'edit_file'].includes(call.tool)) {
            return false;
        }
        const input = call.input;
        if (!input || typeof input !== 'object' || Array.isArray(input)) {
            return false;
        }
        const record = input;
        const rawPath = typeof record.path === 'string'
            ? record.path
            : call.tool === 'search_files' ? '.'
                : undefined;
        if (!rawPath) {
            return false;
        }
        const resolvedWorkspaceRoot = resolve(workspaceRoot);
        const resolvedTarget = resolve(resolvedWorkspaceRoot, rawPath);
        const relativeTarget = relative(resolvedWorkspaceRoot, resolvedTarget);
        return relativeTarget.startsWith('..') || isAbsolute(relativeTarget);
    }
    static getShellCommand(call) {
        if (call.tool !== 'run_shell_mutate') {
            return undefined;
        }
        const input = call.input;
        if (!input || typeof input !== 'object' || Array.isArray(input)) {
            return undefined;
        }
        const command = input.command;
        return typeof command === 'string' && command.trim() ? command : undefined;
    }
}
//# sourceMappingURL=policies.js.map