UNPKG

@boundless-oss/atlas

Version:

Atlas - MCP Server for comprehensive startup project management

553 lines (489 loc) 21.4 kB
export class RoadmapWizard { roadmapManager; prioritizationEngine; wizardStates = new Map(); constructor(roadmapManager, prioritizationEngine) { this.roadmapManager = roadmapManager; this.prioritizationEngine = prioritizationEngine; } async startRoadmapWizard(sessionId) { const state = { step: 1, type: 'roadmap', data: {} }; this.wizardStates.set(sessionId, state); return `🚀 **Product Roadmap Creation Wizard** Let's create a comprehensive product roadmap for your business! **Step 1/4: Basic Information** Please provide the following information: 1. **Product/Roadmap Name**: What is the name of your product or roadmap? 2. **Vision Statement**: What is the long-term vision for this product? (2-3 sentences) 3. **Time Horizon**: How far ahead are you planning? - quarterly (3-12 months) - annual (1-2 years) - multi-year (2-5 years) 4. **Your Name/Role**: Who will be the owner of this roadmap? Example response: - Name: "Customer Portal 2.0" - Vision: "Create a self-service portal that empowers customers to manage their accounts, access resources, and get support without human intervention." - Time Horizon: annual - Owner: "Jane Smith, Product Manager"`; } async continueRoadmapWizard(sessionId, input) { const state = this.wizardStates.get(sessionId); if (!state || state.type !== 'roadmap') { return 'No active roadmap wizard found. Start one with start_roadmap_wizard.'; } switch (state.step) { case 1: // Parse basic information state.data.name = input.name; state.data.vision = input.vision; state.data.timeHorizon = input.timeHorizon; state.data.owner = input.owner; state.step = 2; return `✅ Great! Basic information captured. **Step 2/4: Key Stakeholders** Who are the key stakeholders for this roadmap? Please list their names and roles. Examples: - Engineering Lead: John Doe - Sales Director: Sarah Johnson - Customer Success Manager: Mike Chen - Marketing Head: Lisa Brown You can provide as many stakeholders as needed, or type "none" if you want to skip this step.`; case 2: // Parse stakeholders if (input.stakeholders && input.stakeholders !== 'none') { state.data.stakeholders = Array.isArray(input.stakeholders) ? input.stakeholders : [input.stakeholders]; } else { state.data.stakeholders = []; } state.step = 3; return `✅ Stakeholders added! **Step 3/4: Strategic Context** To help structure your roadmap effectively, please answer: 1. **Primary Goal**: What is the main business goal this roadmap serves? - Revenue growth - Cost reduction - Market expansion - Customer satisfaction - Technical modernization - Other (please specify) 2. **Key Challenges**: What are the main challenges you're trying to solve? (list 2-3) 3. **Success Metrics**: How will you measure success? (list 2-3 metrics) Example: - Goal: Customer satisfaction - Challenges: High support ticket volume, Limited self-service options, Poor mobile experience - Metrics: Support tickets reduced by 50%, Customer satisfaction score > 4.5, Self-service adoption > 70%`; case 3: // Parse strategic context state.data.primaryGoal = input.goal; state.data.challenges = input.challenges; state.data.successMetrics = input.metrics; state.step = 4; const timelineHelp = state.data.timeHorizon === 'quarterly' ? 'next 4 quarters (e.g., Q1 2024, Q2 2024, etc.)' : state.data.timeHorizon === 'annual' ? 'next 2 years by quarter' : 'next 3-5 years by year'; return `✅ Strategic context captured! **Step 4/4: Initial Themes** Let's define 2-3 strategic themes for your roadmap. Themes are high-level focus areas that group related initiatives. For each theme, provide: 1. **Name**: Short, memorable name 2. **Description**: What this theme encompasses 3. **Priority**: must-have, should-have, or nice-to-have 4. **Timeframe**: When will you work on this (${timelineHelp}) Example Theme: - Name: "Self-Service Excellence" - Description: "Build comprehensive self-service capabilities to reduce support burden and improve customer satisfaction" - Priority: must-have - Timeframe: Q1 2024 - Q4 2024 Please provide at least 2 themes to complete the wizard.`; case 4: // Create the roadmap const roadmapOptions = { name: state.data.name, vision: state.data.vision, timeHorizon: state.data.timeHorizon, owner: state.data.owner, stakeholders: state.data.stakeholders }; const roadmap = await this.roadmapManager.createRoadmap(roadmapOptions); // Add initial themes if provided let themesAdded = 0; if (input.themes && Array.isArray(input.themes)) { for (const themeInput of input.themes) { try { const themeOptions = { roadmapId: roadmap.id, name: themeInput.name, description: themeInput.description, objectives: this.deriveObjectivesFromContext(state.data, themeInput), priority: themeInput.priority, startQuarter: themeInput.startQuarter || this.getCurrentQuarter(), endQuarter: themeInput.endQuarter || this.getQuarterOffset(this.getCurrentQuarter(), 4) }; await this.roadmapManager.addTheme(themeOptions); themesAdded++; } catch (error) { console.error('Error adding theme:', error); } } } // Clear wizard state this.wizardStates.delete(sessionId); return `🎉 **Roadmap Created Successfully!** **${roadmap.name}** - Vision: ${roadmap.vision} - Time Horizon: ${roadmap.timeHorizon} - Owner: ${roadmap.owner} - Stakeholders: ${roadmap.stakeholders.length} - Initial Themes: ${themesAdded} **Roadmap ID**: ${roadmap.id} **Strategic Context Captured**: - Primary Goal: ${state.data.primaryGoal} - Key Challenges: ${state.data.challenges.join(', ')} - Success Metrics: ${state.data.successMetrics.join(', ')} **Next Steps**: 1. Add more themes using \`add_roadmap_theme\` 2. Create initiatives within themes using \`create_initiative_wizard\` 3. Add features to initiatives 4. Set up milestones and releases 5. Prioritize features using \`prioritize_features\` Would you like to start adding initiatives to your themes? Use \`create_initiative_wizard\` to begin!`; default: return 'Invalid wizard state. Please restart the wizard.'; } } async startInitiativeWizard(sessionId, roadmapId, themeId) { const state = { step: 1, type: 'initiative', data: {}, roadmapId, themeId }; this.wizardStates.set(sessionId, state); const roadmap = await this.roadmapManager.getRoadmap(roadmapId); const themeDetails = await this.roadmapManager.getThemeDetails(themeId); if (!roadmap || !themeDetails) { this.wizardStates.delete(sessionId); return 'Invalid roadmap or theme ID provided.'; } return `🎯 **Initiative Creation Wizard** **Roadmap**: ${roadmap.name} **Theme**: ${themeDetails.theme.name} Let's create a strategic initiative within this theme. **Step 1/5: Initiative Overview** Please provide: 1. **Title**: A clear, action-oriented title for the initiative 2. **Description**: What this initiative will accomplish (2-3 sentences) 3. **Key Outcomes**: What specific outcomes will this deliver? (list 2-3) Example: - Title: "Implement Smart Search and Knowledge Base" - Description: "Build an AI-powered search system and comprehensive knowledge base to help customers find answers quickly without contacting support." - Outcomes: ["Instant answers to common questions", "Reduced support ticket volume", "Improved customer satisfaction"]`; } async continueInitiativeWizard(sessionId, input) { const state = this.wizardStates.get(sessionId); if (!state || state.type !== 'initiative') { return 'No active initiative wizard found. Start one with create_initiative_wizard.'; } switch (state.step) { case 1: state.data.title = input.title; state.data.description = input.description; state.data.outcomes = input.outcomes; state.step = 2; return `✅ Initiative overview captured! **Step 2/5: Business Value Assessment** Let's quantify the value this initiative will deliver: 1. **User Impact**: How significant is the impact on users? - low: Minor improvement - medium: Noticeable improvement - high: Significant improvement - critical: Game-changing impact 2. **Revenue Impact**: Estimated annual revenue impact in dollars 3. **Cost Savings**: Estimated annual cost savings in dollars 4. **Strategic Value**: How well does this align with company strategy? (1-10, where 10 is perfectly aligned) Example: - User Impact: high - Revenue Impact: 500000 (for $500k) - Cost Savings: 200000 (for $200k) - Strategic Value: 8`; case 2: const customerSat = await this.estimateCustomerSatisfactionImpact(input.userImpact); state.data.estimatedValue = { userImpact: input.userImpact, revenueImpact: input.revenueImpact, costSavings: input.costSavings, strategicValue: input.strategicValue, customerSatisfaction: customerSat }; state.step = 3; return `✅ Business value assessed! **Step 3/5: Effort Estimation** Now let's estimate the effort required: 1. **Development Weeks**: How many weeks of development effort? 2. **Design Weeks**: How many weeks of design effort? 3. **QA/Testing Weeks**: How many weeks of QA effort? 4. **Confidence Level**: How confident are you in these estimates? - low: Very uncertain, could be 50%+ off - medium: Reasonably confident, within 25% - high: Very confident, within 10% Example: - Development: 12 - Design: 4 - QA: 3 - Confidence: medium`; case 3: state.data.estimatedEffort = { developmentWeeks: input.developmentWeeks, designWeeks: input.designWeeks, qaWeeks: input.qaWeeks, confidence: input.confidence }; state.step = 4; return `✅ Effort estimated! **Step 4/5: Risk Assessment** What are the main risks for this initiative? For each risk, provide: 1. **Description**: What could go wrong? 2. **Likelihood**: low, medium, or high 3. **Impact**: low, medium, or high 4. **Mitigation**: How will you address this risk? Please provide 1-3 risks, or type "none" if there are no significant risks. Example Risk: - Description: "Integration with legacy system may be complex" - Likelihood: medium - Impact: high - Mitigation: "Conduct technical spike early, plan for gradual migration"`; case 4: if (input.risks && input.risks !== 'none') { state.data.risks = Array.isArray(input.risks) ? input.risks : [input.risks]; state.data.risks = state.data.risks.map((r, index) => ({ id: `risk-${Date.now()}-${index}`, description: r.description, likelihood: r.likelihood, impact: r.impact, mitigation: r.mitigation })); } else { state.data.risks = []; } state.step = 5; return `✅ Risks assessed! **Step 5/5: Initial Features** Let's define 2-3 key features for this initiative. For each feature: 1. **Name**: Feature name 2. **Description**: What it does 3. **Value Score**: Business value (1-100) 4. **Complexity**: technical complexity (low, medium, high, very-high) Example Feature: - Name: "AI-Powered Search" - Description: "Natural language search that understands user intent and provides relevant results" - Value: 85 - Complexity: high Please provide at least 2 features to complete the initiative.`; case 5: // Create the initiative const initiativeOptions = { roadmapId: state.roadmapId, themeId: state.themeId, title: state.data.title, description: state.data.description, estimatedValue: state.data.estimatedValue, estimatedEffort: state.data.estimatedEffort, risks: state.data.risks }; const initiative = await this.roadmapManager.createInitiative(initiativeOptions); // Add initial features if provided let featuresAdded = 0; if (input.features && Array.isArray(input.features)) { for (const featureInput of input.features) { try { const businessValue = { score: featureInput.value, rationale: `Derived from initiative goals: ${state.data.outcomes.join(', ')}`, metrics: this.deriveFeatureMetrics(featureInput, state.data.outcomes) }; const featureOptions = { roadmapId: state.roadmapId, initiativeId: initiative.id, name: featureInput.name, description: featureInput.description, businessValue, technicalComplexity: featureInput.complexity }; await this.roadmapManager.addFeature(featureOptions); featuresAdded++; } catch (error) { console.error('Error adding feature:', error); } } } // Calculate total effort const totalEffort = state.data.estimatedEffort.developmentWeeks + state.data.estimatedEffort.designWeeks + state.data.estimatedEffort.qaWeeks; // Clear wizard state this.wizardStates.delete(sessionId); return `🎉 **Initiative Created Successfully!** **${initiative.title}** ${initiative.description} **Key Outcomes**: ${state.data.outcomes.map((o, i) => `${i + 1}. ${o}`).join('\n')} **Value Assessment**: - User Impact: ${initiative.value.userImpact} - Revenue Impact: $${initiative.value.revenueImpact.toLocaleString()}/year - Cost Savings: $${initiative.value.costSavings.toLocaleString()}/year - Strategic Value: ${initiative.value.strategicValue}/10 **Effort Estimate**: ${totalEffort} weeks (${initiative.effort.confidence} confidence) **Risks Identified**: ${initiative.risks.length} **Initial Features**: ${featuresAdded} **Initiative ID**: ${initiative.id} **Next Steps**: 1. Add more features using \`add_feature\` 2. Link to epics in your agile management system 3. Prioritize features using \`prioritize_features\` 4. Assign to a release using \`plan_release\` Great work! Your initiative is now part of the roadmap.`; default: return 'Invalid wizard state. Please restart the wizard.'; } } async startQuickFeatureWizard(sessionId, roadmapId, initiativeId) { const state = { step: 1, type: 'feature', data: {}, roadmapId, initiativeId }; this.wizardStates.set(sessionId, state); return `⚡ **Quick Feature Addition** Let's quickly add a feature to your initiative. Please provide: 1. **Name**: Feature name 2. **Description**: What it does (1-2 sentences) 3. **Value**: Business value score (1-100) 4. **Complexity**: low, medium, high, or very-high 5. **Success Metrics**: How will you measure success? (list 2-3 metrics) Example: - Name: "Real-time Notifications" - Description: "Push notifications for important account updates and alerts" - Value: 75 - Complexity: medium - Metrics: ["User engagement up 30%", "Response time < 2 seconds", "90% delivery rate"]`; } async continueQuickFeatureWizard(sessionId, input) { const state = this.wizardStates.get(sessionId); if (!state || state.type !== 'feature') { return 'No active feature wizard found.'; } const businessValue = { score: input.value, rationale: input.rationale || 'Added via quick wizard', metrics: input.metrics || [] }; const featureOptions = { roadmapId: state.roadmapId, initiativeId: state.initiativeId, name: input.name, description: input.description, businessValue, technicalComplexity: input.complexity, targetRelease: input.targetRelease }; const feature = await this.roadmapManager.addFeature(featureOptions); this.wizardStates.delete(sessionId); return `✅ **Feature Added Successfully!** **${feature.name}** ${feature.description} - Business Value: ${feature.businessValue.score}/100 - Technical Complexity: ${feature.technicalComplexity} - Success Metrics: ${feature.businessValue.metrics.length} **Feature ID**: ${feature.id} Feature has been added to the initiative!`; } // Helper methods getCurrentQuarter() { const now = new Date(); const quarter = Math.floor(now.getMonth() / 3) + 1; const year = now.getFullYear(); return `Q${quarter} ${year}`; } getQuarterOffset(startQuarter, offset) { const [q, year] = startQuarter.split(' '); const quarterNum = parseInt(q.substring(1)); const yearNum = parseInt(year); let newQuarter = quarterNum + offset; let newYear = yearNum; while (newQuarter > 4) { newQuarter -= 4; newYear++; } return `Q${newQuarter} ${newYear}`; } deriveObjectivesFromContext(contextData, theme) { const objectives = []; // Add objective based on primary goal if (contextData.primaryGoal) { objectives.push(`Drive ${contextData.primaryGoal} through ${theme.name.toLowerCase()}`); } // Add objectives based on challenges if (contextData.challenges && contextData.challenges.length > 0) { objectives.push(`Address key challenge: ${contextData.challenges[0]}`); } // Add metric-based objective if (contextData.successMetrics && contextData.successMetrics.length > 0) { objectives.push(`Achieve target: ${contextData.successMetrics[0]}`); } // Add theme-specific objective objectives.push(`Deliver ${theme.priority} capabilities for ${theme.name}`); return objectives; } async estimateCustomerSatisfactionImpact(userImpact) { const impactMap = { 'low': 2, 'medium': 5, 'high': 10, 'critical': 20 }; return impactMap[userImpact] || 5; } deriveFeatureMetrics(feature, outcomes) { const metrics = []; // Add feature-specific metric metrics.push(`${feature.name} adoption rate > 60%`); // Add outcome-based metric if (outcomes && outcomes.length > 0) { metrics.push(`Contribute to: ${outcomes[0]}`); } // Add value-based metric if (feature.value > 80) { metrics.push('User satisfaction score > 4.5/5'); } else if (feature.value > 60) { metrics.push('User satisfaction score > 4.0/5'); } else { metrics.push('Feature completion rate > 80%'); } return metrics; } getActiveWizards() { return Array.from(this.wizardStates.keys()); } cancelWizard(sessionId) { return this.wizardStates.delete(sessionId); } } //# sourceMappingURL=roadmap-wizard.js.map