/**
 * Tool Detection Utilities
 *
 * Shared utilities for detecting tool configurations and version status.
 */
import path from 'path';
import * as fs from 'fs';
import { AI_TOOLS } from '../config.js';
/**
 * Names of skill directories created by openspec init.
 */
export const SKILL_NAMES = [
    'openspec-explore',
    'openspec-new-change',
    'openspec-continue-change',
    'openspec-apply-change',
    'openspec-ff-change',
    'openspec-sync-specs',
    'openspec-archive-change',
    'openspec-bulk-archive-change',
    'openspec-verify-change',
    'openspec-onboard',
    'openspec-propose',
];
/**
 * IDs of command templates created by openspec init.
 */
export const COMMAND_IDS = [
    'explore',
    'new',
    'continue',
    'apply',
    'ff',
    'sync',
    'archive',
    'bulk-archive',
    'verify',
    'onboard',
    'propose',
];
/**
 * Gets the list of tools with skillsDir configured.
 */
export function getToolsWithSkillsDir() {
    return AI_TOOLS.filter((t) => t.skillsDir).map((t) => t.value);
}
/**
 * Checks which skill files exist for a tool.
 */
export function getToolSkillStatus(projectRoot, toolId) {
    const tool = AI_TOOLS.find((t) => t.value === toolId);
    if (!tool?.skillsDir) {
        return { configured: false, fullyConfigured: false, skillCount: 0 };
    }
    const skillsDir = path.join(projectRoot, tool.skillsDir, 'skills');
    let skillCount = 0;
    for (const skillName of SKILL_NAMES) {
        const skillFile = path.join(skillsDir, skillName, 'SKILL.md');
        if (fs.existsSync(skillFile)) {
            skillCount++;
        }
    }
    return {
        configured: skillCount > 0,
        fullyConfigured: skillCount === SKILL_NAMES.length,
        skillCount,
    };
}
/**
 * Gets the skill status for all tools with skillsDir configured.
 */
export function getToolStates(projectRoot) {
    const states = new Map();
    const toolIds = AI_TOOLS.filter((t) => t.skillsDir).map((t) => t.value);
    for (const toolId of toolIds) {
        states.set(toolId, getToolSkillStatus(projectRoot, toolId));
    }
    return states;
}
/**
 * Extracts the generatedBy version from a skill file's YAML frontmatter.
 * Returns null if the field is not found or the file doesn't exist.
 */
export function extractGeneratedByVersion(skillFilePath) {
    try {
        if (!fs.existsSync(skillFilePath)) {
            return null;
        }
        const content = fs.readFileSync(skillFilePath, 'utf-8');
        // Look for generatedBy in the YAML frontmatter
        // The file format is:
        // ---
        // ...
        // metadata:
        //   author: openspec
        //   version: "1.0"
        //   generatedBy: "0.23.0"
        // ---
        const generatedByMatch = content.match(/^\s*generatedBy:\s*["']?([^"'\n]+)["']?\s*$/m);
        if (generatedByMatch && generatedByMatch[1]) {
            return generatedByMatch[1].trim();
        }
        return null;
    }
    catch {
        return null;
    }
}
/**
 * Gets version status for a tool by reading the first available skill file.
 */
export function getToolVersionStatus(projectRoot, toolId, currentVersion) {
    const tool = AI_TOOLS.find((t) => t.value === toolId);
    if (!tool?.skillsDir) {
        return {
            toolId,
            toolName: toolId,
            configured: false,
            generatedByVersion: null,
            needsUpdate: false,
        };
    }
    const skillsDir = path.join(projectRoot, tool.skillsDir, 'skills');
    let generatedByVersion = null;
    // Find the first skill file that exists and read its version
    for (const skillName of SKILL_NAMES) {
        const skillFile = path.join(skillsDir, skillName, 'SKILL.md');
        if (fs.existsSync(skillFile)) {
            generatedByVersion = extractGeneratedByVersion(skillFile);
            break;
        }
    }
    const configured = getToolSkillStatus(projectRoot, toolId).configured;
    const needsUpdate = configured && (generatedByVersion === null || generatedByVersion !== currentVersion);
    return {
        toolId,
        toolName: tool.name,
        configured,
        generatedByVersion,
        needsUpdate,
    };
}
/**
 * Gets all configured tools in the project.
 */
export function getConfiguredTools(projectRoot) {
    return AI_TOOLS
        .filter((t) => t.skillsDir && getToolSkillStatus(projectRoot, t.value).configured)
        .map((t) => t.value);
}
/**
 * Gets version status for all configured tools.
 */
export function getAllToolVersionStatus(projectRoot, currentVersion) {
    const configuredTools = getConfiguredTools(projectRoot);
    return configuredTools.map((toolId) => getToolVersionStatus(projectRoot, toolId, currentVersion));
}
//# sourceMappingURL=tool-detection.js.map