/**
 * Default capability mappings for UAP droids and skills.
 */
export const DEFAULT_CAPABILITY_MAPPINGS = [
    {
        capability: 'typescript',
        droids: ['typescript-node-expert', 'javascript-pro'],
        skills: ['typescript-node-expert'],
        filePatterns: ['*.ts', '*.tsx', '*.mts', '*.cts'],
        taskTypes: ['task', 'feature', 'bug'],
        priority: 10,
    },
    {
        capability: 'javascript',
        droids: ['javascript-pro'],
        skills: [],
        filePatterns: ['*.js', '*.jsx', '*.mjs', '*.cjs'],
        taskTypes: ['task', 'feature', 'bug'],
        priority: 8,
    },
    {
        capability: 'cli',
        droids: ['cli-design-expert'],
        skills: ['cli-design-expert'],
        filePatterns: ['**/cli/**', '**/bin/**', '**/commands/**'],
        taskTypes: ['task', 'feature'],
        priority: 9,
    },
    {
        capability: 'security',
        droids: ['security-auditor', 'security-code-reviewer'],
        skills: [],
        filePatterns: ['**/auth/**', '**/security/**', '*.key', '*.pem'],
        taskTypes: ['bug', 'task'],
        priority: 10,
    },
    {
        capability: 'performance',
        droids: ['performance-optimizer', 'performance-reviewer'],
        skills: [],
        filePatterns: ['**/perf/**', '**/benchmark/**'],
        taskTypes: ['task', 'chore'],
        priority: 8,
    },
    {
        capability: 'documentation',
        droids: ['documentation-expert', 'documentation-accuracy-reviewer'],
        skills: [],
        filePatterns: ['*.md', '**/docs/**', 'README*', 'CHANGELOG*'],
        taskTypes: ['task', 'chore'],
        priority: 6,
    },
    {
        capability: 'code-review',
        droids: ['code-quality-guardian', 'code-quality-reviewer'],
        skills: [],
        filePatterns: ['*'],
        taskTypes: ['task', 'chore'],
        priority: 7,
    },
    {
        capability: 'testing',
        droids: ['test-coverage-reviewer', 'test-plan-writer'],
        skills: [],
        filePatterns: ['*.test.*', '*.spec.*', '**/tests/**', '**/__tests__/**'],
        taskTypes: ['task', 'bug'],
        priority: 8,
    },
    {
        capability: 'infrastructure',
        droids: [],
        skills: [],
        filePatterns: [
            '*.tf',
            '**/terraform/**',
            '**/k8s/**',
            '**/helm/**',
            'Dockerfile*',
            'docker-compose*',
        ],
        taskTypes: ['task', 'chore'],
        priority: 9,
    },
    {
        capability: 'python',
        droids: ['python-pro'],
        skills: [],
        filePatterns: ['*.py', '**/python/**'],
        taskTypes: ['task', 'feature', 'bug'],
        priority: 10,
    },
    {
        capability: 'rust',
        droids: ['rust-pro'],
        skills: [],
        filePatterns: ['*.rs', 'Cargo.toml'],
        taskTypes: ['task', 'feature', 'bug'],
        priority: 10,
    },
    {
        capability: 'go',
        droids: ['go-pro'],
        skills: [],
        filePatterns: ['*.go', 'go.mod', 'go.sum'],
        taskTypes: ['task', 'feature', 'bug'],
        priority: 10,
    },
    {
        capability: 'architecture',
        droids: ['architect-reviewer'],
        skills: [],
        filePatterns: [
            'src/types/**',
            '**/schemas/**',
            'src/index.ts',
            'docs/architecture/**',
            'docs/architecture/adr/**',
        ],
        taskTypes: ['task', 'feature', 'epic'],
        priority: 9,
    },
    {
        capability: 'product',
        droids: ['product-strategist'],
        skills: [],
        filePatterns: ['docs/product/**', '**/PRD.md', '**/RFC.md'],
        taskTypes: ['feature', 'epic', 'story'],
        priority: 7,
    },
    {
        capability: 'api-design',
        droids: ['api-designer'],
        skills: [],
        filePatterns: [
            '**/openapi*',
            '**/swagger*',
            '**/api/**/routes*',
            '**/handlers/**',
            'src/types/api.ts',
        ],
        taskTypes: ['task', 'feature'],
        priority: 9,
    },
    {
        capability: 'test-strategy',
        droids: ['test-strategist'],
        skills: [],
        filePatterns: ['vitest.config*', 'jest.config*', 'test/plans/**'],
        taskTypes: ['task', 'feature'],
        priority: 7,
    },
    {
        capability: 'qa',
        droids: ['qa-expert'],
        skills: [],
        filePatterns: ['**/__flaky__/**', 'test/**/flaky*'],
        taskTypes: ['bug', 'task'],
        priority: 7,
    },
    {
        capability: 'release',
        droids: ['release-manager'],
        skills: [],
        filePatterns: ['CHANGELOG.md', 'package.json', 'package-lock.json', '.npmrc', 'release.config*'],
        taskTypes: ['chore', 'task'],
        priority: 8,
    },
    {
        capability: 'compliance',
        droids: ['compliance-officer'],
        skills: [],
        filePatterns: ['policies/**', '.policy-tools/**', 'docs/compliance/**'],
        taskTypes: ['task', 'chore'],
        priority: 9,
    },
    {
        capability: 'incident',
        droids: ['incident-responder'],
        skills: [],
        filePatterns: ['docs/incidents/**', 'docs/runbooks/**', 'docs/postmortems/**'],
        taskTypes: ['bug', 'task'],
        priority: 10,
    },
    {
        capability: 'observability',
        droids: ['observability-engineer'],
        skills: [],
        filePatterns: [
            '**/telemetry/**',
            '**/metrics/**',
            '**/logging/**',
            '**/handlers/**',
            '**/routes/**',
        ],
        taskTypes: ['task', 'feature'],
        priority: 7,
    },
    {
        capability: 'refactoring',
        droids: ['refactoring-specialist'],
        skills: [],
        filePatterns: ['*'],
        taskTypes: ['chore', 'task'],
        priority: 6,
    },
    {
        capability: 'dependency',
        droids: ['dependency-auditor'],
        skills: [],
        filePatterns: [
            'package.json',
            'package-lock.json',
            'Cargo.toml',
            'Cargo.lock',
            'go.mod',
            'go.sum',
            'pyproject.toml',
            'requirements*.txt',
            'uv.lock',
        ],
        taskTypes: ['chore', 'task'],
        priority: 8,
    },
    {
        capability: 'accessibility',
        droids: ['accessibility-tester'],
        skills: [],
        filePatterns: ['**/components/**', '**/ui/**', '**/*.tsx', '**/*.jsx', '**/*.vue'],
        taskTypes: ['task', 'feature', 'bug'],
        priority: 7,
    },
    {
        capability: 'cost',
        droids: ['cost-engineer'],
        skills: [],
        filePatterns: ['**/terraform/**', '**/helm/**', '**/k8s/**', '**/cloudformation/**'],
        taskTypes: ['task', 'chore'],
        priority: 6,
    },
];
/**
 * Capability-based router for intelligent task and agent routing.
 */
export class CapabilityRouter {
    mappings;
    routeCache = new Map();
    cacheTtlMs = 5 * 60 * 1000;
    cacheMaxEntries = 200;
    constructor(customMappings) {
        this.mappings = customMappings || DEFAULT_CAPABILITY_MAPPINGS;
    }
    /**
     * Route a task to the best droids/skills based on task content and affected files.
     */
    routeTask(task, affectedFiles) {
        const cacheKey = this.buildRouteCacheKey(task, affectedFiles);
        const cached = this.routeCache.get(cacheKey);
        if (cached && cached.expiresAt > Date.now()) {
            return cached.result;
        }
        const matchedCapabilities = [];
        const droidScores = new Map();
        const skillScores = new Map();
        const reasons = [];
        // Match by file patterns
        if (affectedFiles && affectedFiles.length > 0) {
            for (const mapping of this.mappings) {
                for (const pattern of mapping.filePatterns) {
                    const matches = this.matchesPattern(affectedFiles, pattern);
                    if (matches.length > 0) {
                        matchedCapabilities.push(mapping.capability);
                        for (const droid of mapping.droids) {
                            const current = droidScores.get(droid) || 0;
                            droidScores.set(droid, current + mapping.priority);
                        }
                        for (const skill of mapping.skills) {
                            const current = skillScores.get(skill) || 0;
                            skillScores.set(skill, current + mapping.priority);
                        }
                        reasons.push(`Files ${matches.slice(0, 2).join(', ')} match ${mapping.capability}`);
                        break; // Only count each mapping once per task
                    }
                }
            }
        }
        // Match by task type
        for (const mapping of this.mappings) {
            if (mapping.taskTypes.includes(task.type)) {
                // Boost score slightly for type match
                for (const droid of mapping.droids) {
                    const current = droidScores.get(droid) || 0;
                    droidScores.set(droid, current + 1);
                }
            }
        }
        // Match by task title/labels keywords
        const keywords = this.extractKeywords(task);
        for (const mapping of this.mappings) {
            if (keywords.some((kw) => kw.includes(mapping.capability) || mapping.capability.includes(kw))) {
                if (!matchedCapabilities.includes(mapping.capability)) {
                    matchedCapabilities.push(mapping.capability);
                }
                for (const droid of mapping.droids) {
                    const current = droidScores.get(droid) || 0;
                    droidScores.set(droid, current + mapping.priority / 2);
                }
                reasons.push(`Keywords match ${mapping.capability}`);
            }
        }
        // Sort by score and take top recommendations
        const sortedDroids = [...droidScores.entries()]
            .sort((a, b) => b[1] - a[1])
            .map(([droid]) => droid);
        const sortedSkills = [...skillScores.entries()]
            .sort((a, b) => b[1] - a[1])
            .map(([skill]) => skill);
        // Calculate confidence
        const maxPossibleScore = this.mappings.reduce((sum, m) => sum + m.priority, 0);
        const actualScore = [...droidScores.values()].reduce((sum, s) => sum + s, 0);
        const confidence = Math.min(1, actualScore / (maxPossibleScore / 2));
        const result = {
            recommendedDroids: sortedDroids.slice(0, 3),
            recommendedSkills: sortedSkills.slice(0, 2),
            matchedCapabilities: [...new Set(matchedCapabilities)],
            confidence,
            reasoning: reasons.length > 0 ? reasons.join('; ') : 'No specific matches, using general routing',
        };
        this.routeCache.set(cacheKey, { result, expiresAt: Date.now() + this.cacheTtlMs });
        if (this.routeCache.size > this.cacheMaxEntries) {
            const oldestKey = this.routeCache.keys().next().value;
            if (oldestKey)
                this.routeCache.delete(oldestKey);
        }
        return result;
    }
    /**
     * Find the best agent for a task based on capabilities.
     */
    findBestAgent(task, availableAgents, affectedFiles) {
        if (availableAgents.length === 0)
            return null;
        const routing = this.routeTask(task, affectedFiles);
        const agentMatches = [];
        for (const agent of availableAgents) {
            const agentCapabilities = (agent.capabilities || []);
            const matchedCapabilities = agentCapabilities.filter((cap) => routing.matchedCapabilities.includes(cap));
            let score = matchedCapabilities.length * 10;
            // Boost for agents with recommended droids in their name
            if (routing.recommendedDroids.some((d) => agent.name.includes(d))) {
                score += 20;
            }
            // Boost for idle agents
            if (agent.status === 'idle') {
                score += 5;
            }
            // Penalty for agents with current tasks
            if (agent.currentTask) {
                score -= 10;
            }
            agentMatches.push({
                agent,
                matchedCapabilities,
                score,
            });
        }
        // Sort by score descending
        agentMatches.sort((a, b) => b.score - a.score);
        return agentMatches[0] || null;
    }
    /**
     * Route files to appropriate capabilities.
     */
    routeFiles(files) {
        const result = new Map();
        for (const mapping of this.mappings) {
            for (const pattern of mapping.filePatterns) {
                const matches = this.matchesPattern(files, pattern);
                if (matches.length > 0) {
                    const existing = result.get(mapping.capability) || [];
                    result.set(mapping.capability, [...new Set([...existing, ...matches])]);
                }
            }
        }
        return result;
    }
    /**
     * Get recommended parallel review droids for a set of files.
     */
    getParallelReviewDroids(files) {
        const routing = this.routeFiles(files);
        const droids = new Set();
        // Always include quality and security for any code change
        droids.add('code-quality-guardian');
        droids.add('security-auditor');
        // Add capability-specific droids
        for (const [capability] of routing) {
            const mapping = this.mappings.find((m) => m.capability === capability);
            if (mapping) {
                for (const droid of mapping.droids) {
                    droids.add(droid);
                }
            }
        }
        // Add documentation reviewer if docs changed
        if (routing.has('documentation')) {
            droids.add('documentation-expert');
        }
        // Add performance reviewer for performance-critical areas
        if (routing.has('performance') || routing.has('database')) {
            droids.add('performance-optimizer');
        }
        return [...droids];
    }
    /**
     * Match files against a glob-like pattern.
     */
    matchesPattern(files, pattern) {
        const regex = this.patternToRegex(pattern);
        return files.filter((f) => regex.test(f));
    }
    /**
     * Convert glob pattern to regex.
     */
    patternToRegex(pattern) {
        const escaped = pattern
            .replace(/[.+^${}()|[\]\\]/g, '\\$&')
            .replace(/\*\*/g, '{{GLOBSTAR}}')
            .replace(/\*/g, '[^/]*')
            .replace(/{{GLOBSTAR}}/g, '.*')
            .replace(/\?/g, '.');
        return new RegExp(`(^|/)${escaped}$`, 'i');
    }
    /**
     * Extract keywords from task for matching.
     */
    extractKeywords(task) {
        const keywords = [];
        // From title
        keywords.push(...task.title
            .toLowerCase()
            .split(/\W+/)
            .filter((w) => w.length > 2));
        // From labels
        keywords.push(...task.labels.map((l) => l.toLowerCase()));
        // From type
        keywords.push(task.type);
        return keywords;
    }
    /**
     * Add or update a capability mapping.
     */
    addMapping(mapping) {
        const existingIndex = this.mappings.findIndex((m) => m.capability === mapping.capability);
        if (existingIndex >= 0) {
            this.mappings[existingIndex] = mapping;
        }
        else {
            this.mappings.push(mapping);
        }
    }
    /**
     * Get all registered mappings.
     */
    getMappings() {
        return [...this.mappings];
    }
    buildRouteCacheKey(task, affectedFiles) {
        return JSON.stringify({
            id: task.id,
            title: task.title,
            type: task.type,
            labels: [...task.labels].sort(),
            files: (affectedFiles ?? []).slice().sort(),
        });
    }
}
/**
 * Singleton instance for global capability routing.
 */
let globalRouter = null;
export function getCapabilityRouter() {
    if (!globalRouter) {
        globalRouter = new CapabilityRouter();
    }
    return globalRouter;
}
export function setCapabilityRouter(router) {
    globalRouter = router;
}
//# sourceMappingURL=capability-router.js.map