BMAD-METHOD/tools/demo-context-100-percent.js

272 lines
12 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env node
// Demo script to test 100% Complete Context Persistence functionality
const path = require('path');
const fs = require('fs');
// Import context manager
const ContextManager = require('./installer/lib/context-manager');
async function demoContext100Percent() {
console.log('🎯 BMAD Context Persistence 100% Complete Demo');
console.log('===============================================\n');
// Create a test workspace in /tmp
const testWorkspace = '/tmp/bmad-context-100-test/.workspace';
if (fs.existsSync(testWorkspace)) {
fs.rmSync(path.dirname(testWorkspace), { recursive: true, force: true });
}
const contextManager = new ContextManager(testWorkspace);
console.log('✅ Initialized test workspace at:', testWorkspace);
console.log(`📁 New directories: versions/, locks/`);
try {
// Demo 1: Context Versioning System
console.log('\n📚 Demo 1: Context Versioning System');
console.log('=====================================');
// Create initial context
await contextManager.updateSharedContext({
currentFocus: 'Implementing advanced context versioning system',
nextSteps: ['Add version tracking', 'Implement conflict resolution', 'Test rollback functionality']
});
// Create first version
const contextFile = path.join(testWorkspace, 'context', 'shared-context.md');
const initialContent = fs.readFileSync(contextFile, 'utf8');
const version1 = await contextManager.createContextVersion('shared-context', initialContent, 'session-001', 'dev-agent');
console.log(`✅ Created version 1: ${version1}`);
// Modify context
await contextManager.updateSharedContext({
currentFocus: 'Implementing advanced context versioning system with conflict resolution',
nextSteps: ['Add version tracking', 'Implement conflict resolution', 'Test rollback functionality', 'Add merge capabilities']
});
// Create second version
const modifiedContent = fs.readFileSync(contextFile, 'utf8');
const version2 = await contextManager.createContextVersion('shared-context', modifiedContent, 'session-002', 'architect-agent');
console.log(`✅ Created version 2: ${version2}`);
// Test version retrieval
const recentVersions = await contextManager.getRecentVersions('shared-context', 5);
console.log(`✅ Retrieved ${recentVersions.length} recent versions`);
recentVersions.forEach((v, i) => {
console.log(` ${i + 1}. ${v.id} by ${v.agent} at ${new Date(v.timestamp).toLocaleString()}`);
});
// Demo 2: Conflict Detection and Resolution
console.log('\n⚔ Demo 2: Conflict Detection and Resolution');
console.log('=============================================');
// Simulate concurrent modification
const newContent1 = modifiedContent.replace('conflict resolution', 'advanced conflict resolution');
const newContent2 = modifiedContent.replace('versioning system', 'versioning and backup system');
// Check for conflicts
const conflict1 = await contextManager.detectContextConflicts('shared-context', newContent1, 'session-003');
console.log(`✅ Conflict detection 1: ${conflict1.hasConflict ? 'CONFLICT DETECTED' : 'No conflict'}`);
const conflict2 = await contextManager.detectContextConflicts('shared-context', newContent2, 'session-004');
console.log(`✅ Conflict detection 2: ${conflict2.hasConflict ? 'CONFLICT DETECTED' : 'No conflict'}`);
// Test merge capabilities
if (conflict1.hasConflict || conflict2.hasConflict) {
console.log(' Conflicts detected - would normally trigger merge process');
}
// Create versions for merge testing
const change1 = { content: newContent1, timestamp: new Date().toISOString() };
const change2 = { content: newContent2, timestamp: new Date(Date.now() + 1000).toISOString() };
try {
const mergedContent = await contextManager.mergeContextChanges('shared-context', initialContent, change1, change2);
console.log('✅ Context merge successful');
console.log(` Merged content length: ${mergedContent.length} characters`);
} catch (error) {
console.log(`⚠️ Merge test: ${error.message}`);
}
// Demo 3: Context Locking System
console.log('\n🔒 Demo 3: Context Locking System');
console.log('=================================');
// Acquire lock for session 1
const lock1 = await contextManager.acquireContextLock('shared-context', 'session-001', 10000);
console.log(`✅ Lock acquisition (session-001): ${lock1.acquired ? 'SUCCESS' : 'FAILED'}`);
// Try to acquire same lock from session 2
const lock2 = await contextManager.acquireContextLock('shared-context', 'session-002', 5000);
console.log(`✅ Lock acquisition (session-002): ${lock2.acquired ? 'SUCCESS' : 'FAILED'}`);
if (!lock2.acquired) {
console.log(` Locked by: ${lock2.lockedBy}, expires: ${new Date(lock2.expiresAt).toLocaleString()}`);
}
// Release lock
const release1 = await contextManager.releaseContextLock('shared-context', 'session-001');
console.log(`✅ Lock release (session-001): ${release1.released ? 'SUCCESS' : 'FAILED'}`);
// Now session 2 can acquire the lock
const lock3 = await contextManager.acquireContextLock('shared-context', 'session-002', 5000);
console.log(`✅ Lock acquisition (session-002) after release: ${lock3.acquired ? 'SUCCESS' : 'FAILED'}`);
// Cleanup expired locks test
const cleanup = await contextManager.cleanupExpiredLocks();
console.log(`✅ Expired locks cleaned up: ${cleanup.cleanedCount}`);
// Release remaining locks
await contextManager.releaseContextLock('shared-context', 'session-002');
// Demo 4: Rollback System
console.log('\n⏪ Demo 4: Context Rollback System');
console.log('==================================');
// Get current context
const currentContext = await contextManager.loadSharedContext();
console.log(`✅ Current context focus: "${currentContext.currentFocus.substring(0, 50)}..."`);
// Rollback to version 1
if (recentVersions.length > 0) {
const rollbackResult = await contextManager.rollbackToVersion('shared-context', recentVersions[0].id);
console.log(`✅ Rollback result: ${rollbackResult.success ? 'SUCCESS' : 'FAILED'}`);
if (rollbackResult.success) {
console.log(` Rolled back to: ${new Date(rollbackResult.rolledBackTo).toLocaleString()}`);
console.log(` Original agent: ${rollbackResult.agent}`);
}
// Verify rollback worked
const rolledBackContext = await contextManager.loadSharedContext();
console.log(`✅ After rollback focus: "${rolledBackContext.currentFocus.substring(0, 50)}..."`);
}
// Demo 5: BMAD Agent Integration Hooks
console.log('\n🤖 Demo 5: BMAD Agent Integration Hooks');
console.log('=======================================');
// Test story start hook
await contextManager.onStoryStart('Story-3.1-Advanced-Context-System', 'dev-agent', 'session-005');
console.log('✅ Story start hook executed');
// Test decision made hook
await contextManager.onDecisionMade({
title: 'Implement context versioning with Git-like functionality',
decision: 'Use JSON-based versioning with content hashing for conflict detection',
rationale: 'Provides reliable conflict detection and merge capabilities',
impact: 'Enables safe concurrent context modifications'
}, 'architect-agent', 'session-005');
console.log('✅ Decision made hook executed');
// Test quality audit hook
await contextManager.onQualityAudit({
story: 'Story-3.1-Advanced-Context-System',
realityAuditScore: '95/100',
patternCompliance: '92/100',
technicalDebtScore: '88/100',
overallQuality: 'A- (95/100)',
details: 'Context versioning system implemented with comprehensive conflict resolution'
}, 'qa-agent', 'session-005');
console.log('✅ Quality audit hook executed');
// Test agent handoff hook
await contextManager.onAgentHandoff('dev-agent', 'qa-agent', 'session-005',
'Context versioning system complete. All features implemented and tested. Ready for comprehensive quality validation.');
console.log('✅ Agent handoff hook executed');
// Demo 6: Integration Verification
console.log('\n🔗 Demo 6: Integration Verification');
console.log('====================================');
// Verify all hook integrations worked
const finalStatus = await contextManager.getWorkspaceStatus();
console.log('✅ Integration verification:');
console.log(` - Primary Agent: ${finalStatus.context.primaryAgent}`);
console.log(` - Current Focus: ${finalStatus.context.currentFocus.substring(0, 60)}...`);
console.log(` - Quality Score: ${finalStatus.progress.qualityScore}`);
console.log(` - Recent Decisions: ${finalStatus.recentDecisions.length}`);
// Check that decision was auto-logged
const decisions = await contextManager.getDecisions();
console.log(` - Total Decisions: ${decisions.length}`);
const autoDecision = decisions.find(d => d.title.includes('context versioning'));
console.log(` - Auto-logged decision: ${autoDecision ? 'YES' : 'NO'}`);
// Demo 7: Directory Structure Verification
console.log('\n📁 Demo 7: Enhanced Directory Structure');
console.log('=======================================');
const directories = ['context', 'decisions', 'progress', 'quality', 'archive', 'versions', 'locks'];
console.log('✅ Directory verification:');
directories.forEach(dir => {
const dirPath = path.join(testWorkspace, dir);
const exists = fs.existsSync(dirPath);
const files = exists ? fs.readdirSync(dirPath).length : 0;
console.log(` - ${dir}/: ${exists ? 'EXISTS' : 'MISSING'} (${files} files)`);
});
// Verify version files
const versionFiles = fs.readdirSync(path.join(testWorkspace, 'versions'));
console.log(`✅ Version files created: ${versionFiles.length}`);
versionFiles.forEach((file, index) => {
console.log(` ${index + 1}. ${file}`);
});
// Demo 8: Performance and Concurrency Testing
console.log('\n⚡ Demo 8: Performance and Concurrency Testing');
console.log('===============================================');
// Test multiple concurrent operations
const startTime = Date.now();
const operations = [
contextManager.updateSharedContext({ currentFocus: 'Concurrent test 1' }),
contextManager.logDecision({
title: 'Concurrent decision test',
agent: 'test-agent',
decision: 'Testing concurrent operations',
rationale: 'Verify system stability under load'
}),
contextManager.updateProgress({
currentStory: 'Concurrency Test Story',
completedTasks: ['Test task 1', 'Test task 2']
}),
contextManager.updateQualityMetrics({
agent: 'test-agent',
story: 'Concurrency Test Story',
overallQuality: 'B+ (88/100)',
details: 'Concurrent operation test'
})
];
await Promise.all(operations);
const endTime = Date.now();
console.log(`✅ Concurrent operations completed in ${endTime - startTime}ms`);
console.log(` All operations completed successfully`);
console.log('\n🎉 Context Persistence 100% Complete Demo Finished!');
console.log('====================================================');
console.log(`📁 Test workspace: ${testWorkspace}`);
console.log('🎯 100% Features Demonstrated:');
console.log(' ✅ Context versioning with content hashing');
console.log(' ✅ Conflict detection and intelligent merging');
console.log(' ✅ Context locking for concurrent access safety');
console.log(' ✅ Rollback capabilities with backup protection');
console.log(' ✅ BMAD agent integration hooks for automatic capture');
console.log(' ✅ Story/Decision/Quality/Handoff event processing');
console.log(' ✅ Performance optimization for concurrent operations');
console.log(' ✅ Enterprise-grade directory structure');
console.log('🚀 Production-ready with enterprise features!');
} catch (error) {
console.error('\n❌ Demo failed:', error.message);
console.error(error.stack);
}
}
// Run the demo
if (require.main === module) {
demoContext100Percent();
}
module.exports = { demoContext100Percent };