import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { CallToolRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, ReadResourceRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
import { readFileSync } from 'fs';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
import { setupKanbanTools } from './modules/kanban/index.js';
import { setupDevelopmentTools } from './modules/development/index.js';
import { setupWorkspaceTools } from './modules/workspace/index.js';
import { setupProjectInitTools } from './modules/project-init/index.js';
import { setupCodeIntelligenceTools } from './modules/code-intelligence/index.js';
import { setupLocalAITools } from './modules/local-ai/index.js';
import { setupDeveloperWorkflowTools } from './modules/developer-workflow/index.js';
import { setupDocumentationTools } from './modules/documentation/index.js';
import { setupDataManagementTools } from './modules/data-management/index.js';
import { setupProjectManagementTools } from './modules/project-management/index.js';
import { setupClaudeCodeIntegration } from './modules/claude-code-integration/index.js';
import { setupRepositoryTools } from './modules/repository-setup/index.js';
import { setupSecurityTools } from './modules/security/index.js';
import { setupMemoryManagementTools } from './modules/memory-management/index.js';
import { setupBusinessGuidanceTools } from './modules/business-guidance/index.js';
import { setupAgileManagementTools } from './modules/agile-management/index.js';
import { setupProductRoadmap } from './modules/product-roadmap/index.js';
import { setupADRManagementModule } from './modules/adr-management/index.js';
import { setupApprovalSystem } from './modules/approval-system/index.js';
import { MethodologyManager } from './modules/methodology-config/methodology-manager.js';
import { ConfigManager } from './config/config-manager.js';
import { setupRAGRetrieval } from './modules/rag-retrieval/index.js';
import { DashboardServer } from './web-dashboard/server.js';
import { PerformanceMonitor } from './utils/performance-monitor.js';
import { SecurityManager } from './utils/security-manager.js';
import { ErrorHandler } from './utils/error-handler.js';
import { setupPerformanceMonitoring, handlePerformanceMonitoringTool } from './modules/performance-monitoring/index.js';
import { setupWorkflowRecipes, handleWorkflowRecipeTool } from './modules/workflow-recipes/index.js';
import { setupErrorAnalysis, handleErrorAnalysisTool } from './modules/error-analysis/index.js';
// Get version from package.json
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const packageJson = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));
const VERSION = packageJson.version;
export class AtlasServer {
    server;
    configManager;
    dashboardServer;
    performanceMonitor;
    securityManager;
    errorHandler;
    agileManager;
    constructor() {
        this.configManager = new ConfigManager();
        this.performanceMonitor = PerformanceMonitor.getInstance();
        this.securityManager = SecurityManager.getInstance();
        this.errorHandler = new ErrorHandler();
        this.server = new Server({
            name: 'atlas',
            version: VERSION,
        }, {
            capabilities: {
                resources: {},
                tools: {},
                prompts: {},
            },
        });
        this.setupHandlers();
    }
    initializeDashboard() {
        // Dashboard will be initialized after config is loaded in registerModules
    }
    setupHandlers() {
        this.server.setRequestHandler(ListResourcesRequestSchema, async () => ({
            resources: [
                {
                    uri: 'atlas://kanban/boards',
                    name: 'Kanban Boards',
                    description: 'List of all kanban boards in the project',
                    mimeType: 'application/json',
                },
                {
                    uri: 'atlas://docs/templates',
                    name: 'Documentation Templates',
                    description: 'Available documentation templates',
                    mimeType: 'application/json',
                },
                {
                    uri: 'atlas://project/status',
                    name: 'Project Status',
                    description: 'Current project configuration and status',
                    mimeType: 'application/json',
                },
            ],
        }));
        this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
            const { uri } = request.params;
            switch (uri) {
                case 'atlas://kanban/boards':
                    return {
                        contents: [
                            {
                                uri,
                                mimeType: 'application/json',
                                text: JSON.stringify({ boards: [] }, null, 2),
                            },
                        ],
                    };
                case 'atlas://docs/templates':
                    return {
                        contents: [
                            {
                                uri,
                                mimeType: 'application/json',
                                text: JSON.stringify({
                                    templates: [
                                        'README',
                                        'CONTRIBUTING',
                                        'ARCHITECTURE',
                                        'API_DOCS',
                                    ],
                                }, null, 2),
                            },
                        ],
                    };
                case 'atlas://project/status':
                    return {
                        contents: [
                            {
                                uri,
                                mimeType: 'application/json',
                                text: JSON.stringify({
                                    initialized: false,
                                    modules: {
                                        kanban: { enabled: true },
                                        documentation: { enabled: true },
                                        development: { enabled: true },
                                    },
                                }, null, 2),
                            },
                        ],
                    };
                case 'atlas://requirements':
                    const { handleProductRequirementsResource } = await import('./modules/product-requirements/index.js');
                    return await handleProductRequirementsResource(uri);
                default:
                    throw new Error(`Unknown resource: ${uri}`);
            }
        });
        // Tools will be registered dynamically by modules
        // Tools will be registered dynamically by modules
        this.server.setRequestHandler(ListPromptsRequestSchema, async () => ({
            prompts: [
                {
                    name: 'startup_pitch',
                    description: 'Generate a startup pitch deck outline',
                },
                {
                    name: 'architecture_review',
                    description: 'Review and suggest improvements for system architecture',
                },
                {
                    name: 'sprint_planning',
                    description: 'Plan an agile sprint with tasks and priorities',
                },
            ],
        }));
        this.server.setRequestHandler(GetPromptRequestSchema, async (request) => {
            const { name } = request.params;
            switch (name) {
                case 'startup_pitch':
                    return {
                        prompt: {
                            name: 'startup_pitch',
                            description: 'Generate a startup pitch deck outline',
                            messages: [
                                {
                                    role: 'user',
                                    content: {
                                        type: 'text',
                                        text: 'Help me create a compelling startup pitch deck outline. I need sections for problem, solution, market opportunity, business model, competition, team, and funding ask.',
                                    },
                                },
                            ],
                        },
                    };
                case 'architecture_review':
                    return {
                        prompt: {
                            name: 'architecture_review',
                            description: 'Review and suggest improvements for system architecture',
                            messages: [
                                {
                                    role: 'user',
                                    content: {
                                        type: 'text',
                                        text: 'Please review the system architecture and suggest improvements for scalability, security, and maintainability.',
                                    },
                                },
                            ],
                        },
                    };
                case 'sprint_planning':
                    return {
                        prompt: {
                            name: 'sprint_planning',
                            description: 'Plan an agile sprint with tasks and priorities',
                            messages: [
                                {
                                    role: 'user',
                                    content: {
                                        type: 'text',
                                        text: 'Help me plan a 2-week sprint. I need to break down features into tasks, estimate story points, and prioritize based on business value.',
                                    },
                                },
                            ],
                        },
                    };
                default:
                    throw new Error(`Unknown prompt: ${name}`);
            }
        });
    }
    async registerModules() {
        // Create a composite handler for tools
        const moduleHandlers = [];
        // Store the original setRequestHandler
        const originalSetRequestHandler = this.server.setRequestHandler.bind(this.server);
        // Override setRequestHandler to intercept module handlers
        this.server.setRequestHandler = (schema, handler) => {
            if (schema === CallToolRequestSchema) {
                // Store the handler instead of registering it
                moduleHandlers.push(handler);
                return;
            }
            // For other schemas, use the original handler
            return originalSetRequestHandler(schema, handler);
        };
        // Load configuration
        await this.configManager.load();
        // Register modules based on configuration first
        const enabledModules = [];
        if (this.configManager.isModuleEnabled('kanban')) {
            const kanbanModule = await setupKanbanTools(this.server, this.configManager);
            enabledModules.push(kanbanModule);
        }
        if (this.configManager.isModuleEnabled('development')) {
            const devModule = await setupDevelopmentTools(this.server, this.configManager);
            enabledModules.push(devModule);
        }
        // Always enable workspace for multi-repo mode
        if (this.configManager.isMultiRepo()) {
            const workspaceModule = await setupWorkspaceTools(this.server, this.configManager);
            enabledModules.push(workspaceModule);
        }
        // Project initialization is always available
        const projectInitModule = await setupProjectInitTools(this.server, this.configManager);
        enabledModules.push(projectInitModule);
        // Code intelligence module (always enabled for local code analysis)
        const codeIntelModule = await setupCodeIntelligenceTools(this.server, this.configManager);
        enabledModules.push(codeIntelModule);
        // Local AI module for embeddings and semantic search
        const localAIModule = await setupLocalAITools(this.server, this.configManager);
        enabledModules.push(localAIModule);
        // Developer workflow module for TDD and git integration
        const devWorkflowModule = await setupDeveloperWorkflowTools(this.server, this.configManager);
        enabledModules.push(devWorkflowModule);
        // Documentation module - always saves to user's project
        if (this.configManager.isModuleEnabled('documentation')) {
            const docModule = await setupDocumentationTools(this.server, this.configManager);
            enabledModules.push(docModule);
        }
        // Data management module - always enabled for export/import
        const dataModule = await setupDataManagementTools(this.server, this.configManager);
        enabledModules.push(dataModule);
        // Agent orchestration module - always enabled for sub-agent conversations
        // const agentModule = await setupAgentOrchestrationTools(this.server, this.configManager);
        // enabledModules.push(agentModule);
        // Project management module - always enabled for init/status
        const projectMgmtModule = await setupProjectManagementTools(this.server, this.configManager);
        enabledModules.push(projectMgmtModule);
        // Claude Code integration - always enabled for seamless experience
        const claudeCodeModule = await setupClaudeCodeIntegration(this.server, this.configManager);
        enabledModules.push(claudeCodeModule);
        // Repository setup tools - always enabled for Git best practices
        const repoModule = await setupRepositoryTools(this.server, this.configManager);
        enabledModules.push(repoModule);
        // Security tools - always enabled for local security scanning
        const securityModule = await setupSecurityTools(this.server, this.configManager);
        enabledModules.push(securityModule);
        // Memory management - always enabled for project memory and context
        const memoryModule = await setupMemoryManagementTools(this.server, this.configManager);
        enabledModules.push(memoryModule);
        // Bootstrap tools - always enabled for better onboarding
        const { setupBootstrapModule } = await import('./modules/bootstrap/index.js');
        const bootstrapModule = await setupBootstrapModule(this.server);
        enabledModules.push({ tools: [], resources: [] }); // Bootstrap doesn't return standard module format
        // Deprecation management - always enabled for safe upgrades
        const { setupDeprecationTools } = await import('./modules/deprecation/index.js');
        const deprecationModule = await setupDeprecationTools(this.server, this.configManager);
        enabledModules.push(deprecationModule);
        // Issue tracking - always enabled for bug/feature tracking
        const { setupIssueTrackingTools } = await import('./modules/issue-tracking/index.js');
        const issueTrackingModule = await setupIssueTrackingTools(this.server, this.configManager);
        enabledModules.push(issueTrackingModule);
        // Process automation - always enabled for workflow automation
        const { setupProcessAutomation } = await import('./modules/process-automation/index.js');
        const processAutomationModule = await setupProcessAutomation(this.server, this.configManager);
        enabledModules.push(processAutomationModule);
        // Business guidance - enabled if module is configured
        if (this.configManager.isModuleEnabled('business')) {
            const businessModule = await setupBusinessGuidanceTools(this.server, this.configManager);
            enabledModules.push(businessModule);
        }
        // Agile management - enabled if module is configured
        if (this.configManager.isModuleEnabled('agile')) {
            const agileModule = await setupAgileManagementTools(this.server, this.configManager);
            this.agileManager = agileModule.agileManager; // Store the manager instance
            enabledModules.push(agileModule);
        }
        // Product requirements - enabled if module is configured
        if (this.configManager.isModuleEnabled('product-requirements')) {
            const { setupProductRequirements } = await import('./modules/product-requirements/index.js');
            const productRequirementsModule = await setupProductRequirements(this.server);
            enabledModules.push(productRequirementsModule);
        }
        // Product roadmap - enabled if module is configured
        if (this.configManager.isModuleEnabled('product-roadmap')) {
            const roadmapModule = await setupProductRoadmap(this.server, this.configManager);
            enabledModules.push(roadmapModule);
        }
        // ADR management - enabled if module is configured
        if (this.configManager.isModuleEnabled('adr-management')) {
            const adrModule = await setupADRManagementModule(this.server, this.configManager);
            enabledModules.push(adrModule);
        }
        // Code analysis module - enabled if configured
        if (this.configManager.isModuleEnabled('code-analysis')) {
            const { setupCodeAnalysisTools } = await import('./modules/code-analysis/index.js');
            const codeAnalysisModule = await setupCodeAnalysisTools(this.server, this.configManager);
            enabledModules.push(codeAnalysisModule);
        }
        // Testing framework module - enabled if configured
        if (this.configManager.isModuleEnabled('testing-framework')) {
            const { setupTestingFrameworkTools } = await import('./modules/testing-framework/index.js');
            const testingFrameworkModule = await setupTestingFrameworkTools(this.server, this.configManager);
            enabledModules.push(testingFrameworkModule);
        }
        // Deployment and migration management - enabled if configured
        if (this.configManager.isModuleEnabled('deployment-management')) {
            const { setupDeploymentTools } = await import('./modules/deployment-management/index.js');
            const deploymentModule = await setupDeploymentTools(this.server, this.configManager);
            enabledModules.push(deploymentModule);
        }
        // Git workflow module - enabled if configured
        if (this.configManager.isModuleEnabled('git-workflow')) {
            const { setupGitWorkflowTools } = await import('./modules/git-workflow/index.js');
            const gitWorkflowModule = await setupGitWorkflowTools(this.server, this.configManager);
            enabledModules.push(gitWorkflowModule);
        }
        // Task orchestration module - enabled if configured
        if (this.configManager.isModuleEnabled('task-orchestration')) {
            const { setupTaskOrchestrationTools } = await import('./modules/task-orchestration/index.js');
            const taskOrchestrationModule = await setupTaskOrchestrationTools(this.server, this.configManager);
            enabledModules.push(taskOrchestrationModule);
        }
        // RAG retrieval module - always enabled for semantic search
        const ragModule = await setupRAGRetrieval(this.server, this.configManager);
        enabledModules.push(ragModule);
        // Performance monitoring module - always enabled for system metrics
        const performanceModule = await setupPerformanceMonitoring(this.server);
        enabledModules.push(performanceModule);
        // Workflow recipes module - always enabled for process automation
        const workflowModule = await setupWorkflowRecipes(this.server);
        enabledModules.push(workflowModule);
        // Error analysis module - always enabled for error tracking
        const errorAnalysisModule = await setupErrorAnalysis(this.server);
        enabledModules.push(errorAnalysisModule);
        // Bootstrap module - enabled if configured
        if (this.configManager.isModuleEnabled('bootstrap')) {
            const { setupBootstrapModule } = await import('./modules/bootstrap/index.js');
            const bootstrapModule = await setupBootstrapModule(this.server);
            enabledModules.push(bootstrapModule);
        }
        // Approval system - always enabled for safety
        const approvalModule = await setupApprovalSystem(this.server, this.configManager);
        enabledModules.push(approvalModule);
        // Methodology manager - initialize but don't add tools directly
        const methodologyManager = new MethodologyManager(this.configManager);
        await methodologyManager.init();
        // Initialize dashboard server after all modules are loaded
        if (this.configManager.isDashboardEnabled()) {
            await this.startDashboardServer();
        }
        // Register additional tools from enabled modules
        const allTools = enabledModules.flatMap(module => module.tools || []);
        // Update the tools list handler
        this.server.setRequestHandler(ListToolsRequestSchema, async () => {
            const baseTools = await this.getBaseTools();
            return {
                tools: [...baseTools, ...allTools],
            };
        });
        // Restore original setRequestHandler
        this.server.setRequestHandler = originalSetRequestHandler;
        // Now create a single composite handler for all tools
        this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
            const { name } = request.params;
            // Handle enterprise tools directly
            if (name.startsWith('get_system_metrics') ||
                name.startsWith('get_tool_metrics') ||
                name.startsWith('generate_performance_alerts') ||
                name.startsWith('export_performance_metrics') ||
                name.startsWith('record_quality_evaluation') ||
                name.startsWith('get_quality_metrics')) {
                return await handlePerformanceMonitoringTool(name, request.params.arguments);
            }
            if (name.startsWith('list_workflow_recipes') ||
                name.startsWith('get_workflow_recipe') ||
                name.startsWith('execute_workflow_recipe') ||
                name.startsWith('create_workflow_recipe') ||
                name.startsWith('validate_workflow_step')) {
                return await handleWorkflowRecipeTool(name, request.params.arguments);
            }
            if (name.startsWith('get_error_details') ||
                name.startsWith('analyze_error_patterns') ||
                name.startsWith('get_error_timeline') ||
                name.startsWith('generate_error_report') ||
                name.startsWith('resolve_error_suggestion') ||
                name.startsWith('simulate_error_recovery')) {
                return await handleErrorAnalysisTool(name, request.params.arguments);
            }
            // Product requirements tools
            if (name.startsWith('create_requirement') ||
                name.startsWith('list_requirements') ||
                name.startsWith('get_requirement') ||
                name.startsWith('update_requirement') ||
                name.startsWith('delete_requirement') ||
                name.startsWith('search_requirements') ||
                name.startsWith('link_requirement_to_story') ||
                name.startsWith('update_implementation_status') ||
                name.startsWith('generate_requirements_report')) {
                const { handleProductRequirementsTool } = await import('./modules/product-requirements/index.js');
                return await handleProductRequirementsTool(name, request.params.arguments);
            }
            // Security tools are handled by the security module's own handler
            // (already registered in setupSecurityTools)
            // Try each module handler in order
            for (const handler of moduleHandlers) {
                try {
                    const result = await handler(request);
                    // If the handler returned a valid result, use it
                    if (result && result !== null) {
                        return result;
                    }
                }
                catch (error) {
                    // If the handler threw an error, it might be because it doesn't handle this tool
                    // Continue to the next handler
                    continue;
                }
            }
            // If no module handled it, try the main server handler
            return this.handleToolCall(request);
        });
    }
    async handleToolCall(request) {
        const { name, arguments: args } = request.params;
        if (!args) {
            throw new Error('No arguments provided');
        }
        switch (name) {
            case 'init_project': {
                const { projectName, projectType } = args;
                return {
                    content: [
                        {
                            type: 'text',
                            text: `Project "${projectName}" initialized as ${projectType} startup project.`,
                        },
                    ],
                };
            }
            case 'create_board': {
                const { name: boardName, columns } = args;
                return {
                    content: [
                        {
                            type: 'text',
                            text: `Kanban board "${boardName}" created with columns: ${columns?.join(', ') || 'default columns'}`,
                        },
                    ],
                };
            }
            case 'add_task': {
                const { title, boardName, column } = args;
                return {
                    content: [
                        {
                            type: 'text',
                            text: `Task "${title}" added to ${boardName} board in ${column || 'Backlog'} column`,
                        },
                    ],
                };
            }
            case 'generate_readme': {
                const { projectName } = args;
                return {
                    content: [
                        {
                            type: 'text',
                            text: `README.md generated for ${projectName}`,
                        },
                    ],
                };
            }
            case 'setup_repository': {
                const { platform } = args;
                return {
                    content: [
                        {
                            type: 'text',
                            text: `Repository configured for ${platform || 'github'} with CI/CD and best practices`,
                        },
                    ],
                };
            }
            default:
                throw new Error(`Unknown tool: ${name}`);
        }
    }
    async getBaseTools() {
        return [
            // Project initialization
            {
                name: 'init_project',
                description: 'Initialize a new startup project with best practices',
                inputSchema: {
                    type: 'object',
                    properties: {
                        projectName: { type: 'string', description: 'Name of the project' },
                        projectType: {
                            type: 'string',
                            enum: ['saas', 'marketplace', 'ai-tool', 'mobile-app', 'custom'],
                            description: 'Type of startup project'
                        },
                        includeClaudeConfig: { type: 'boolean', default: true },
                    },
                    required: ['projectName', 'projectType'],
                },
            },
            // Documentation tools
            {
                name: 'generate_readme',
                description: 'Generate a professional README.md for the project',
                inputSchema: {
                    type: 'object',
                    properties: {
                        projectName: { type: 'string' },
                        description: { type: 'string' },
                        features: { type: 'array', items: { type: 'string' } },
                        techStack: { type: 'array', items: { type: 'string' } },
                    },
                    required: ['projectName', 'description'],
                },
            },
            // Repository setup
            {
                name: 'setup_repository',
                description: 'Set up repository with CI/CD and best practices',
                inputSchema: {
                    type: 'object',
                    properties: {
                        platform: {
                            type: 'string',
                            enum: ['github', 'gitlab', 'bitbucket'],
                            default: 'github'
                        },
                        includeCI: { type: 'boolean', default: true },
                        includeLinting: { type: 'boolean', default: true },
                        includePreCommit: { type: 'boolean', default: true },
                    },
                },
            },
        ];
    }
    async startDashboardServer() {
        try {
            const dashboardConfig = this.configManager.getDashboardConfig();
            this.dashboardServer = new DashboardServer(dashboardConfig, this.performanceMonitor, this.securityManager, this.errorHandler, this.agileManager);
            await this.dashboardServer.start();
        }
        catch (error) {
            console.error('❌ Failed to start dashboard server:', error.message);
            console.error('💡 Dashboard will be disabled. Check port availability and configuration.');
        }
    }
    async stopDashboardServer() {
        if (this.dashboardServer) {
            await this.dashboardServer.stop();
            this.dashboardServer = undefined;
        }
    }
    async run() {
        // Register modules before starting the server
        await this.registerModules();
        const transport = new StdioServerTransport();
        await this.server.connect(transport);
        console.error(`Atlas MCP Server v${VERSION} running...`);
        // Show dashboard URL if available
        if (this.dashboardServer) {
            console.error(`📊 Atlas Dashboard: ${this.dashboardServer.getUrl()}`);
        }
    }
    async connectTransport(transport) {
        // Register modules before connecting
        await this.registerModules();
        // Connect to the provided transport
        await this.server.connect(transport);
        // Show dashboard URL if available
        if (this.dashboardServer) {
            console.error(`📊 Atlas Dashboard: ${this.dashboardServer.getUrl()}`);
        }
    }
}
//# sourceMappingURL=server.js.map