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
JavaScript
/**
* 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;