UNPKG

bc-code-intelligence-mcp

Version:

BC Code Intelligence MCP Server - Complete Specialist Bundle with AI-driven expert consultation, seamless handoffs, and context-preserving workflows

665 lines 35.1 kB
// Streamlined tool handlers for BCKB MCP Server 1.0.2 // Map streamlined workflow types to existing workflow types function mapWorkflowType(streamlinedType) { const workflowMapping = { 'code-optimization': 'enhance-bc-app', 'architecture-review': 'review-bc-code', 'security-audit': 'review-bc-code', 'performance-analysis': 'enhance-bc-app', 'integration-design': 'enhance-bc-app', 'upgrade-planning': 'upgrade-bc-version', 'testing-strategy': 'enhance-bc-app', 'developer-onboarding': 'onboard-developer', 'pure-review': 'review-bc-code' }; return workflowMapping[streamlinedType] || streamlinedType; } // Detect if a workflow request is actually a specialist conversation request function detectSpecialistConversationRequest(workflowType, context) { const fullText = `${workflowType} ${context || ''}`.toLowerCase(); // Common conversation patterns const conversationPatterns = [ { pattern: /talk.*to.*sam|sam.*talk/i, specialist: 'sam-coder', intent: 'conversation' }, { pattern: /talk.*to.*dean|dean.*talk/i, specialist: 'dean-debug', intent: 'conversation' }, { pattern: /talk.*to.*alex|alex.*talk/i, specialist: 'alex-architect', intent: 'conversation' }, { pattern: /talk.*to.*eva|eva.*talk/i, specialist: 'eva-errors', intent: 'conversation' }, { pattern: /talk.*to.*quinn|quinn.*talk/i, specialist: 'quinn-tester', intent: 'conversation' }, { pattern: /talk.*to.*roger|roger.*talk/i, specialist: 'roger-reviewer', intent: 'conversation' }, { pattern: /talk.*to.*seth|seth.*talk/i, specialist: 'seth-security', intent: 'conversation' }, { pattern: /talk.*to.*jordan|jordan.*talk/i, specialist: 'jordan-bridge', intent: 'conversation' }, { pattern: /talk.*to.*logan|logan.*talk/i, specialist: 'logan-legacy', intent: 'conversation' }, { pattern: /talk.*to.*uma|uma.*talk/i, specialist: 'uma-ux', intent: 'conversation' }, { pattern: /talk.*to.*morgan|morgan.*talk/i, specialist: 'morgan-market', intent: 'conversation' }, { pattern: /talk.*to.*taylor|taylor.*talk/i, specialist: 'taylor-docs', intent: 'conversation' }, { pattern: /talk.*to.*maya|maya.*talk/i, specialist: 'maya-mentor', intent: 'conversation' }, { pattern: /talk.*to.*casey|casey.*talk/i, specialist: 'casey-copilot', intent: 'conversation' }, // Ask patterns { pattern: /ask.*sam|sam.*question/i, specialist: 'sam-coder', intent: 'question' }, { pattern: /ask.*dean|dean.*question/i, specialist: 'dean-debug', intent: 'question' }, { pattern: /ask.*alex|alex.*question/i, specialist: 'alex-architect', intent: 'question' }, // Specialist names in workflow type { pattern: /^sam/i, specialist: 'sam-coder', intent: 'direct-reference' }, { pattern: /^dean/i, specialist: 'dean-debug', intent: 'direct-reference' }, { pattern: /^alex/i, specialist: 'alex-architect', intent: 'direct-reference' }, { pattern: /^eva/i, specialist: 'eva-errors', intent: 'direct-reference' }, { pattern: /^quinn/i, specialist: 'quinn-tester', intent: 'direct-reference' }, { pattern: /^roger/i, specialist: 'roger-reviewer', intent: 'direct-reference' }, { pattern: /^seth/i, specialist: 'seth-security', intent: 'direct-reference' }, { pattern: /^jordan/i, specialist: 'jordan-bridge', intent: 'direct-reference' }, { pattern: /^logan/i, specialist: 'logan-legacy', intent: 'direct-reference' }, { pattern: /^uma/i, specialist: 'uma-ux', intent: 'direct-reference' }, { pattern: /^morgan/i, specialist: 'morgan-market', intent: 'direct-reference' }, { pattern: /^taylor/i, specialist: 'taylor-docs', intent: 'direct-reference' }, { pattern: /^maya/i, specialist: 'maya-mentor', intent: 'direct-reference' }, { pattern: /^casey/i, specialist: 'casey-copilot', intent: 'direct-reference' } ]; for (const { pattern, specialist, intent } of conversationPatterns) { if (pattern.test(fullText)) { return { intent, specialist }; } } return null; } export function createStreamlinedHandlers(server, services) { const { knowledgeService, codeAnalysisService, methodologyService, workflowService, layerService } = services; return { 'find_bc_knowledge': async (args) => { try { const { query, search_type = 'all', bc_version, limit = 10 } = args; // Validate required parameters if (!query) { return { isError: true, error: 'query parameter is required', content: [{ type: 'text', text: 'Error: query parameter is required' }] }; } const results = { query, search_type, results: [] }; if (search_type === 'topics' || search_type === 'all') { const topics = await knowledgeService.searchTopics({ code_context: query, // FIX: Use code_context instead of query bc_version, limit: search_type === 'topics' ? limit : Math.ceil(limit / 3) }); results.results.push({ type: 'topics', items: topics }); } if (search_type === 'specialists' || search_type === 'all') { const specialists = await knowledgeService.findSpecialistsByQuery(query); results.results.push({ type: 'specialists', items: specialists.slice(0, search_type === 'specialists' ? limit : Math.ceil(limit / 3)) }); } if (search_type === 'workflows' || search_type === 'all') { const workflows = await methodologyService.findWorkflowsByQuery(query); results.results.push({ type: 'workflows', items: workflows.slice(0, search_type === 'workflows' ? limit : Math.ceil(limit / 3)) }); } return { content: [{ type: 'text', text: JSON.stringify(results, null, 2) }] }; } catch (error) { return { isError: true, error: (error && error.message) ? error.message : 'Service error occurred', content: [{ type: 'text', text: `Error: ${(error && error.message) ? error.message : 'Service error occurred'}` }] }; } }, 'ask_bc_expert': async (args) => { try { const { question, context, preferred_specialist, autonomous_mode = false } = args; // Validate required parameters if (!question) { return { isError: true, error: 'question parameter is required', content: [{ type: 'text', text: 'Error: question parameter is required' }] }; } // Auto-detect if this is a "took over app" scenario const isOnboardingScenario = /took over|inherited|new to|understand.*app|unfamiliar/i.test(question + ' ' + (context || '')); if (isOnboardingScenario && !preferred_specialist) { // Start onboarding workflow automatically const startRequest = { workflow_type: 'onboard-developer', project_context: context || question, bc_version: 'BC22' // default }; const session = await workflowService.startWorkflow(startRequest); const guidance = await workflowService.getPhaseGuidance(session.id); return { content: [{ type: 'text', text: JSON.stringify({ response_type: 'workflow_started', workflow_id: session.id, workflow_type: 'developer_onboarding', message: 'I detected this is a new developer onboarding scenario. Starting the systematic onboarding workflow.', guidance }, null, 2) }] }; } // Normal specialist consultation const specialist = await knowledgeService.askSpecialist(question, preferred_specialist); // AUTONOMOUS MODE: Return structured action plan if (autonomous_mode) { // Extract actionable steps from consultation const actionPlan = { response_type: 'autonomous_action_plan', specialist: { id: specialist.specialist.id, name: specialist.specialist.name, expertise: specialist.specialist.expertise }, action_plan: { primary_action: specialist.consultation.response.split('\n')[0], // First line is usually the main recommendation steps: specialist.consultation.response .split('\n') .filter((line) => /^\d+\.|^-|^•/.test(line.trim())) // Extract numbered/bulleted steps .map((step) => step.trim()), required_tools: specialist.recommended_topics .filter((t) => t.domain === 'tools' || t.domain === 'methodologies') .map((t) => t.id), confidence: specialist.consultation.confidence || 0.85, blocking_issues: specialist.consultation.blocking_issues || [], alternatives: specialist.consultation.alternatives || [] }, recommended_topics: specialist.recommended_topics, next_specialist: specialist.consultation.hand_off_to || null, context: context }; return { content: [{ type: 'text', text: JSON.stringify(actionPlan, null, 2) }] }; } // INTERACTIVE MODE: Return conversational response return { content: [{ type: 'text', text: JSON.stringify({ response_type: 'specialist_consultation', specialist: { id: specialist.specialist.id, name: specialist.specialist.name, expertise: specialist.specialist.expertise }, consultation: specialist.consultation, recommended_topics: specialist.recommended_topics, context: context }, null, 2) }] }; } catch (error) { return { isError: true, error: (error && error.message) ? error.message : 'Service error occurred', content: [{ type: 'text', text: `Error: ${(error && error.message) ? error.message : 'Service error occurred'}` }] }; } }, 'analyze_al_code': async (args) => { const { code, analysis_type = 'comprehensive', operation = 'analyze', bc_version, suggest_workflows = true } = args; if (code.toLowerCase() === 'workspace') { // Workspace analysis using existing method const analysisResult = await codeAnalysisService.analyzeCode({ code_snippet: "// Workspace analysis requested", analysis_type: 'workspace_overview', suggest_topics: suggest_workflows, bc_version }); if (suggest_workflows) { // Suggest relevant workflows based on analysis const workflowSuggestions = await methodologyService.findWorkflowsByQuery('code analysis optimization'); analysisResult.suggested_workflows = workflowSuggestions; } // VALIDATE OPERATION: Return compliance issues + auto-fix suggestions if (operation === 'validate') { return { content: [{ type: 'text', text: JSON.stringify({ response_type: 'validation_report', compliance_issues: analysisResult.issues || [], auto_fix_suggestions: analysisResult.patterns ?.filter((p) => p.auto_fixable === true) .map((p) => ({ issue: p.pattern, fix_action: p.recommended_action, code_snippet: p.code_snippet, confidence: p.confidence || 0.9 })) || [], blocking_issues: analysisResult.issues?.filter((i) => i.severity === 'critical') || [], warnings: analysisResult.issues?.filter((i) => i.severity === 'warning') || [], bc_version: bc_version, analysis_type: analysis_type }, null, 2) }] }; } // SUGGEST_FIXES OPERATION: Return code transformations if (operation === 'suggest_fixes') { return { content: [{ type: 'text', text: JSON.stringify({ response_type: 'code_transformations', transformations: analysisResult.patterns ?.map((p) => ({ pattern: p.pattern, transformation: p.recommended_action, before_code: p.code_snippet, after_code: p.suggested_code || '// Auto-generation not available', impact: p.impact || 'medium', confidence: p.confidence || 0.85 })) || [], recommended_workflow: analysisResult.suggested_workflows?.[0] || null, bc_version: bc_version }, null, 2) }] }; } // ANALYZE OPERATION: Return conversational analysis return { content: [{ type: 'text', text: JSON.stringify(analysisResult, null, 2) }] }; } else { // Code snippet analysis const analysisResult = await codeAnalysisService.analyzeCode({ code_snippet: code, analysis_type, suggest_topics: suggest_workflows, bc_version }); // VALIDATE OPERATION: Return compliance issues + auto-fix suggestions if (operation === 'validate') { return { content: [{ type: 'text', text: JSON.stringify({ response_type: 'validation_report', compliance_issues: analysisResult.issues || [], auto_fix_suggestions: analysisResult.patterns ?.filter((p) => p.auto_fixable === true) .map((p) => ({ issue: p.pattern, fix_action: p.recommended_action, code_snippet: p.code_snippet, confidence: p.confidence || 0.9 })) || [], blocking_issues: analysisResult.issues?.filter((i) => i.severity === 'critical') || [], warnings: analysisResult.issues?.filter((i) => i.severity === 'warning') || [], bc_version: bc_version, analysis_type: analysis_type }, null, 2) }] }; } // SUGGEST_FIXES OPERATION: Return code transformations if (operation === 'suggest_fixes') { return { content: [{ type: 'text', text: JSON.stringify({ response_type: 'code_transformations', transformations: analysisResult.patterns ?.map((p) => ({ pattern: p.pattern, transformation: p.recommended_action, before_code: p.code_snippet, after_code: p.suggested_code || '// Auto-generation not available', impact: p.impact || 'medium', confidence: p.confidence || 0.85 })) || [], recommended_workflow: suggest_workflows ? await methodologyService.findWorkflowsByQuery('code optimization') : null, bc_version: bc_version }, null, 2) }] }; } // ANALYZE OPERATION: Return conversational analysis return { content: [{ type: 'text', text: JSON.stringify(analysisResult, null, 2) }] }; } }, 'get_bc_topic': async (args) => { const { topic_id, include_samples = true } = args; const topic = await knowledgeService.getTopic(topic_id, include_samples); return { content: [{ type: 'text', text: JSON.stringify(topic, null, 2) }] }; }, 'start_bc_workflow': async (args) => { const { workflow_type, context, bc_version, execution_mode = 'interactive', checkpoint_id, additional_info } = args; // Resume from checkpoint if provided if (checkpoint_id) { try { const session = await workflowService.resumeWorkflow(checkpoint_id); const guidance = await workflowService.getPhaseGuidance(session.id); if (execution_mode === 'autonomous') { return { content: [{ type: 'text', text: JSON.stringify({ response_type: 'workflow_next_action', workflow_id: session.id, checkpoint_id: checkpoint_id, current_phase: session.current_phase, next_action: { action_type: 'execute_phase', phase: session.current_phase, specialist: session.current_specialist, required_inputs: guidance.required_inputs || [], expected_outputs: guidance.expected_outputs || [], guidance: guidance.description }, can_proceed: !guidance.blocking_issues || guidance.blocking_issues.length === 0, blocking_issues: guidance.blocking_issues || [], progress: session.progress || 0 }, null, 2) }] }; } return { content: [{ type: 'text', text: JSON.stringify({ workflow_id: session.id, status: 'resumed', current_phase: session.current_phase, specialist: session.current_specialist, guidance }, null, 2) }] }; } catch (error) { return { isError: true, error: `Failed to resume workflow from checkpoint: ${error instanceof Error ? error.message : 'Unknown error'}`, content: [{ type: 'text', text: `Error resuming workflow: ${error instanceof Error ? error.message : 'Unknown error'}` }] }; } } // Detect if this looks like a specialist conversation request const isSpecialistRequest = detectSpecialistConversationRequest(workflow_type, context); if (isSpecialistRequest) { return { content: [{ type: 'text', text: JSON.stringify({ error: 'Workflow type appears to be a specialist conversation request', suggestion: 'Use ask_bc_expert tool instead for direct specialist conversations', detected_intent: isSpecialistRequest.intent, recommended_specialist: isSpecialistRequest.specialist, correct_usage: `ask_bc_expert({ question: "${context || workflow_type}", preferred_specialist: "${isSpecialistRequest.specialist}" })` }, null, 2) }], isError: true }; } // Map streamlined workflow type to existing workflow type const mappedWorkflowType = mapWorkflowType(workflow_type); try { const session = await workflowService.startWorkflow({ workflow_type: mappedWorkflowType, project_context: context, bc_version: bc_version || 'BC22', additional_context: additional_info }); const guidance = await workflowService.getPhaseGuidance(session.id); // AUTONOMOUS MODE: Return next action instead of interactive guidance if (execution_mode === 'autonomous') { return { content: [{ type: 'text', text: JSON.stringify({ response_type: 'workflow_next_action', workflow_id: session.id, workflow_type: workflow_type, checkpoint_id: session.id, // Use session ID as checkpoint for resumption current_phase: session.current_phase, next_action: { action_type: 'execute_phase', phase: session.current_phase, specialist: session.current_specialist, required_inputs: guidance.required_inputs || [], expected_outputs: guidance.expected_outputs || [], guidance: guidance.description, estimated_duration: guidance.estimated_duration || 'unknown' }, can_proceed: !guidance.blocking_issues || guidance.blocking_issues.length === 0, blocking_issues: guidance.blocking_issues || [], total_phases: session.total_phases || 5, progress: 0 }, null, 2) }] }; } // INTERACTIVE MODE: Return conversational workflow guidance return { content: [{ type: 'text', text: JSON.stringify({ workflow_id: session.id, workflow_type: workflow_type, // Return original type for clarity mapped_to: mappedWorkflowType, status: 'started', current_phase: session.current_phase, specialist: session.current_specialist, guidance }, null, 2) }] }; } catch (error) { // Enhanced error handling with suggestions const errorMessage = error instanceof Error ? error.message : 'Unknown error'; if (errorMessage.includes('Unknown workflow type')) { return { isError: true, error: 'Invalid workflow type', content: [{ type: 'text', text: `Error: Invalid workflow type '${workflow_type}'. Use ask_bc_expert for specialist conversations.` }] }; } return { isError: true, error: errorMessage, content: [{ type: 'text', text: `Error: ${errorMessage}` }] }; } }, 'advance_workflow': async (args) => { const { workflow_id, phase_results, next_focus, check_status_only } = args; // Validate required parameters if (!workflow_id) { return { isError: true, error: 'workflow_id parameter is required', content: [{ type: 'text', text: 'Error: workflow_id parameter is required' }] }; } try { const result = await workflowService.advancePhase({ workflow_id, phase_results, specialist_notes: next_focus, check_status_only }); return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }; } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; if (errorMessage.includes('Workflow session not found')) { return { isError: true, error: 'Workflow session not found', content: [{ type: 'text', text: `Error: Workflow session '${workflow_id}' not found. Use start_bc_workflow to create a new workflow.` }] }; } return { isError: true, error: errorMessage, content: [{ type: 'text', text: `Error: ${errorMessage}` }] }; } }, 'get_workflow_help': async (args) => { const { workflow_id, help_type = 'guidance' } = args; if (!workflow_id) { // List active workflows const activeWorkflows = await workflowService.getActiveWorkflows(); return { content: [{ type: 'text', text: JSON.stringify({ help_type: 'active_workflows', active_workflows: activeWorkflows }, null, 2) }] }; } switch (help_type) { case 'status': const status = await workflowService.getWorkflowStatus(workflow_id); return { content: [{ type: 'text', text: JSON.stringify(status, null, 2) }] }; case 'guidance': case 'next-steps': const guidance = await workflowService.getPhaseGuidance(workflow_id); return { content: [{ type: 'text', text: guidance }] }; case 'methodology': const methodology = await workflowService.getWorkflowMethodology(workflow_id); return { content: [{ type: 'text', text: JSON.stringify(methodology, null, 2) }] }; default: throw new Error(`Unknown help type: ${help_type}`); } }, 'get_bc_help': async (args) => { const { current_situation, workspace_context } = args; // Basic situation analysis using existing methods const searchResults = await knowledgeService.searchTopics({ query: current_situation, limit: 5 }); const specialists = await knowledgeService.findSpecialistsByQuery(current_situation); const workflows = await methodologyService.findWorkflowsByQuery(current_situation); // Basic analysis and suggestions const suggestions = { analysis: `Based on your situation: "${current_situation}", I've analyzed available resources.`, tools: [ { tool: 'find_bc_knowledge', reason: 'Search for specific BC topics related to your situation', usage: `find_bc_knowledge({ query: "${current_situation}" })` }, { tool: 'ask_bc_expert', reason: 'Get expert consultation with automatic specialist selection', usage: `ask_bc_expert({ question: "${current_situation}" })` } ], workflows: workflows.slice(0, 3), specialists: specialists.slice(0, 3), related_topics: searchResults, next_steps: [ 'Start with ask_bc_expert for immediate consultation', 'Use find_bc_knowledge to explore related topics', 'Consider starting a workflow if this is a complex task' ] }; return { content: [{ type: 'text', text: JSON.stringify({ situation_analysis: suggestions.analysis, recommended_tools: suggestions.tools, suggested_workflows: suggestions.workflows, available_specialists: suggestions.specialists, related_topics: suggestions.related_topics, next_steps: suggestions.next_steps }, null, 2) }] }; } }; } //# sourceMappingURL=streamlined-handlers.js.map