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

264 lines (221 loc) • 8.96 kB
/** * Implementation Verification Script * Tests that automation system is properly installed and functional * Run with: node templates/automation/verify-implementation.js */ const fs = require('fs').promises; const path = require('path'); // SecureProcessManager will be available after installation const SecureProcessManager = require('../../lib/secure-process-manager'); class ImplementationVerifier { constructor() { this.projectRoot = process.cwd(); this.results = { passed: 0, failed: 0, tests: [] }; // Initialize secure process manager this.processManager = new SecureProcessManager({ projectRoot: this.projectRoot, verboseLogging: true, // Enable for verification maxProcesses: 2, defaultTimeoutMs: 30000 // 30 seconds for tests }); } async verifyImplementation() { console.log('šŸ” Verifying Automation Implementation...\n'); // Directory structure tests await this.testDirectoryStructure(); // File existence tests await this.testCoreFiles(); // Configuration tests await this.testConfiguration(); // Functional tests await this.testFunctionality(); // Generate report this.generateReport(); return this.results.failed === 0; } async testDirectoryStructure() { console.log('šŸ“ Testing Directory Structure...'); const requiredDirs = [ 'scripts/automation', 'docs/automation', 'docs/automation/logs', 'docs/state', 'docs/recovery', 'docs/decisions' ]; for (const dir of requiredDirs) { await this.testExists(dir, 'directory'); } } async testCoreFiles() { console.log('šŸ“„ Testing Core Files...'); const requiredFiles = [ { path: 'scripts/automation/context-preservation.js', minSize: 20000 }, { path: 'scripts/automation/daily-automation-cycle.js', minSize: 25000 }, { path: 'scripts/automation/auto-recovery.js', minSize: 15000 }, { path: 'vitest.config.js', minSize: 200 }, { path: 'package.json', minSize: 100 } ]; for (const file of requiredFiles) { await this.testFile(file.path, file.minSize); } } async testConfiguration() { console.log('āš™ļø Testing Configuration...'); try { const packageJson = JSON.parse( await fs.readFile(path.join(this.projectRoot, 'package.json'), 'utf8') ); // Test automation scripts const requiredScripts = [ 'automation:daily', 'automation:preserve', 'automation:recover', 'test' ]; for (const script of requiredScripts) { if (packageJson.scripts && packageJson.scripts[script]) { this.addTest(`package.json has ${script} script`, true); } else { this.addTest(`package.json has ${script} script`, false); } } // Test dependencies const requiredDeps = ['vitest']; const allDeps = { ...packageJson.dependencies, ...packageJson.devDependencies }; for (const dep of requiredDeps) { if (allDeps[dep]) { this.addTest(`${dep} dependency exists`, true); } else { this.addTest(`${dep} dependency exists`, false); } } } catch (error) { this.addTest('package.json is valid JSON', false); } } async testFunctionality() { console.log('šŸš€ Testing Functionality...'); // Test context preservation try { const result = await this.executeCommand('npm', ['run', 'automation:preserve']); this.addTest('Context preservation executes', result.exitCode === 0); } catch (error) { this.addTest('Context preservation executes', false); } // Test automation cycle (with timeout) try { const result = await this.executeCommand('npm', ['run', 'automation:daily'], 30000); this.addTest('Daily automation cycle completes', result.exitCode === 0); } catch (error) { this.addTest('Daily automation cycle completes', false); } // Test test execution try { const result = await this.executeCommand('npm', ['test']); this.addTest('Test command executes', result.exitCode === 0 || result.exitCode === 1); // 1 is OK if no tests exist } catch (error) { this.addTest('Test command executes', false); } // Check generated files await this.testExists('docs/state/current-state-summary.json', 'file'); await this.testExists('docs/automation/latest-daily-report.md', 'file'); } async testExists(filePath, type) { try { const fullPath = path.join(this.projectRoot, filePath); const stats = await fs.stat(fullPath); const isCorrectType = type === 'directory' ? stats.isDirectory() : stats.isFile(); this.addTest(`${filePath} exists and is ${type}`, isCorrectType); } catch (error) { this.addTest(`${filePath} exists and is ${type}`, false); } } async testFile(filePath, minSize) { try { const fullPath = path.join(this.projectRoot, filePath); const stats = await fs.stat(fullPath); this.addTest(`${filePath} exists`, true); this.addTest(`${filePath} has minimum size (${minSize} bytes)`, stats.size >= minSize); } catch (error) { this.addTest(`${filePath} exists`, false); this.addTest(`${filePath} has minimum size (${minSize} bytes)`, false); } } async executeCommand(command, args = [], timeout = 10000) { try { const result = await this.processManager.executeCommand(command, args, { cwd: this.projectRoot, timeout: timeout }); return { exitCode: result.exitCode, stdout: result.stdout, stderr: result.stderr, duration: result.duration }; } catch (error) { return { exitCode: -1, stdout: '', stderr: error.message, duration: 0 }; } } addTest(name, passed) { this.results.tests.push({ name, passed }); if (passed) { this.results.passed++; console.log(` āœ… ${name}`); } else { this.results.failed++; console.log(` āŒ ${name}`); } } generateReport() { console.log('\n' + '='.repeat(60)); console.log('šŸ“Š IMPLEMENTATION VERIFICATION REPORT'); console.log('='.repeat(60)); console.log(`āœ… Passed: ${this.results.passed}`); console.log(`āŒ Failed: ${this.results.failed}`); console.log(`šŸ“Š Total: ${this.results.tests.length}`); console.log(`šŸŽÆ Success Rate: ${((this.results.passed / this.results.tests.length) * 100).toFixed(1)}%`); if (this.results.failed === 0) { console.log('\nšŸŽ‰ IMPLEMENTATION SUCCESSFUL!'); console.log('Your automation system is properly installed and functional.'); console.log('\nNext steps:'); console.log('- Run: npm run automation:daily'); console.log('- Check: docs/automation/latest-daily-report.md'); console.log('- Review: docs/recovery/RECOVERY.md'); } else { console.log('\nāš ļø IMPLEMENTATION INCOMPLETE'); console.log('Please address the failed tests above.'); console.log('\nFailed tests:'); this.results.tests .filter(test => !test.passed) .forEach(test => console.log(` - ${test.name}`)); } console.log('\n' + '='.repeat(60)); } } // Execute verification if run directly if (require.main === module) { const verifier = new ImplementationVerifier(); verifier.verifyImplementation() .then(success => { process.exit(success ? 0 : 1); }) .catch(error => { console.error('āŒ Verification failed:', error); process.exit(1); }); } module.exports = ImplementationVerifier;