// Planu — Settings and extensions auditor for SPEC-092, SPEC-374
import { readFile, access } from 'node:fs/promises';
import { join } from 'node:path';
const DOCS_REF = 'https://code.claude.com/docs/en/settings';
const RTK_DOCS_REF = 'https://github.com/planu-dev/rtk';
async function readSettings(filePath) {
    try {
        const content = await readFile(filePath, 'utf-8');
        return JSON.parse(content);
    }
    catch {
        return null;
    }
}
async function pathExists(p) {
    try {
        await access(p);
        return true;
    }
    catch {
        return false;
    }
}
function settingsHasRtkHook(data) {
    const preToolUse = data.hooks?.PreToolUse;
    if (!Array.isArray(preToolUse)) {
        return false;
    }
    return preToolUse.some((entry) => (entry.hooks ?? []).some((h) => typeof h === 'string' && h.toLowerCase().includes('rtk')));
}
function auditSingleSettings(data, label) {
    const findings = [];
    const allowList = data.permissions?.allow ?? [];
    for (const pattern of ['mcp__specforge__', 'mcp__sdd__']) {
        const obsolete = allowList.filter((p) => p.includes(pattern));
        if (obsolete.length > 0) {
            findings.push({
                area: 'settings',
                severity: 'warn',
                message: `${label} has ${String(obsolete.length)} obsolete permission(s) matching "${pattern}"`,
                suggestion: `Remove obsolete entries from permissions.allow: ${obsolete.join(', ')}`,
                docsRef: DOCS_REF,
            });
        }
    }
    if (data.autoMemoryEnabled === false) {
        findings.push({
            area: 'settings',
            severity: 'info',
            message: `${label} has autoMemoryEnabled: false — auto-memory is disabled`,
            suggestion: 'Consider enabling auto-memory for cross-session learning',
            docsRef: DOCS_REF,
        });
    }
    const defaultMode = data.permissions?.defaultMode;
    if ((defaultMode === 'auto' || defaultMode === 'acceptEdits') &&
        data.autoMode?.environment === undefined) {
        findings.push({
            area: 'settings',
            severity: 'warn',
            code: 'AUTO_MODE_ENV_MISSING',
            message: `${label} has permissions.defaultMode="${defaultMode}" but no autoMode.environment configured`,
            suggestion: 'Configure autoMode.environment (e.g., "docker", "vm") to define trusted repos/buckets for auto-mode',
            docsRef: DOCS_REF,
        });
    }
    if (defaultMode === 'bypassPermissions') {
        findings.push({
            area: 'settings',
            severity: 'critical',
            code: 'BYPASS_PERMISSIONS_NO_ISOLATION',
            message: `${label} has permissions.defaultMode="bypassPermissions" — all permission checks are disabled`,
            suggestion: 'Only use bypassPermissions inside isolated containers or VMs. Remove from developer workstations.',
            docsRef: DOCS_REF,
        });
    }
    if (!settingsHasRtkHook(data)) {
        findings.push({
            area: 'settings',
            severity: 'info',
            code: 'RTK_HOOK_MISSING',
            message: `${label} has no RTK PreToolUse hook configured`,
            suggestion: 'Add RTK (Response Token Killer) to PreToolUse hooks to reduce token usage by 30-60%. ' +
                'Run suggest_token_optimizer for setup instructions.',
            docsRef: RTK_DOCS_REF,
        });
    }
    return findings;
}
function auditCompactWindow() {
    const val = process.env.CLAUDE_CODE_AUTO_COMPACT_WINDOW;
    if (val === undefined || val === '') {
        return {
            area: 'settings',
            severity: 'info',
            code: 'COMPACT_WINDOW_MISSING',
            message: 'CLAUDE_CODE_AUTO_COMPACT_WINDOW is not set — long sessions consume more tokens',
            suggestion: 'Set CLAUDE_CODE_AUTO_COMPACT_WINDOW=200000 in your shell profile to cap context window size and reduce token costs.',
            docsRef: DOCS_REF,
        };
    }
    return null;
}
export async function auditSettings(projectPath) {
    const findings = [];
    const pairs = [
        { path: join(projectPath, '.claude', 'settings.json'), label: 'settings.json' },
        { path: join(projectPath, '.claude', 'settings.local.json'), label: 'settings.local.json' },
    ];
    for (const { path: p, label } of pairs) {
        const data = await readSettings(p);
        if (data) {
            findings.push(...auditSingleSettings(data, label));
        }
    }
    if (!(await pathExists(join(projectPath, '.claude', 'skills')))) {
        findings.push({
            area: 'settings',
            severity: 'info',
            message: 'No .claude/skills/ directory found',
            suggestion: 'Create skills for repeatable workflows — invoke with /skill-name in Claude Code',
            docsRef: DOCS_REF,
        });
    }
    if (!(await pathExists(join(projectPath, '.claude', 'hooks')))) {
        findings.push({
            area: 'settings',
            severity: 'info',
            message: 'No .claude/hooks/ directory found',
            suggestion: 'Add hooks to automate quality gates (e.g., filter test output, truncate long logs)',
            docsRef: DOCS_REF,
        });
    }
    const compactWindowFinding = auditCompactWindow();
    if (compactWindowFinding !== null) {
        findings.push(compactWindowFinding);
    }
    return findings;
}
//# sourceMappingURL=settings-auditor.js.map