@boundless-oss/atlas
Version:
Atlas - MCP Server for comprehensive startup project management
552 lines (533 loc) • 17.7 kB
text/typescript
/**
* Workflow Recipes
* Implements MCP Design Guide Section 3.3 principles for orchestrating complex workflows
*/
export interface WorkflowStep {
step: number;
action: string;
tool: string;
parameters?: Record<string, any>;
validation: string;
onFailure: string;
notes?: string;
}
export interface WorkflowRecipe {
name: string;
description: string;
category: 'development' | 'deployment' | 'security' | 'planning' | 'quality';
prerequisites: string[];
steps: WorkflowStep[];
successCriteria: string[];
rollbackProcedure?: string[];
}
/**
* Critical workflow recipes for enterprise software development
*/
export const WORKFLOW_RECIPES: Record<string, WorkflowRecipe> = {
FEATURE_DEVELOPMENT: {
name: 'Complete Feature Development',
description: 'End-to-end workflow for implementing a new feature following TDD and best practices',
category: 'development',
prerequisites: [
'Atlas project is initialized',
'Feature requirements are defined',
'Acceptance criteria are documented',
'Development environment is set up'
],
steps: [
{
step: 1,
action: 'Initiate TDD Session',
tool: 'start_tdd_session',
parameters: {
featureName: '${FEATURE_NAME}',
description: '${FEATURE_DESCRIPTION}'
},
validation: 'TDD session is active and tracking is enabled',
onFailure: 'Cannot proceed without TDD enforcement. Check project configuration.',
notes: 'This establishes the TDD workflow and ensures test-first development'
},
{
step: 2,
action: 'Create Feature Structure',
tool: 'create_feature',
parameters: {
name: '${FEATURE_NAME}',
description: '${FEATURE_DESCRIPTION}'
},
validation: 'Feature is created and TDD reminder is displayed',
onFailure: 'Check feature name for conflicts or invalid characters'
},
{
step: 3,
action: 'Write First Failing Test',
tool: 'write_test',
parameters: {
testName: '${FEATURE_NAME}_basic_functionality',
testType: 'unit',
description: 'Test the core functionality of ${FEATURE_NAME}'
},
validation: 'Test is written and fails as expected (RED phase)',
onFailure: 'Review test logic and ensure it properly validates the expected behavior',
notes: 'Start with the simplest test case that validates core functionality'
},
{
step: 4,
action: 'Implement Minimum Code',
tool: 'implement_feature_code',
parameters: {
featureName: '${FEATURE_NAME}',
implementation: 'minimum'
},
validation: 'Previously failing test now passes (GREEN phase)',
onFailure: 'Review implementation and test logic. Ensure minimal code to pass test.'
},
{
step: 5,
action: 'Refactor Implementation',
tool: 'refactor_code',
parameters: {
featureName: '${FEATURE_NAME}',
focus: 'code_quality'
},
validation: 'All tests still pass after refactoring (REFACTOR phase)',
onFailure: 'Revert refactoring and identify which change broke tests'
},
{
step: 6,
action: 'Add Edge Case Tests',
tool: 'write_test',
parameters: {
testName: '${FEATURE_NAME}_edge_cases',
testType: 'unit',
description: 'Test edge cases and error conditions'
},
validation: 'Edge case tests are failing as expected',
onFailure: 'Review edge cases and ensure tests cover boundary conditions'
},
{
step: 7,
action: 'Implement Edge Case Handling',
tool: 'implement_feature_code',
parameters: {
featureName: '${FEATURE_NAME}',
implementation: 'edge_cases'
},
validation: 'All tests including edge cases now pass',
onFailure: 'Review edge case implementation and error handling logic'
},
{
step: 8,
action: 'Run Full Test Suite',
tool: 'run_tests',
parameters: {
scope: 'all',
coverage: true
},
validation: 'All tests pass and coverage meets minimum requirements (80%)',
onFailure: 'Fix failing tests before proceeding. Address coverage gaps.',
notes: 'Ensure no regressions in existing functionality'
},
{
step: 9,
action: 'Security Scan',
tool: 'perform_security_scan',
parameters: {
scope: 'feature',
featureName: '${FEATURE_NAME}'
},
validation: 'No critical security vulnerabilities found',
onFailure: 'Address security issues before proceeding to code review'
},
{
step: 10,
action: 'Store Implementation Context',
tool: 'store_memory',
parameters: {
content: 'Implemented ${FEATURE_NAME}: ${FEATURE_DESCRIPTION}',
type: 'feature-implementation',
tags: ['${FEATURE_NAME}', 'completed', 'tdd']
},
validation: 'Feature context is stored for future reference',
onFailure: 'Manual documentation may be needed if memory storage fails'
}
],
successCriteria: [
'All tests pass including new feature tests',
'Code coverage is at least 80%',
'No security vulnerabilities introduced',
'TDD workflow was followed throughout',
'Feature context is documented'
],
rollbackProcedure: [
'Revert code changes using version control',
'Remove failing tests if they cannot be fixed',
'Update feature status to indicate rollback',
'Document reasons for rollback in project memory'
]
},
SPRINT_PLANNING: {
name: 'Comprehensive Sprint Planning',
description: 'Complete sprint planning workflow from goal setting to capacity allocation',
category: 'planning',
prerequisites: [
'Product backlog exists with prioritized stories',
'Team velocity data is available',
'Team capacity is known',
'Sprint duration is defined'
],
steps: [
{
step: 1,
action: 'Review Product Backlog',
tool: 'list_agile_backlog',
parameters: {
status: 'todo',
priority: 'high'
},
validation: 'Backlog items are visible and prioritized',
onFailure: 'Create or prioritize backlog items before sprint planning'
},
{
step: 2,
action: 'Check Team Velocity',
tool: 'generate_velocity_report',
parameters: {
lastNSprints: 3
},
validation: 'Team velocity data is available for capacity planning',
onFailure: 'Use estimated capacity if velocity data is unavailable'
},
{
step: 3,
action: 'Create Sprint Interactively',
tool: 'create_sprint_interactive',
parameters: {
action: 'start'
},
validation: 'Interactive sprint planning wizard is initiated',
onFailure: 'Use manual sprint creation if wizard fails'
},
{
step: 4,
action: 'Continue Sprint Planning',
tool: 'create_sprint_interactive',
parameters: {
action: 'continue',
workflowId: '${WORKFLOW_ID}',
response: '${USER_RESPONSES}'
},
validation: 'Sprint is created with proper capacity and goal definition',
onFailure: 'Review capacity calculations and goal clarity'
},
{
step: 5,
action: 'Conduct Planning Session',
tool: 'conduct_sprint_planning',
parameters: {
sprintId: '${SPRINT_ID}',
attendees: '${TEAM_MEMBERS}',
capacity: '${TEAM_CAPACITY}'
},
validation: 'Planning session is documented with commitments',
onFailure: 'Reschedule planning session with full team attendance'
},
{
step: 6,
action: 'Generate Sprint Status',
tool: 'get_sprint_status',
parameters: {
sprintId: '${SPRINT_ID}'
},
validation: 'Sprint status shows proper setup and ready state',
onFailure: 'Review sprint configuration and fix any issues'
}
],
successCriteria: [
'Sprint has clear, measurable goal',
'Team capacity is realistic and agreed upon',
'Story selection aligns with sprint goal',
'All team members understand commitments',
'Sprint tracking is properly set up'
]
},
SECURITY_REVIEW: {
name: 'Comprehensive Security Review',
description: 'Complete security assessment workflow for code and dependencies',
category: 'security',
prerequisites: [
'Code is ready for security review',
'Dependencies are up to date',
'Security scanning tools are configured'
],
steps: [
{
step: 1,
action: 'Scan for Hardcoded Secrets',
tool: 'scan_for_secrets',
parameters: {
scope: 'all-files',
includeComments: true
},
validation: 'No hardcoded secrets found in codebase',
onFailure: 'Remove or secure any found secrets before proceeding'
},
{
step: 2,
action: 'Perform Vulnerability Scan',
tool: 'check_vulnerabilities',
parameters: {
includeDepth: 'deep',
checkDependencies: true
},
validation: 'No critical vulnerabilities found',
onFailure: 'Address critical vulnerabilities before approval'
},
{
step: 3,
action: 'Run Security Analysis',
tool: 'perform_security_scan',
parameters: {
scope: 'full',
includeVulnerabilities: true,
includeDependencies: true
},
validation: 'Security scan passes with acceptable risk level',
onFailure: 'Review and address security findings'
},
{
step: 4,
action: 'Check Data Access Patterns',
tool: 'check_data_access',
parameters: {
scope: 'all',
validatePermissions: true
},
validation: 'Data access follows least privilege principle',
onFailure: 'Review and restrict data access permissions'
},
{
step: 5,
action: 'Generate Security Report',
tool: 'generate_security_report',
parameters: {
includeRecommendations: true,
format: 'detailed'
},
validation: 'Comprehensive security report is generated',
onFailure: 'Manual security documentation may be required'
}
],
successCriteria: [
'No hardcoded secrets in codebase',
'No critical security vulnerabilities',
'Dependencies are secure and up to date',
'Data access follows security best practices',
'Security report documents current state'
]
},
DEPLOYMENT_PREPARATION: {
name: 'Pre-Deployment Verification',
description: 'Complete checklist and verification before production deployment',
category: 'deployment',
prerequisites: [
'All features are implemented and tested',
'Security review is completed',
'Performance testing is done',
'Deployment pipeline is configured'
],
steps: [
{
step: 1,
action: 'Run Complete Test Suite',
tool: 'run_tests',
parameters: {
scope: 'all',
coverage: true,
includeIntegration: true
},
validation: 'All tests pass with 90%+ coverage',
onFailure: 'Fix failing tests and improve coverage before deployment'
},
{
step: 2,
action: 'Final Security Scan',
tool: 'perform_security_scan',
parameters: {
scope: 'deployment',
includeVulnerabilities: true
},
validation: 'No security issues found',
onFailure: 'Address security concerns before deployment'
},
{
step: 3,
action: 'Verify Configuration',
tool: 'configure_security_settings',
parameters: {
environment: 'production',
validate: true
},
validation: 'Production configuration is secure and complete',
onFailure: 'Fix configuration issues before deployment'
},
{
step: 4,
action: 'Document Deployment',
tool: 'store_memory',
parameters: {
content: 'Deployment ${VERSION} prepared: ${DEPLOYMENT_NOTES}',
type: 'deployment-preparation',
tags: ['deployment', '${VERSION}', 'production']
},
validation: 'Deployment preparation is documented',
onFailure: 'Manual documentation of deployment preparation required'
}
],
successCriteria: [
'All tests pass with high coverage',
'Security scan shows no critical issues',
'Configuration is validated for production',
'Deployment is properly documented',
'Rollback plan is prepared'
]
},
CODE_QUALITY_REVIEW: {
name: 'Code Quality Assessment',
description: 'Comprehensive code quality review and improvement workflow',
category: 'quality',
prerequisites: [
'Code is ready for review',
'Tests are written and passing',
'Documentation is updated'
],
steps: [
{
step: 1,
action: 'Analyze Code Context',
tool: 'analyze_code_context',
parameters: {
scope: 'all',
includeComplexity: true
},
validation: 'Code analysis provides quality metrics',
onFailure: 'Manual code review may be required'
},
{
step: 2,
action: 'Check Test Coverage',
tool: 'analyze_test_coverage',
parameters: {
includeUncovered: true,
threshold: 80
},
validation: 'Test coverage meets or exceeds threshold',
onFailure: 'Add tests for uncovered code paths'
},
{
step: 3,
action: 'Run Quality Tests',
tool: 'run_tests',
parameters: {
scope: 'quality',
includePerformance: true
},
validation: 'All quality tests pass',
onFailure: 'Address performance or quality issues'
},
{
step: 4,
action: 'Track Test Results',
tool: 'track_test_results',
parameters: {
includeMetrics: true,
generateReport: true
},
validation: 'Test results are tracked and reported',
onFailure: 'Manual tracking of test results required'
}
],
successCriteria: [
'Code complexity is within acceptable limits',
'Test coverage meets minimum requirements',
'Performance tests pass',
'Code follows established patterns and conventions'
]
}
};
/**
* Get workflow recipe by name
*/
export function getWorkflowRecipe(name: string): WorkflowRecipe | null {
return WORKFLOW_RECIPES[name] || null;
}
/**
* Get workflows by category
*/
export function getWorkflowsByCategory(category: WorkflowRecipe['category']): WorkflowRecipe[] {
return Object.values(WORKFLOW_RECIPES).filter(recipe => recipe.category === category);
}
/**
* Format workflow recipe for prompt inclusion
*/
export function formatWorkflowForPrompt(recipe: WorkflowRecipe): string {
let formatted = `## ${recipe.name}\n\n`;
formatted += `**Description:** ${recipe.description}\n\n`;
if (recipe.prerequisites.length > 0) {
formatted += `**Prerequisites:**\n`;
recipe.prerequisites.forEach(prereq => {
formatted += `- ${prereq}\n`;
});
formatted += '\n';
}
formatted += `**Steps (MUST be followed in exact order):**\n\n`;
recipe.steps.forEach(step => {
formatted += `**Step ${step.step}: ${step.action}**\n`;
formatted += `- Tool: \`${step.tool}\`\n`;
if (step.parameters) {
formatted += `- Parameters: \`${JSON.stringify(step.parameters)}\`\n`;
}
formatted += `- Validation: ${step.validation}\n`;
formatted += `- On Failure: ${step.onFailure}\n`;
if (step.notes) {
formatted += `- Notes: ${step.notes}\n`;
}
formatted += '\n';
});
formatted += `**Success Criteria:**\n`;
recipe.successCriteria.forEach(criteria => {
formatted += `- ${criteria}\n`;
});
if (recipe.rollbackProcedure) {
formatted += `\n**Rollback Procedure:**\n`;
recipe.rollbackProcedure.forEach(step => {
formatted += `- ${step}\n`;
});
}
return formatted;
}
/**
* Find applicable workflows based on user intent
*/
export function findApplicableWorkflows(userRequest: string): WorkflowRecipe[] {
const request = userRequest.toLowerCase();
const applicable: WorkflowRecipe[] = [];
// Keywords to workflow mapping
const workflowKeywords: Record<string, string[]> = {
FEATURE_DEVELOPMENT: ['implement', 'feature', 'develop', 'code', 'tdd', 'build'],
SPRINT_PLANNING: ['sprint', 'plan', 'planning', 'capacity', 'backlog'],
SECURITY_REVIEW: ['security', 'scan', 'vulnerability', 'secure', 'review'],
DEPLOYMENT_PREPARATION: ['deploy', 'deployment', 'production', 'release'],
CODE_QUALITY_REVIEW: ['quality', 'review', 'coverage', 'test', 'analyze']
};
for (const [workflowName, keywords] of Object.entries(workflowKeywords)) {
const hasKeyword = keywords.some(keyword => request.includes(keyword));
if (hasKeyword) {
const recipe = WORKFLOW_RECIPES[workflowName];
if (recipe) {
applicable.push(recipe);
}
}
}
return applicable;
}