// SPEC-597-EXEMPT: canonical mapping (npm-package↔framework, keyword catalogue)
// — must enumerate framework names by design; no detection logic to migrate.
// tools/suggest-tooling/skills-catalog.ts — SPEC-022 skills.sh catalog fetcher
// Extracted from suggest-tooling.ts to stay within the 400-line file budget.
import { getJvmVersion } from '../../config/version-defaults.js';
// === SPEC-013: Mobile tooling lines ===
export function buildMobileToolingLines(knowledge) {
    const mobileFrameworks = [
        'swiftui',
        'uikit',
        'flutter',
        'react-native',
        'expo',
        'jetpack-compose',
        'android-views',
        'kotlin-multiplatform',
    ];
    // knowledge.apps may be missing in partial mocks; guard with an explicit check
    const apps = Array.isArray(knowledge.apps) ? knowledge.apps : [];
    const isMobile = apps.some(
    /* v8 ignore start */ // null-coalescing fallback for framework is runtime-dependent
    (app) => mobileFrameworks.includes(app.framework ?? '') || app.mobilePlatform !== undefined);
    const isIos = apps.some((app) => app.mobilePlatform === 'ios' || app.framework === 'swiftui' || app.framework === 'uikit');
    const isAndroid = apps.some((app) => app.mobilePlatform === 'android' ||
        app.framework === 'compose' ||
        app.framework === 'xml-views');
    const lines = [];
    if (isMobile) {
        lines.push('## Mobile Tooling');
        lines.push('');
    }
    if (isIos) {
        lines.push('### iOS Tools');
        lines.push('');
        lines.push('- **SwiftLint** — Static code analysis for Swift');
        lines.push('- **SwiftFormat** — Code formatting for Swift');
        lines.push('- **Fastlane** — Automated iOS deployment (match: cert sync, gym: build, pilot: TestFlight)');
        lines.push('- **Xcode Cloud** — CI/CD integrated with Xcode');
        lines.push('- **Firebase App Distribution** — Beta testing distribution');
        lines.push("- **TestFlight** — Apple's official beta testing platform");
        lines.push('- **App Store Connect API** — Automated App Store management');
        lines.push('');
        lines.push('### iOS Release Pipeline');
        lines.push('');
        lines.push('- **iOS Release Pipeline:** Fastlane match (cert sync) → Fastlane gym (build .ipa) → Fastlane pilot (TestFlight upload) → App Store Connect API submission');
        lines.push('- **App Store Checklist:** app screenshots (6.9" + 6.7" + 5.5" + 12.9" iPad), PrivacyInfo.xcprivacy manifest, export compliance declaration, app review guidelines compliance');
        lines.push('');
    }
    if (isAndroid) {
        lines.push('### Android Tools');
        lines.push('');
        lines.push('- **Ktlint** — Kotlin linting and formatting');
        lines.push('- **Detekt** — Static code analysis for Kotlin');
        lines.push('- **Fastlane Supply** — Automated Play Store deployment');
        lines.push('- **Firebase App Distribution** — Beta testing distribution');
        lines.push('- **GitHub Actions + Gradle** — CI/CD pipeline for Android');
        lines.push('- **Firebase Crashlytics** — Crash reporting');
        lines.push('');
        lines.push('### Android Release Pipeline');
        lines.push('');
        lines.push('- **Android Release Pipeline:** Gradle assemble/bundle → sign AAB with keystore → Fastlane supply or GitHub Actions upload-artifact → Play Store internal track → staged rollout');
        lines.push('- **Play Store Checklist:** signed .aab file, targetSdk meeting current requirements, 64-bit native libraries, content rating questionnaire, screenshots (phone + 7" + 10" tablet)');
        lines.push('');
    }
    return lines;
}
// === SPEC-013 TD-P14-02: Compose Multiplatform tooling ===
/**
 * Returns true when the project uses Kotlin Multiplatform or Compose Multiplatform.
 */
function isKmpProject(knowledge) {
    const stackLower = knowledge.stack.map((s) => s.toLowerCase());
    const frameworkLower = (knowledge.framework ?? '').toLowerCase();
    return (frameworkLower === 'kmp' ||
        frameworkLower === 'kotlin-multiplatform' ||
        frameworkLower === 'compose-multiplatform' ||
        stackLower.some((s) => s.includes('kotlin-multiplatform') || s.includes('compose-multiplatform') || s === 'kmp'));
}
/**
 * Build Compose Multiplatform tooling recommendation lines.
 * Emitted when the project is a KMP/Compose Multiplatform project.
 */
export function buildKmpToolingLines(knowledge) {
    if (!isKmpProject(knowledge)) {
        return [];
    }
    return [
        '## Compose Multiplatform Tooling',
        '',
        `### Compose Multiplatform ${getJvmVersion('compose-multiplatform')}+ (Stable iOS — May 2025)`,
        '',
        `- **Compose Multiplatform ${getJvmVersion('compose-multiplatform')}+** — Share UI across Android + iOS + Desktop with SwiftUI interop`,
        '  - iOS target is now **stable and production-ready** (scroll physics on par with SwiftUI, all APIs finalized)',
        `  - Install: add \`compose.multiplatform = "${getJvmVersion('compose-multiplatform')}"\` to \`gradle/libs.versions.toml\``,
        '  - iOS integration: UIViewController embedding via `ComposeUIViewController`, SwiftUI interop via `UIViewControllerRepresentable`',
        '  - Docs: https://www.jetbrains.com/compose-multiplatform/',
        '',
        '- **KMP test tooling:** `kotlin.test` (multiplatform assertions), `Turbine` (Flow testing), `Mokkery` (mocking)',
        `  - Install: \`testImplementation("app.cash.turbine:turbine:${getJvmVersion('turbine')}")\``,
        '',
        '> Compose Multiplatform iOS reached stable status in May 2025. Recommended over React Native/Flutter for Kotlin-first teams.',
        '',
    ];
}
// === SPEC-033 TD-P14-03: K3s tooling recommendations ===
/**
 * Returns true when the project uses K3s as orchestrator.
 * Combines filesystem detection (k3sDetected) with stack/conventions/tooling signals.
 */
function isK3sProject(knowledge) {
    // SPEC-033 TD-P14-01: filesystem detection takes precedence
    if (knowledge.k3sDetected === true) {
        return true;
    }
    const stackLower = knowledge.stack.map((s) => s.toLowerCase());
    const conventionsStr = JSON.stringify(knowledge.conventions).toLowerCase();
    const toolingStr = JSON.stringify(knowledge.tooling).toLowerCase();
    return (stackLower.some((s) => s.includes('k3s')) ||
        conventionsStr.includes('k3s') ||
        toolingStr.includes('k3s') ||
        toolingStr.includes('k3s.yaml') ||
        toolingStr.includes('k3s+k3s1'));
}
/**
 * Build K3s-specific tooling recommendation lines.
 * Emitted when K3s is detected in the project stack or conventions.
 */
export function buildK3sToolingLines(knowledge) {
    if (!isK3sProject(knowledge)) {
        return [];
    }
    return [
        '## K3s Tooling (Kubernetes-certified lightweight cluster)',
        '',
        '- **Helm** — Kubernetes-compatible package manager, works identically with K3s',
        '  - Install: `curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash`',
        '  - K3s note: Helm charts designed for K8s are fully compatible — no changes needed',
        '  - Docs: https://helm.sh',
        '',
        '- **Traefik** — Default K3s ingress controller (pre-installed in K3s)',
        '  - Configure via `HelmChart` CRD or `IngressRoute` CRD',
        '  - Dashboard: `kubectl port-forward -n kube-system deploy/traefik 9000`',
        '  - Docs: https://doc.traefik.io/traefik/providers/kubernetes-crd/',
        '',
        '- **Rancher** — Multi-cluster management for K3s (official JetBrains/SUSE tool)',
        '  - Install: deploy to a dedicated management cluster or use Rancher Desktop locally',
        '  - K3s note: Rancher is the recommended GUI/management layer for K3s production clusters',
        '  - Docs: https://rancherdesktop.io',
        '',
        '> K3s is CNCF-certified Kubernetes (88% of orgs with K8s report TCO advantages with K3s for edge/dev environments).',
        '',
    ];
}
// === SPEC-022: skills.sh catalog fetcher ===
// Note: fetchRecommendedSkills was extracted to skills-fetcher.ts (SPEC-017a).
// The functions below are retained for compatibility but are no longer the primary path.
/* v8 ignore start */
function isMcpServer(knowledge) {
    const stackLower = knowledge.stack.map((s) => s.toLowerCase());
    const toolingStr = JSON.stringify(knowledge.tooling).toLowerCase();
    return (stackLower.some((s) => s.includes('mcp') || s.includes('@modelcontextprotocol')) ||
        toolingStr.includes('modelcontextprotocol') ||
        toolingStr.includes('@modelcontextprotocol'));
}
async function fetchSkillsShCatalog(stack, language) {
    return new Promise((resolve) => {
        const stackParam = encodeURIComponent([...stack, language].join(',').toLowerCase());
        const url = `https://skills.sh/api/catalog?stack=${stackParam}`;
        // Dynamic import to avoid top-level import of https
        import('node:https')
            .then(({ default: https }) => {
            /* v8 ignore start */
            const req = https.get(url, { timeout: 5000 }, (res) => {
                let data = '';
                res.on('data', (chunk) => {
                    data += chunk.toString();
                });
                res.on('end', () => {
                    try {
                        const parsed = JSON.parse(data);
                        const results = (parsed.skills ?? []).slice(0, 5).map((s) => ({
                            name: s.name,
                            description: s.description ?? `Skill: ${s.name}`,
                            installCommand: s.installCommand ?? `npx skills add ${s.name}`,
                            justification: `Relevant to your ${language} stack`,
                        }));
                        resolve(results);
                    }
                    catch {
                        resolve([]);
                    }
                });
            });
            req.on('error', () => {
                resolve([]);
            });
            req.on('timeout', () => {
                req.destroy();
                resolve([]);
            });
            /* v8 ignore stop */
        })
            .catch(() => {
            resolve([]);
        });
    });
}
function buildFallbackSkills(knowledge) {
    const skills = [];
    const stackLower = knowledge.stack.map((s) => s.toLowerCase());
    const lang = knowledge.language.toLowerCase();
    if (lang === 'typescript' || lang === 'javascript') {
        skills.push({
            name: 'typescript-patterns',
            description: 'TypeScript best practices, strict mode patterns, and type safety conventions',
            installCommand: 'npx skills add typescript-patterns',
            justification: `Project uses ${knowledge.language}`,
        });
    }
    if (stackLower.some((s) => s.includes('react'))) {
        skills.push({
            name: 'react-patterns',
            description: 'React component patterns, hooks best practices, and performance optimization',
            installCommand: 'npx skills add react-patterns',
            justification: 'React detected in project stack',
        });
    }
    if (stackLower.some((s) => s.includes('next'))) {
        skills.push({
            name: 'nextjs-patterns',
            description: 'Next.js App Router patterns, server components, and deployment best practices',
            installCommand: 'npx skills add nextjs-patterns',
            justification: 'Next.js detected in project stack',
        });
    }
    if (stackLower.some((s) => s.includes('python')) ||
        knowledge.language.toLowerCase() === 'python') {
        skills.push({
            name: 'python-patterns',
            description: 'Python best practices, type hints, async patterns, and testing conventions',
            installCommand: 'npx skills add python-patterns',
            justification: 'Python detected in project stack',
        });
    }
    return skills;
}
export async function fetchRecommendedSkills(knowledge) {
    const skills = [];
    // Always add mcp-builder first for MCP server projects
    if (isMcpServer(knowledge)) {
        skills.push({
            name: 'mcp-builder',
            description: 'Best practices and conventions for building high-quality MCP servers',
            installCommand: 'npx skills add mcp-builder',
            justification: 'Project detected as an MCP server (@modelcontextprotocol detected in stack/tooling)',
        });
    }
    // Fetch skills.sh catalog in real time (with graceful fallback to hardcoded skills)
    const catalogSkills = await fetchSkillsShCatalog(knowledge.stack, knowledge.language);
    if (catalogSkills.length > 0) {
        skills.push(...catalogSkills);
    }
    else {
        // Fallback: use hardcoded relevant skills when catalog is unavailable or empty
        skills.push(...buildFallbackSkills(knowledge));
    }
    // Deduplicate by name
    const seen = new Set();
    return skills.filter((s) => {
        if (seen.has(s.name)) {
            return false;
        }
        seen.add(s.name);
        return true;
    });
}
/* v8 ignore stop */
//# sourceMappingURL=skills-catalog.js.map