"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.permissionCovers = permissionCovers;
exports.readClaudeSettings = readClaudeSettings;
exports.getMissingPermissions = getMissingPermissions;
exports.validateAgentPermissions = validateAgentPermissions;
const fs = __importStar(require("node:fs"));
const path = __importStar(require("node:path"));
const chalk_1 = __importDefault(require("chalk"));
const logger_1 = require("./logger");
const platform_1 = require("./platform");
const CLAUDE_SETTINGS_LOCAL = '.claude/settings.local.json';
const CLAUDE_SETTINGS_PROJECT = '.claude/settings.json';
const REQUIRED_CLAUDE_PERMISSIONS = [
    'Bash(git:*)',
    'Bash(npm:*)',
    'Bash(npx:*)',
    'Bash(node:*)',
    'Bash(python:*)',
    'Bash(tsc:*)',
];
/**
 * Returns true if `existing` permission covers `required`.
 * e.g. "Bash(npm:*)" covers "Bash(npm install:*)" because the command
 * prefix "npm" is a word-boundary prefix of "npm install".
 */
function permissionCovers(existing, required) {
    if (existing === required)
        return true;
    const existingMatch = existing.match(/^(\w+)\((.+)\)$/);
    const requiredMatch = required.match(/^(\w+)\((.+)\)$/);
    if (!existingMatch || !requiredMatch)
        return existing === required;
    const [, existingTool, existingPattern] = existingMatch;
    const [, requiredTool, requiredPattern] = requiredMatch;
    if (existingTool !== requiredTool)
        return false;
    if (existingPattern === '*')
        return true;
    const existingCmd = existingPattern.replace(/:?\*$/, '');
    const requiredCmd = requiredPattern.replace(/:?\*$/, '');
    if (existingCmd === requiredCmd)
        return true;
    if (requiredCmd.startsWith(existingCmd + ' '))
        return true;
    return false;
}
function readClaudeSettings(dir) {
    const files = [
        path.join(dir, CLAUDE_SETTINGS_PROJECT),
        path.join(dir, CLAUDE_SETTINGS_LOCAL),
    ];
    const merged = {};
    for (const file of files) {
        if (!fs.existsSync(file))
            continue;
        try {
            const data = JSON.parse(fs.readFileSync(file, 'utf8'));
            if (data.permissions?.allow) {
                if (!merged.permissions)
                    merged.permissions = {};
                if (!merged.permissions.allow)
                    merged.permissions.allow = [];
                merged.permissions.allow.push(...data.permissions.allow);
            }
        }
        catch {
            // skip unreadable files
        }
    }
    return merged;
}
function getMissingPermissions(required, allowed) {
    return required.filter((req) => !allowed.some((existing) => permissionCovers(existing, req)));
}
function readLocalSettings(dir) {
    const filePath = path.join(dir, CLAUDE_SETTINGS_LOCAL);
    if (!fs.existsSync(filePath))
        return {};
    try {
        return JSON.parse(fs.readFileSync(filePath, 'utf8'));
    }
    catch {
        return {};
    }
}
function writeLocalSettings(dir, settings) {
    const filePath = path.join(dir, CLAUDE_SETTINGS_LOCAL);
    const dirPath = path.dirname(filePath);
    if (!fs.existsSync(dirPath)) {
        fs.mkdirSync(dirPath, { recursive: true });
    }
    fs.writeFileSync(filePath, JSON.stringify(settings, null, 2) + '\n', 'utf8');
}
// ── Claude ────────────────────────────────────────────────────────────────
async function validateClaudePermissions(rl, dir) {
    if (!(0, platform_1.commandExists)('claude')) {
        logger_1.logger.warn('Claude CLI not found — skipping permission check.');
        return;
    }
    const merged = readClaudeSettings(dir);
    const allowed = merged.permissions?.allow ?? [];
    const missing = getMissingPermissions(REQUIRED_CLAUDE_PERMISSIONS, allowed);
    if (missing.length === 0) {
        logger_1.logger.info('Claude: all required permissions are configured.');
        return;
    }
    console.log(`\n  ${chalk_1.default.yellow('Claude is missing required tool permissions:')}`);
    missing.forEach((p) => console.log(`    ${chalk_1.default.dim('•')} ${p}`));
    const raw = await rl.question(`\n  Add them to ${chalk_1.default.cyan(CLAUDE_SETTINGS_LOCAL)}? ${chalk_1.default.dim('[Y/n]')}: `);
    if (raw.trim().toLowerCase() === 'n') {
        logger_1.logger.warn('Skipped Claude permission setup — Claude may prompt for approval during tasks.');
        return;
    }
    const local = readLocalSettings(dir);
    if (!local.permissions)
        local.permissions = {};
    if (!local.permissions.allow)
        local.permissions.allow = [];
    local.permissions.allow.push(...missing);
    writeLocalSettings(dir, local);
    logger_1.logger.success(`Added ${missing.length} permission(s) to ${CLAUDE_SETTINGS_LOCAL}`);
}
// ── Cursor ────────────────────────────────────────────────────────────────
async function validateCursorPermissions(_rl, _dir) {
    if (!(0, platform_1.commandExists)('agent')) {
        logger_1.logger.warn('Cursor Agent CLI (agent) not found — install it from Cursor settings ' +
            'or ensure it is on your PATH.');
        return;
    }
    logger_1.logger.info('Cursor: agent CLI found (uses --trust flag, no additional permissions needed).');
}
// ── Antigravity ────────────────────────────────────────────────────────────
async function validateAntigravityPermissions(_rl, _dir) {
    if (!(0, platform_1.commandExists)('agy') && !(0, platform_1.commandExists)('antigravity')) {
        logger_1.logger.warn('Antigravity CLI (agy or antigravity) not found — install from ' +
            'antigravity.google/download or ensure it is on your PATH.');
        return;
    }
    logger_1.logger.info('Antigravity: CLI found (no additional permissions needed).');
}
// ── Anthropic Agent SDK ────────────────────────────────────────────────────
async function validateAnthropicSdkPermissions(_rl, _dir) {
    let sdkInstalled = true;
    try {
        require.resolve('@anthropic-ai/claude-agent-sdk');
    }
    catch {
        sdkInstalled = false;
    }
    if (!sdkInstalled) {
        logger_1.logger.warn('Anthropic Agent SDK not found — install with: npm install @anthropic-ai/claude-agent-sdk');
    }
    const tokens = (process.env.ANTHROPIC_API_KEY || '')
        .split(',')
        .map((t) => t.trim())
        .filter(Boolean);
    if (tokens.length === 0) {
        logger_1.logger.warn('anthropic-sdk: no ANTHROPIC_API_KEY configured — set one (or a comma-separated pool) in .env.aidev.');
        return;
    }
    if (sdkInstalled) {
        logger_1.logger.info(`anthropic-sdk: SDK installed, ${tokens.length} API key${tokens.length === 1 ? '' : 's'} configured.`);
    }
}
// ── Codex ──────────────────────────────────────────────────────────────────
async function validateCodexPermissions(_rl, _dir) {
    if (!(0, platform_1.commandExists)('codex')) {
        logger_1.logger.warn('Codex CLI not found — install with: npm install -g @openai/codex. ' +
            'Set OPENAI_API_KEY or run codex login.');
        return;
    }
    logger_1.logger.info('Codex: CLI found (codex exec, no additional permissions needed).');
}
// ── Public API ────────────────────────────────────────────────────────────
async function validateAgentPermissions(agents, rl, dir = process.cwd()) {
    for (const agent of agents) {
        if (agent === 'claude') {
            await validateClaudePermissions(rl, dir);
        }
        else if (agent === 'cursor') {
            await validateCursorPermissions(rl, dir);
        }
        else if (agent === 'antigravity') {
            await validateAntigravityPermissions(rl, dir);
        }
        else if (agent === 'codex') {
            await validateCodexPermissions(rl, dir);
        }
        else if (agent === 'anthropic-sdk') {
            await validateAnthropicSdkPermissions(rl, dir);
        }
    }
}
//# sourceMappingURL=permissions.js.map