// @crash-shield-ignore-file — config/cache reader for Planu-controlled JSON; writer is this codebase, shape guaranteed by build/seed.
// engine/auto-updater/config-detector.ts — Detects MCP config file location and Planu install method.
// SPEC-443
import { readFile } from 'node:fs/promises';
import { homedir } from 'node:os';
import { join } from 'node:path';
import { PLANU_VERSION } from '../../config/version.js';
// ---------------------------------------------------------------------------
// Config path resolution
// ---------------------------------------------------------------------------
/** All supported MCP config paths, in priority order. */
function getCandidatePaths() {
    const home = homedir();
    return [
        { type: 'claudeCode', path: join(home, '.claude.json') },
        {
            type: 'claudeDesktopMac',
            path: join(home, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json'),
        },
        {
            type: 'claudeDesktopLinux',
            path: join(home, '.config', 'Claude', 'claude_desktop_config.json'),
        },
    ];
}
/**
 * Finds the first MCP config file that exists on disk.
 * Returns the path and type, or null values if none found.
 */
export async function findMcpConfig() {
    const candidates = getCandidatePaths();
    for (const candidate of candidates) {
        try {
            await readFile(candidate.path, 'utf-8');
            return { configPath: candidate.path, configType: candidate.type };
        }
        catch {
            // File does not exist or is not readable — try next
        }
    }
    return { configPath: null, configType: null };
}
// ---------------------------------------------------------------------------
// Install method detection
// ---------------------------------------------------------------------------
/**
 * Determines how Planu is installed based on the mcpServers.planu entry.
 */
export function detectInstallMethod(mcpEntry) {
    const args = mcpEntry.args ?? [];
    if (mcpEntry.command === 'npx') {
        const hasPlanu = args.some((a) => a === '@planu/cli@latest' || a === '@planu/cli' || a.startsWith('@planu/cli@'));
        if (hasPlanu) {
            return args.some((a) => a.includes('@latest')) ? 'npx-latest' : 'npx-pinned';
        }
    }
    if (mcpEntry.command === 'planu' ||
        (typeof mcpEntry.command === 'string' && mcpEntry.command.endsWith('/planu'))) {
        return 'global';
    }
    if (mcpEntry.command === 'node' || args.some((a) => a.includes('/dist/'))) {
        return 'local-path';
    }
    return 'unknown';
}
// ---------------------------------------------------------------------------
// Combined detection
// ---------------------------------------------------------------------------
/**
 * Reads the MCP config, finds the planu entry, and returns full install info.
 */
export async function detectPlanuInstall() {
    const location = await findMcpConfig();
    if (location.configPath === null) {
        return {
            method: 'unknown',
            currentVersion: PLANU_VERSION,
            configPath: null,
            mcpEntry: null,
        };
    }
    let config;
    try {
        const raw = await readFile(location.configPath, 'utf-8');
        config = JSON.parse(raw);
    }
    catch {
        return {
            method: 'unknown',
            currentVersion: PLANU_VERSION,
            configPath: location.configPath,
            mcpEntry: null,
        };
    }
    const mcpEntry = config.mcpServers?.planu ?? null;
    if (mcpEntry === null) {
        return {
            method: 'unknown',
            currentVersion: PLANU_VERSION,
            configPath: location.configPath,
            mcpEntry: null,
        };
    }
    const method = detectInstallMethod(mcpEntry);
    return {
        method,
        currentVersion: PLANU_VERSION,
        configPath: location.configPath,
        mcpEntry,
    };
}
//# sourceMappingURL=config-detector.js.map