var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { readdir, readFile } from "fs/promises";
import path from "path";
import { parse as parseYaml } from "yaml";
const SKILL_MARKDOWN_FILENAME = "SKILL.md";
const SKILL_FRONTMATTER_SEPARATOR = "\n---\n";
function normalizePluginSkillDirectoryPaths(pluginCustomFolderPaths = []) {
    return Array.from(new Set(pluginCustomFolderPaths
        .map((pluginCustomFolderPath) => path.resolve(pluginCustomFolderPath, "skills"))));
}
function parseSkillManifest(directoryName, markdown) {
    var _a, _b;
    const [frontmatterBlock, instructions = ""] = markdown.split("\r\n").join("\n").split(SKILL_FRONTMATTER_SEPARATOR, 2);
    const metadata = parseYaml(frontmatterBlock);
    return {
        directoryName,
        name: (_a = metadata.name) !== null && _a !== void 0 ? _a : directoryName,
        description: (_b = metadata.description) !== null && _b !== void 0 ? _b : "",
        instructions: instructions.trim(),
    };
}
function readSkillManifest(skillsDirectoryPath, directoryName) {
    return __awaiter(this, void 0, void 0, function* () {
        const markdown = yield readFile(path.join(skillsDirectoryPath, directoryName, SKILL_MARKDOWN_FILENAME), "utf8");
        return parseSkillManifest(directoryName, markdown);
    });
}
function listDirectorySkillManifests(skillsDirectoryPath) {
    return __awaiter(this, void 0, void 0, function* () {
        try {
            const entries = yield readdir(skillsDirectoryPath, { withFileTypes: true });
            return yield Promise.all(entries
                .filter((entry) => entry.isDirectory())
                .map((entry) => entry.name)
                .sort()
                .map((directoryName) => readSkillManifest(skillsDirectoryPath, directoryName)));
        }
        catch (error) {
            if (error.code === "ENOENT") {
                return [];
            }
            throw error;
        }
    });
}
function mergeSkillManifests(skillGroups) {
    return Array.from(new Map(skillGroups.flat().map((skill) => [
        `${skill.name}:${skill.directoryName}`,
        skill,
    ])).values());
}
export function getProjectSkillsDirectoryPath(customComponentsDir) {
    return path.resolve(customComponentsDir, "skills");
}
function getProjectSkillDirectoryPaths(customComponentsDir, pluginCustomFolderPaths = []) {
    return Array.from(new Set([
        getProjectSkillsDirectoryPath(customComponentsDir),
        ...normalizePluginSkillDirectoryPaths(pluginCustomFolderPaths),
    ]));
}
export function listProjectSkillManifests(customComponentsDir_1) {
    return __awaiter(this, arguments, void 0, function* (customComponentsDir, pluginCustomFolderPaths = []) {
        return mergeSkillManifests(yield Promise.all(getProjectSkillDirectoryPaths(customComponentsDir, pluginCustomFolderPaths).map(listDirectorySkillManifests)));
    });
}
export function listSkillManifests(customComponentsDir_1) {
    return __awaiter(this, arguments, void 0, function* (customComponentsDir, pluginCustomFolderPaths = []) {
        return yield listProjectSkillManifests(customComponentsDir, pluginCustomFolderPaths);
    });
}
export function loadSkillManifest(skillName_1, customComponentsDir_1) {
    return __awaiter(this, arguments, void 0, function* (skillName, customComponentsDir, pluginCustomFolderPaths = []) {
        var _a;
        const manifests = yield listSkillManifests(customComponentsDir, pluginCustomFolderPaths);
        return ((_a = manifests.find((manifest) => manifest.name === skillName || manifest.directoryName === skillName)) !== null && _a !== void 0 ? _a : null);
    });
}
export function loadSkillMarkdown(skillName_1, customComponentsDir_1) {
    return __awaiter(this, arguments, void 0, function* (skillName, customComponentsDir, pluginCustomFolderPaths = []) {
        const manifest = yield loadSkillManifest(skillName, customComponentsDir, pluginCustomFolderPaths);
        if (!manifest) {
            return null;
        }
        const directories = [
            ...getProjectSkillDirectoryPaths(customComponentsDir, pluginCustomFolderPaths),
        ];
        for (const skillsDirectoryPath of directories) {
            try {
                return yield readFile(path.join(skillsDirectoryPath, manifest.directoryName, SKILL_MARKDOWN_FILENAME), "utf8");
            }
            catch (error) {
                if (error.code !== "ENOENT") {
                    throw error;
                }
            }
        }
        return null;
    });
}
