UNPKG

claude-code-automation

Version:

🚀 Generic project automation system with anti-compaction protection and recovery capabilities. Automatically detects project type (React, Node.js, Python, Rust, Go, Java) and provides intelligent analysis. Claude Code optimized - run 'welcome' after inst

435 lines (370 loc) 15.4 kB
/** * Context Preservation Engine * Anti-compaction system that maintains project state and context * Ensures project can be fully reconstructed after prompt compaction */ const fs = require('fs').promises; const path = require('path'); class ContextPreservationEngine { constructor() { this.projectRoot = path.resolve(__dirname, '../..'); this.stateDir = path.join(this.projectRoot, 'docs/state'); this.decisionsDir = path.join(this.projectRoot, 'docs/decisions'); this.automationDir = path.join(this.projectRoot, 'docs/automation'); } /** * Preserve complete project state for compaction resistance * Creates redundant, comprehensive project documentation */ async preserveCurrentState() { const timestamp = new Date().toISOString(); console.log(`🔄 Preserving project state at ${timestamp}`); try { const projectState = { timestamp, metadata: await this.captureProjectMetadata(), phase: await this.getCurrentPhase(), progress: await this.captureProgress(), architecture: await this.captureArchitecture(), codebase: await this.captureCodebaseSnapshot(), tests: await this.captureTestState(), dependencies: await this.captureDependencies(), decisions: await this.captureDecisionHistory(), automationState: await this.captureAutomationState() }; // Store in multiple locations for redundancy await this.storeStateRedundantly(projectState, timestamp); // Update living documentation await this.updateLivingDocumentation(projectState); // Create recovery instructions await this.generateRecoveryInstructions(projectState); console.log(`✅ Project state preserved successfully`); return projectState; } catch (error) { console.error(`❌ Error preserving project state:`, error); throw error; } } /** * Capture essential project metadata */ async captureProjectMetadata() { const packageJson = JSON.parse( await fs.readFile(path.join(this.projectRoot, 'package.json'), 'utf8') ); return { name: packageJson.name, version: packageJson.version, description: packageJson.description, scripts: packageJson.scripts, dependencies: packageJson.dependencies, devDependencies: packageJson.devDependencies, projectStructure: await this.captureDirectoryStructure() }; } /** * Determine current development phase */ async getCurrentPhase() { // Analyze completed tasks and current state to determine phase const completedFeatures = await this.analyzeCompletedFeatures(); const testCoverage = await this.getTestCoverage(); const codeComplexity = await this.analyzeCodeComplexity(); return { currentSprint: this.determineCurrentSprint(completedFeatures), completedEpics: completedFeatures.epics, completedStories: completedFeatures.stories, testCoverage, codeComplexity, nextPriorities: this.determineNextPriorities(completedFeatures) }; } /** * Capture current project progress */ async captureProgress() { return { calculatorModes: await this.analyzeCalculatorModes(), testingInfrastructure: await this.analyzeTestingState(), cicdPipeline: await this.analyzeCICDState(), automationLevel: await this.analyzeAutomationLevel(), qualityMetrics: await this.captureQualityMetrics() }; } /** * Capture architectural decisions and patterns */ async captureArchitecture() { return { patterns: await this.identifyArchitecturalPatterns(), modules: await this.analyzeModuleStructure(), interfaces: await this.documentInterfaces(), dataFlow: await this.mapDataFlow(), designDecisions: await this.captureDesignDecisions() }; } /** * Create snapshot of codebase with analysis */ async captureCodebaseSnapshot() { const snapshot = { files: {}, statistics: await this.calculateCodeStatistics(), complexity: await this.analyzeCodeComplexity(), dependencies: await this.analyzeDependencyGraph() }; // Capture key files with metadata const keyFiles = await this.identifyKeyFiles(); for (const file of keyFiles) { const content = await fs.readFile(file, 'utf8'); snapshot.files[file] = { content, size: content.length, lines: content.split('\n').length, lastModified: (await fs.stat(file)).mtime, analysis: await this.analyzeFile(content, file) }; } return snapshot; } /** * Store project state with redundancy */ async storeStateRedundantly(projectState, timestamp) { const stateFile = `project-state-${timestamp.replace(/[:.]/g, '-')}.json`; // Primary storage await fs.writeFile( path.join(this.stateDir, stateFile), JSON.stringify(projectState, null, 2) ); // Backup storage in multiple locations const backupLocations = [ path.join(this.projectRoot, '.backup', stateFile), path.join(this.automationDir, 'latest-state.json') ]; for (const location of backupLocations) { await fs.mkdir(path.dirname(location), { recursive: true }); await fs.writeFile(location, JSON.stringify(projectState, null, 2)); } // Create compressed summary for quick reference const summary = this.createStateSummary(projectState); await fs.writeFile( path.join(this.stateDir, 'current-state-summary.json'), JSON.stringify(summary, null, 2) ); } /** * Update living documentation based on current state */ async updateLivingDocumentation(projectState) { // Update main README with current status const readme = await this.generateLivingReadme(projectState); await fs.writeFile(path.join(this.projectRoot, 'README.md'), readme); // Update technical documentation const techDoc = await this.generateTechnicalDocumentation(projectState); await fs.writeFile( path.join(this.automationDir, 'technical-overview.md'), techDoc ); // Update progress documentation const progressDoc = await this.generateProgressDocumentation(projectState); await fs.writeFile( path.join(this.automationDir, 'current-progress.md'), progressDoc ); } /** * Generate recovery instructions for project reconstruction */ async generateRecoveryInstructions(projectState) { const instructions = `# Project Recovery Instructions Generated: ${projectState.timestamp} ## Quick Recovery (5 minutes) 1. \`npm install\` - Install dependencies 2. \`npm run test\` - Verify basic functionality 3. \`npm start\` - Launch calculator application 4. Check docs/state/current-state-summary.json for latest status ## Full Context Recovery (15 minutes) 1. Review docs/automation/technical-overview.md for architecture 2. Check docs/automation/current-progress.md for completion status 3. Examine src/ directory structure for implementation details 4. Run scripts/automation/context-analysis.js for full analysis ## Current Phase: ${projectState.phase.currentSprint} ## Next Priority: ${projectState.phase.nextPriorities[0] || 'Analyze current state'} ## Key Files to Examine: ${Object.keys(projectState.codebase.files).map(file => `- ${file}`).join('\n')} ## Automation Status: - Testing Infrastructure: ${projectState.progress.testingInfrastructure.status} - CI/CD Pipeline: ${projectState.progress.cicdPipeline.status} - Calculator Modes: ${projectState.progress.calculatorModes.implemented.length}/12 implemented ## Recovery Verification: - [ ] Calculator launches without errors - [ ] All tests pass: \`npm test\` - [ ] All 12 calculator modes are accessible - [ ] Context preservation system is functional For detailed recovery, see docs/recovery/ directory. `; await fs.writeFile( path.join(this.projectRoot, 'docs/recovery', 'RECOVERY.md'), instructions ); } /** * Helper methods for analysis and data capture */ async analyzeCalculatorModes() { // Analyze which calculator modes are implemented try { const modernHtml = await fs.readFile( path.join(this.projectRoot, 'src/renderer/modern.html'), 'utf8' ); const modes = [ 'basic', 'scientific', 'programmer', 'financial', 'graphing', 'physics', 'chemistry', 'biology', 'health', 'environmental', 'construction', 'astronomy' ]; const implemented = modes.filter(mode => modernHtml.includes(`data-mode="${mode}"`) ); return { total: modes.length, implemented: implemented, pending: modes.filter(mode => !implemented.includes(mode)), implementationStatus: `${implemented.length}/${modes.length}` }; } catch (error) { return { error: error.message, total: 12, implemented: [], pending: [] }; } } async analyzeTestingState() { // Analyze current testing infrastructure try { const vitestConfig = await fs.readFile( path.join(this.projectRoot, 'vitest.config.js'), 'utf8' ); return { status: 'configured', framework: 'vitest', hasConfig: true, coverageEnabled: vitestConfig.includes('coverage') }; } catch (error) { return { status: 'not-configured', error: error.message }; } } async identifyKeyFiles() { const keyPaths = [ 'src/renderer/modern.html', 'src/renderer/modern-calculator.js', 'src/core/ScientificCalculator.js', 'src/core/MathEngine.js', 'src/constants/MathConstants.js', 'package.json', 'CLAUDE.md' ]; const existingFiles = []; for (const filePath of keyPaths) { const fullPath = path.join(this.projectRoot, filePath); try { await fs.access(fullPath); existingFiles.push(fullPath); } catch (error) { // File doesn't exist, skip it } } return existingFiles; } createStateSummary(projectState) { return { timestamp: projectState.timestamp, phase: projectState.phase.currentSprint, calculatorModes: `${projectState.progress.calculatorModes.implemented.length}/12`, testCoverage: projectState.phase.testCoverage || 'unknown', automationLevel: projectState.progress.automationLevel || 'basic', nextPriority: projectState.phase.nextPriorities[0] || 'analyze-state', keyMetrics: { filesAnalyzed: Object.keys(projectState.codebase.files).length, totalLines: projectState.codebase.statistics?.totalLines || 0, testFiles: projectState.tests?.testFiles?.length || 0 } }; } // Placeholder methods for future implementation async captureTestState() { return { status: 'pending', testFiles: [] }; } async captureDependencies() { return { npm: [], dev: [] }; } async captureDecisionHistory() { return []; } async captureAutomationState() { return { level: 'basic' }; } async captureDirectoryStructure() { return {}; } async analyzeCompletedFeatures() { return { epics: [], stories: [] }; } async getTestCoverage() { return 'unknown'; } async analyzeCodeComplexity() { return { average: 'medium' }; } async analyzeCICDState() { return { status: 'not-configured' }; } async analyzeAutomationLevel() { return 'basic'; } async captureQualityMetrics() { return {}; } async identifyArchitecturalPatterns() { return []; } async analyzeModuleStructure() { return {}; } async documentInterfaces() { return {}; } async mapDataFlow() { return {}; } async captureDesignDecisions() { return []; } async calculateCodeStatistics() { return { totalLines: 0 }; } async analyzeDependencyGraph() { return {}; } async analyzeFile(content, file) { return { type: 'unknown' }; } determineCurrentSprint(features) { // Logic to determine current sprint based on completed features return 'Sprint 1: Foundation'; } determineNextPriorities(features) { return ['Set up testing infrastructure', 'Implement automation']; } async generateLivingReadme(state) { return `# Calculator Suite - Enterprise Grade Auto-generated: ${state.timestamp} ## Current Status: ${state.phase.currentSprint} Calculator Modes: ${state.progress.calculatorModes.implementationStatus} ## Quick Start \`\`\`bash npm install npm start \`\`\` ## Project State - Phase: ${state.phase.currentSprint} - Test Coverage: ${state.phase.testCoverage} - Automation Level: ${state.progress.automationLevel} For detailed documentation, see docs/automation/ `; } async generateTechnicalDocumentation(state) { return `# Technical Overview Generated: ${state.timestamp} ## Architecture Current phase: ${state.phase.currentSprint} ## Implementation Status ${state.progress.calculatorModes.implemented.map(mode => `✅ ${mode}`).join('\n')} ${state.progress.calculatorModes.pending.map(mode => `⏳ ${mode}`).join('\n')} ## Next Steps ${state.phase.nextPriorities.map(priority => `- ${priority}`).join('\n')} `; } async generateProgressDocumentation(state) { return `# Current Progress Updated: ${state.timestamp} ## Sprint Progress: ${state.phase.currentSprint} ### Completed ${state.phase.completedStories.map(story => `✅ ${story}`).join('\n') || '- Initial setup'} ### In Progress - Context preservation system implementation ### Next ${state.phase.nextPriorities.map(priority => `⏳ ${priority}`).join('\n')} `; } } module.exports = ContextPreservationEngine; // Auto-execute if run directly if (require.main === module) { const engine = new ContextPreservationEngine(); engine.preserveCurrentState() .then(() => console.log('✅ Context preservation completed')) .catch(error => console.error('❌ Context preservation failed:', error)); }