diff --git a/workspace-utils-enhanced/context.js b/workspace-utils-enhanced/context.js deleted file mode 100644 index 4ed45a78..00000000 --- a/workspace-utils-enhanced/context.js +++ /dev/null @@ -1,384 +0,0 @@ -#!/usr/bin/env node -const path = require('path'); -const fs = require('fs'); - -// Import context manager (copy functionality since we can't use external dependencies) -class ContextManager { - constructor(workspacePath = null) { - this.workspacePath = workspacePath || path.join(process.cwd(), '.workspace'); - this.contextPath = path.join(this.workspacePath, 'context'); - this.decisionsPath = path.join(this.workspacePath, 'decisions'); - this.progressPath = path.join(this.workspacePath, 'progress'); - this.qualityPath = path.join(this.workspacePath, 'quality'); - this.maxContextSize = 10 * 1024 * 1024; - this.initialize(); - } - - initialize() { - const dirs = [this.contextPath, this.decisionsPath, this.progressPath, this.qualityPath]; - for (const dir of dirs) { - if (!fs.existsSync(dir)) { - fs.mkdirSync(dir, { recursive: true }); - } - } - } - - async loadSharedContext() { - try { - const contextFile = path.join(this.contextPath, 'shared-context.md'); - - if (!fs.existsSync(contextFile)) { - return this.getDefaultSharedContext(); - } - - const content = fs.readFileSync(contextFile, 'utf8'); - return this.parseSharedContext(content); - } catch (error) { - console.error('Failed to load shared context:', error.message); - return this.getDefaultSharedContext(); - } - } - - getDefaultSharedContext() { - return { - lastUpdated: new Date().toISOString(), - activeSessions: [], - primaryAgent: 'unknown', - currentFocus: 'No active development focus', - keyDecisions: [], - nextSteps: [], - sessionNotes: '' - }; - } - - parseSharedContext(content) { - const context = this.getDefaultSharedContext(); - - try { - const lastUpdatedMatch = content.match(/\*\*Last Updated:\*\* (.+)/); - if (lastUpdatedMatch) context.lastUpdated = lastUpdatedMatch[1]; - - const activeSessionsMatch = content.match(/\*\*Active Sessions:\*\* (.+)/); - if (activeSessionsMatch && activeSessionsMatch[1] !== 'None') { - context.activeSessions = activeSessionsMatch[1].split(', ').map(s => s.trim()); - } - - const primaryAgentMatch = content.match(/\*\*Primary Agent:\*\* (.+)/); - if (primaryAgentMatch) context.primaryAgent = primaryAgentMatch[1]; - - const currentFocusMatch = content.match(/## Current Focus\n([\s\S]*?)(?=\n## |$)/); - if (currentFocusMatch) context.currentFocus = currentFocusMatch[1].trim(); - - const keyDecisionsMatch = content.match(/## Key Decisions\n([\s\S]*?)(?=\n## |$)/); - if (keyDecisionsMatch) { - context.keyDecisions = keyDecisionsMatch[1] - .split('\n') - .filter(line => line.startsWith('- ')) - .map(line => line.substring(2).trim()) - .filter(decision => decision && !decision.includes('No decisions recorded')); - } - - const nextStepsMatch = content.match(/## Next Steps\n([\s\S]*?)(?=\n## |$)/); - if (nextStepsMatch) { - context.nextSteps = nextStepsMatch[1] - .split('\n') - .filter(line => line.startsWith('- ')) - .map(line => line.substring(2).trim()) - .filter(step => step && !step.includes('No next steps defined')); - } - - const sessionNotesMatch = content.match(/## Session Notes\n([\s\S]*?)$/); - if (sessionNotesMatch) context.sessionNotes = sessionNotesMatch[1].trim(); - - } catch (error) { - console.warn('Failed to parse shared context, using defaults:', error.message); - } - - return context; - } - - async loadProgress() { - try { - const progressFile = path.join(this.progressPath, 'progress-summary.md'); - - if (!fs.existsSync(progressFile)) { - return { - lastUpdated: new Date().toISOString(), - currentStory: 'No active story', - completedTasks: [], - pendingTasks: [], - blockers: [], - qualityScore: 'Not assessed' - }; - } - - const content = fs.readFileSync(progressFile, 'utf8'); - const progress = { - lastUpdated: new Date().toISOString(), - currentStory: 'No active story', - completedTasks: [], - pendingTasks: [], - blockers: [], - qualityScore: 'Not assessed' - }; - - const currentStoryMatch = content.match(/\*\*Current Story:\*\* (.+)/); - if (currentStoryMatch) progress.currentStory = currentStoryMatch[1]; - - const qualityScoreMatch = content.match(/\*\*Quality Score:\*\* (.+)/); - if (qualityScoreMatch) progress.qualityScore = qualityScoreMatch[1]; - - return progress; - } catch (error) { - console.error('Failed to load progress:', error.message); - return { - lastUpdated: new Date().toISOString(), - currentStory: 'No active story', - completedTasks: [], - pendingTasks: [], - blockers: [], - qualityScore: 'Not assessed' - }; - } - } - - async getLatestQualityMetrics() { - try { - const qualityFile = path.join(this.qualityPath, 'quality-metrics.md'); - - if (!fs.existsSync(qualityFile)) { - return null; - } - - const content = fs.readFileSync(qualityFile, 'utf8'); - const assessments = content.split('## Quality Assessment -'); - - if (assessments.length < 2) { - return null; - } - - return { - timestamp: assessments[1].split('\n')[0].trim(), - available: true - }; - } catch (error) { - console.error('Failed to get latest quality metrics:', error.message); - return null; - } - } -} - -// Context Management CLI -async function handleContextCommand() { - try { - const workspacePath = path.join(process.cwd(), '.workspace'); - - if (!fs.existsSync(workspacePath)) { - console.error('āŒ Workspace directory not found. Run `npx bmad-method install` first.'); - process.exit(1); - } - - const contextManager = new ContextManager(); - const args = process.argv.slice(2); - const command = args[0]; - - switch (command) { - case 'status': - await showContextStatus(contextManager); - break; - case 'load': - await loadContext(contextManager); - break; - case 'update': - await updateContext(contextManager, args.slice(1)); - break; - case 'decisions': - await showDecisions(contextManager); - break; - case 'progress': - await showProgress(contextManager); - break; - case 'export': - await exportContext(contextManager); - break; - default: - showUsage(); - } - } catch (error) { - console.error('āŒ Context command failed:', error.message); - process.exit(1); - } -} - -async function showContextStatus(contextManager) { - console.log('šŸ“„ BMAD Context Status'); - console.log('======================'); - - const context = await contextManager.loadSharedContext(); - const progress = await contextManager.loadProgress(); - const quality = await contextManager.getLatestQualityMetrics(); - - console.log(`šŸ“ Context: ${contextManager.contextPath}`); - console.log(`šŸ• Last Updated: ${context.lastUpdated}`); - console.log(`šŸ‘¤ Primary Agent: ${context.primaryAgent}`); - console.log(`šŸŽÆ Current Focus: ${context.currentFocus}`); - console.log(`šŸ“Š Quality Score: ${progress.qualityScore}`); - - if (context.activeSessions.length > 0) { - console.log(`\nšŸ‘„ Active Sessions: ${context.activeSessions.length}`); - context.activeSessions.forEach((session, index) => { - console.log(` ${index + 1}. ${session}`); - }); - } - - if (context.keyDecisions.length > 0) { - console.log(`\nšŸ”‘ Recent Key Decisions:`); - context.keyDecisions.slice(-3).forEach((decision, index) => { - console.log(` ${index + 1}. ${decision}`); - }); - } - - if (context.nextSteps.length > 0) { - console.log(`\nā­ļø Next Steps:`); - context.nextSteps.forEach((step, index) => { - console.log(` ${index + 1}. ${step}`); - }); - } - - console.log(`\nšŸ“ˆ Quality Metrics: ${quality ? 'Available' : 'Not available'}`); -} - -async function loadContext(contextManager) { - console.log('šŸ“„ Loading workspace context...\n'); - - const context = await contextManager.loadSharedContext(); - - console.log('šŸŽÆ Current Focus:'); - console.log(context.currentFocus); - - if (context.keyDecisions.length > 0) { - console.log('\nšŸ”‘ Key Decisions:'); - context.keyDecisions.forEach((decision, index) => { - console.log(` ${index + 1}. ${decision}`); - }); - } - - if (context.nextSteps.length > 0) { - console.log('\nā­ļø Next Steps:'); - context.nextSteps.forEach((step, index) => { - console.log(` ${index + 1}. ${step}`); - }); - } - - if (context.sessionNotes) { - console.log('\nšŸ“ Session Notes:'); - console.log(context.sessionNotes); - } -} - -async function showDecisions(contextManager) { - const decisionsFile = path.join(contextManager.decisionsPath, 'decisions-log.md'); - - if (!fs.existsSync(decisionsFile)) { - console.log('šŸ“‹ No decisions recorded yet.'); - return; - } - - const content = fs.readFileSync(decisionsFile, 'utf8'); - const decisions = content.split('## Decision ').slice(1); - - console.log('šŸ“‹ Architectural & Design Decisions'); - console.log('==================================='); - - decisions.slice(-5).forEach((decision, index) => { - const lines = decision.split('\n'); - const title = lines[0].replace(/^\d+:\s*/, ''); - const dateMatch = decision.match(/\*\*Date:\*\* (.+)/); - const agentMatch = decision.match(/\*\*Agent:\*\* (.+)/); - - console.log(`\n${decisions.length - 4 + index}. ${title}`); - if (dateMatch) console.log(` šŸ“… ${dateMatch[1]}`); - if (agentMatch) console.log(` šŸ‘¤ ${agentMatch[1]}`); - }); -} - -async function showProgress(contextManager) { - const progress = await contextManager.loadProgress(); - - console.log('šŸ“ˆ Development Progress'); - console.log('======================'); - console.log(`šŸŽÆ Current Story: ${progress.currentStory}`); - console.log(`šŸ“Š Quality Score: ${progress.qualityScore}`); - console.log(`šŸ• Last Updated: ${progress.lastUpdated}`); - - if (progress.completedTasks && progress.completedTasks.length > 0) { - console.log(`\nāœ… Completed Tasks: ${progress.completedTasks.length}`); - } - - if (progress.pendingTasks && progress.pendingTasks.length > 0) { - console.log(`ā³ Pending Tasks: ${progress.pendingTasks.length}`); - } - - if (progress.blockers && progress.blockers.length > 0) { - console.log(`🚫 Blockers: ${progress.blockers.length}`); - } -} - -async function exportContext(contextManager) { - try { - const context = await contextManager.loadSharedContext(); - const progress = await contextManager.loadProgress(); - - const exportContent = `# Workspace Context Export -**Generated:** ${new Date().toISOString()} - -## Current Status -- **Primary Agent:** ${context.primaryAgent} -- **Active Sessions:** ${context.activeSessions.join(', ') || 'None'} -- **Current Focus:** ${context.currentFocus} -- **Quality Score:** ${progress.qualityScore} - -## Key Decisions -${context.keyDecisions.map(d => `- ${d}`).join('\n') || '- No decisions recorded'} - -## Next Steps -${context.nextSteps.map(step => `- ${step}`).join('\n') || '- No next steps defined'} - -## Session Notes -${context.sessionNotes || 'No session notes available'} -`; - - const exportFile = path.join(process.cwd(), `context-export-${Date.now()}.md`); - fs.writeFileSync(exportFile, exportContent); - - console.log('āœ… Context exported successfully'); - console.log(`šŸ“ Export file: ${exportFile}`); - } catch (error) { - console.error('āŒ Failed to export context:', error.message); - } -} - -function showUsage() { - console.log('šŸ“„ BMAD Context Management'); - console.log('=========================='); - console.log(''); - console.log('Usage: node context.js '); - console.log(''); - console.log('Commands:'); - console.log(' status - Show current workspace context status'); - console.log(' load - Load and display shared context'); - console.log(' decisions - Show recent architectural decisions'); - console.log(' progress - Show development progress summary'); - console.log(' export - Export context to markdown file'); - console.log(''); - console.log('Examples:'); - console.log(' node context.js status'); - console.log(' node context.js load'); - console.log(' node context.js export'); -} - -if (require.main === module) { - handleContextCommand(); -} - -module.exports = { ContextManager }; \ No newline at end of file