context-forge
Version:
AI orchestration platform with autonomous teams, enhancement planning, migration tools, 25+ slash commands, checkpoints & hooks. Multi-IDE: Claude, Cursor, Windsurf, Cline, Copilot
1,035 lines (850 loc) • 34.3 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateEnhancementHooks = generateEnhancementHooks;
async function generateEnhancementHooks(config) {
const files = [];
const enhancement = config.enhancementConfig;
if (!enhancement || !config.extras.hooks) {
return files;
}
// Generate pre-implementation hook
files.push({
path: '.claude/hooks/pre-implementation.py',
content: generatePreImplementationHook(enhancement),
description: 'Pre-implementation validation hook',
});
// Generate feature validation hook
files.push({
path: '.claude/hooks/feature-validation.py',
content: generateFeatureValidationHook(enhancement),
description: 'Feature validation hook',
});
// Generate integration test hook
files.push({
path: '.claude/hooks/integration-test.py',
content: generateIntegrationTestHook(enhancement),
description: 'Integration testing hook',
});
// Generate progress tracking hook
files.push({
path: '.claude/hooks/progress-tracker.py',
content: generateProgressTrackingHook(enhancement),
description: 'Progress tracking hook',
});
// Generate phase completion hook
files.push({
path: '.claude/hooks/phase-completion.py',
content: generatePhaseCompletionHook(enhancement),
description: 'Phase completion validation hook',
});
return files;
}
function generatePreImplementationHook(_enhancement) {
return `#!/usr/bin/env python3
"""
Pre-Implementation Hook for Enhancement Features
Validates environment and dependencies before starting feature implementation
"""
import os
import sys
import json
import subprocess
from datetime import datetime
def log(message, level="INFO"):
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
print(f"[{timestamp}] [{level}] {message}")
def check_environment():
"""Verify development environment is ready"""
log("Checking development environment...")
issues = []
# Check Node/npm
try:
node_version = subprocess.check_output(['node', '--version'], text=True).strip()
log(f"Node version: {node_version}")
except:
issues.append("Node.js not found")
# Check package manager
for pm in ['npm', 'yarn', 'pnpm']:
try:
subprocess.check_output([pm, '--version'], stderr=subprocess.DEVNULL)
log(f"Package manager {pm} available")
break
except:
continue
else:
issues.append("No package manager found")
# Check git status
try:
git_status = subprocess.check_output(['git', 'status', '--porcelain'], text=True)
if git_status.strip():
log("WARNING: Uncommitted changes detected", "WARN")
except:
issues.append("Git not available")
return issues
def validate_feature_dependencies(feature_id):
"""Check if feature dependencies are met"""
log(f"Validating dependencies for feature: {feature_id}")
# Read enhancement config
config_path = "ENHANCEMENT_PLAN.md"
if not os.path.exists(config_path):
return ["Enhancement plan not found"]
# Simple dependency check (in real implementation, parse actual config)
dependencies_met = True
if not dependencies_met:
return [f"Dependencies not met for {feature_id}"]
return []
def check_test_coverage():
"""Verify current test coverage meets threshold"""
log("Checking test coverage...")
try:
# Run coverage check
result = subprocess.run(
['npm', 'run', 'coverage'],
capture_output=True,
text=True
)
# Parse coverage (simplified)
if "Coverage threshold" in result.stdout:
log("Test coverage meets requirements")
else:
return ["Test coverage below threshold"]
except:
log("Unable to check coverage", "WARN")
return []
def main():
log("=== Pre-Implementation Hook Started ===")
# Get context from environment
feature_id = os.getenv('ENHANCEMENT_FEATURE_ID', '')
phase_id = os.getenv('ENHANCEMENT_PHASE_ID', '')
all_issues = []
# Run checks
all_issues.extend(check_environment())
if feature_id:
all_issues.extend(validate_feature_dependencies(feature_id))
all_issues.extend(check_test_coverage())
# Report results
if all_issues:
log("Pre-implementation checks failed:", "ERROR")
for issue in all_issues:
log(f" - {issue}", "ERROR")
# Write status file
with open('.enhancement-status.json', 'w') as f:
json.dump({
'status': 'blocked',
'issues': all_issues,
'timestamp': datetime.now().isoformat()
}, f, indent=2)
sys.exit(1)
else:
log("All pre-implementation checks passed!", "SUCCESS")
# Write status file
with open('.enhancement-status.json', 'w') as f:
json.dump({
'status': 'ready',
'feature': feature_id,
'phase': phase_id,
'timestamp': datetime.now().isoformat()
}, f, indent=2)
log("=== Ready to implement! ===")
if __name__ == "__main__":
main()
`;
}
function generateFeatureValidationHook(_enhancement) {
return `#!/usr/bin/env python3
"""
Feature Validation Hook
Validates feature implementation against acceptance criteria
"""
import os
import sys
import json
import subprocess
import re
from pathlib import Path
class FeatureValidator:
def __init__(self, feature_id):
self.feature_id = feature_id
self.results = {
'feature_id': feature_id,
'checks': {},
'passed': 0,
'failed': 0,
'warnings': 0
}
def validate_code_quality(self):
"""Check code quality standards"""
print(f"Validating code quality for {self.feature_id}...")
# Run linter
try:
result = subprocess.run(
['npm', 'run', 'lint'],
capture_output=True,
text=True
)
if result.returncode == 0:
self.results['checks']['linting'] = 'PASSED'
self.results['passed'] += 1
else:
self.results['checks']['linting'] = 'FAILED'
self.results['failed'] += 1
print(f"Linting errors found:\\n{result.stdout}")
except Exception as e:
self.results['checks']['linting'] = f'ERROR: {str(e)}'
self.results['failed'] += 1
def validate_tests(self):
"""Ensure tests are written and passing"""
print(f"Validating tests...")
# Check for test files
test_patterns = [
f"**/*{self.feature_id}*.test.*",
f"**/*{self.feature_id}*.spec.*"
]
test_files = []
for pattern in test_patterns:
test_files.extend(Path('.').glob(pattern))
if not test_files:
self.results['checks']['test_files'] = 'WARNING: No test files found'
self.results['warnings'] += 1
else:
self.results['checks']['test_files'] = f'PASSED: {len(test_files)} test files'
self.results['passed'] += 1
# Run tests
try:
result = subprocess.run(
['npm', 'test', '--', f'--grep={self.feature_id}'],
capture_output=True,
text=True
)
if result.returncode == 0:
self.results['checks']['test_execution'] = 'PASSED'
self.results['passed'] += 1
else:
self.results['checks']['test_execution'] = 'FAILED'
self.results['failed'] += 1
except:
self.results['checks']['test_execution'] = 'SKIPPED'
def validate_documentation(self):
"""Check if documentation is updated"""
print("Validating documentation...")
doc_files = [
'README.md',
'docs/api.md',
f'docs/features/{self.feature_id}.md'
]
docs_updated = False
for doc_file in doc_files:
if os.path.exists(doc_file):
# Check if file was recently modified
stat = os.stat(doc_file)
# Simple check - in real implementation, compare with git
docs_updated = True
break
if docs_updated:
self.results['checks']['documentation'] = 'PASSED'
self.results['passed'] += 1
else:
self.results['checks']['documentation'] = 'WARNING: Documentation may need updates'
self.results['warnings'] += 1
def validate_integration_points(self):
"""Verify integration points are properly implemented"""
print("Validating integration points...")
# This would check actual integration points from config
# Simplified version here
integration_checks = {
'api_endpoints': self._check_api_endpoints(),
'database_schema': self._check_database_schema(),
'ui_components': self._check_ui_components()
}
for check, result in integration_checks.items():
if result == 'PASSED':
self.results['passed'] += 1
elif result == 'FAILED':
self.results['failed'] += 1
else:
self.results['warnings'] += 1
self.results['checks'][check] = result
def _check_api_endpoints(self):
# Simplified check
return 'PASSED'
def _check_database_schema(self):
# Check for migrations
migration_path = Path('migrations') / f'{self.feature_id}*.sql'
if list(Path('.').glob(str(migration_path))):
return 'PASSED'
return 'WARNING: No migrations found'
def _check_ui_components(self):
# Check for component files
component_path = Path('src/components') / f'*{self.feature_id}*'
if list(Path('src').glob(f'**/*{self.feature_id}*')):
return 'PASSED'
return 'N/A'
def generate_report(self):
"""Generate validation report"""
print("\\n=== Feature Validation Report ===")
print(f"Feature: {self.feature_id}")
print(f"Passed: {self.results['passed']}")
print(f"Failed: {self.results['failed']}")
print(f"Warnings: {self.results['warnings']}")
print("\\nCheck Results:")
for check, result in self.results['checks'].items():
print(f" - {check}: {result}")
# Write results to file
with open(f'.feature-validation-{self.feature_id}.json', 'w') as f:
json.dump(self.results, f, indent=2)
return self.results['failed'] == 0
def main():
feature_id = os.getenv('ENHANCEMENT_FEATURE_ID', sys.argv[1] if len(sys.argv) > 1 else '')
if not feature_id:
print("ERROR: No feature ID provided")
sys.exit(1)
validator = FeatureValidator(feature_id)
# Run validations
validator.validate_code_quality()
validator.validate_tests()
validator.validate_documentation()
validator.validate_integration_points()
# Generate report
success = validator.generate_report()
if not success:
print("\\n❌ Feature validation failed!")
sys.exit(1)
else:
print("\\n✅ Feature validation passed!")
if __name__ == "__main__":
main()
`;
}
function generateIntegrationTestHook(_enhancement) {
return `#!/usr/bin/env python3
"""
Integration Test Hook
Runs integration tests for enhanced features
"""
import os
import sys
import json
import subprocess
import time
from datetime import datetime
class IntegrationTester:
def __init__(self):
self.results = {
'timestamp': datetime.now().isoformat(),
'tests': [],
'summary': {
'total': 0,
'passed': 0,
'failed': 0,
'skipped': 0
}
}
def setup_test_environment(self):
"""Prepare test environment"""
print("Setting up test environment...")
# Start test database
subprocess.run(['docker-compose', 'up', '-d', 'test-db'],
capture_output=True)
time.sleep(5) # Wait for DB
# Run migrations
subprocess.run(['npm', 'run', 'migrate:test'],
capture_output=True)
print("Test environment ready")
def run_api_integration_tests(self):
"""Test API endpoints"""
print("\\nRunning API integration tests...")
result = subprocess.run(
['npm', 'run', 'test:api'],
capture_output=True,
text=True
)
test_result = {
'name': 'API Integration',
'type': 'api',
'passed': result.returncode == 0,
'duration': 0, # Would measure actual duration
'output': result.stdout[-500:] if result.stdout else ''
}
self.results['tests'].append(test_result)
self._update_summary(test_result)
def run_database_integration_tests(self):
"""Test database operations"""
print("\\nRunning database integration tests...")
result = subprocess.run(
['npm', 'run', 'test:db'],
capture_output=True,
text=True
)
test_result = {
'name': 'Database Integration',
'type': 'database',
'passed': result.returncode == 0,
'duration': 0,
'output': result.stdout[-500:] if result.stdout else ''
}
self.results['tests'].append(test_result)
self._update_summary(test_result)
def run_ui_integration_tests(self):
"""Test UI components"""
print("\\nRunning UI integration tests...")
# Start dev server
server_process = subprocess.Popen(
['npm', 'run', 'dev'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
time.sleep(10) # Wait for server
try:
# Run UI tests
result = subprocess.run(
['npm', 'run', 'test:e2e'],
capture_output=True,
text=True
)
test_result = {
'name': 'UI Integration',
'type': 'ui',
'passed': result.returncode == 0,
'duration': 0,
'output': result.stdout[-500:] if result.stdout else ''
}
self.results['tests'].append(test_result)
self._update_summary(test_result)
finally:
server_process.terminate()
def run_feature_specific_tests(self, feature_ids):
"""Run tests for specific features"""
for feature_id in feature_ids:
print(f"\\nRunning tests for feature: {feature_id}")
result = subprocess.run(
['npm', 'test', '--', f'--grep={feature_id}'],
capture_output=True,
text=True
)
test_result = {
'name': f'Feature: {feature_id}',
'type': 'feature',
'passed': result.returncode == 0,
'duration': 0,
'output': result.stdout[-500:] if result.stdout else ''
}
self.results['tests'].append(test_result)
self._update_summary(test_result)
def _update_summary(self, test_result):
self.results['summary']['total'] += 1
if test_result['passed']:
self.results['summary']['passed'] += 1
else:
self.results['summary']['failed'] += 1
def cleanup(self):
"""Clean up test environment"""
print("\\nCleaning up test environment...")
subprocess.run(['docker-compose', 'down'], capture_output=True)
def generate_report(self):
"""Generate test report"""
print("\\n=== Integration Test Report ===")
print(f"Total Tests: {self.results['summary']['total']}")
print(f"Passed: {self.results['summary']['passed']}")
print(f"Failed: {self.results['summary']['failed']}")
if self.results['summary']['failed'] > 0:
print("\\nFailed Tests:")
for test in self.results['tests']:
if not test['passed']:
print(f" - {test['name']}")
if test['output']:
print(f" Output: {test['output'][:200]}...")
# Save report
with open('integration-test-results.json', 'w') as f:
json.dump(self.results, f, indent=2)
return self.results['summary']['failed'] == 0
def main():
feature_ids = os.getenv('ENHANCEMENT_FEATURES', '').split(',')
feature_ids = [f.strip() for f in feature_ids if f.strip()]
tester = IntegrationTester()
try:
tester.setup_test_environment()
# Run different test suites
tester.run_api_integration_tests()
tester.run_database_integration_tests()
tester.run_ui_integration_tests()
if feature_ids:
tester.run_feature_specific_tests(feature_ids)
# Generate report
success = tester.generate_report()
if not success:
print("\\n❌ Integration tests failed!")
sys.exit(1)
else:
print("\\n✅ All integration tests passed!")
finally:
tester.cleanup()
if __name__ == "__main__":
main()
`;
}
function generateProgressTrackingHook(_enhancement) {
return `#!/usr/bin/env python3
"""
Progress Tracking Hook
Tracks and reports enhancement implementation progress
"""
import os
import json
import subprocess
from datetime import datetime, timedelta
from pathlib import Path
class ProgressTracker:
def __init__(self):
self.progress_file = '.enhancement-progress.json'
self.progress = self.load_progress()
def load_progress(self):
"""Load existing progress data"""
if os.path.exists(self.progress_file):
with open(self.progress_file, 'r') as f:
return json.load(f)
return {
'start_date': datetime.now().isoformat(),
'phases': {},
'features': {},
'tasks': {},
'metrics': {
'velocity': [],
'completion_rate': 0,
'estimated_completion': None
}
}
def update_task_status(self, task_id, status):
"""Update individual task status"""
if task_id not in self.progress['tasks']:
self.progress['tasks'][task_id] = {
'created': datetime.now().isoformat(),
'status_history': []
}
self.progress['tasks'][task_id]['status'] = status
self.progress['tasks'][task_id]['status_history'].append({
'status': status,
'timestamp': datetime.now().isoformat()
})
if status == 'completed':
self.progress['tasks'][task_id]['completed'] = datetime.now().isoformat()
def update_feature_progress(self, feature_id):
"""Calculate and update feature progress"""
# Count completed tasks for this feature
feature_tasks = [t for t in self.progress['tasks']
if t.startswith(f"{feature_id}-")]
completed = sum(1 for t in feature_tasks
if self.progress['tasks'].get(t, {}).get('status') == 'completed')
total = len(feature_tasks) or 1
progress = (completed / total) * 100
self.progress['features'][feature_id] = {
'progress': progress,
'completed_tasks': completed,
'total_tasks': total,
'last_updated': datetime.now().isoformat()
}
return progress
def update_phase_progress(self, phase_id):
"""Calculate and update phase progress"""
# Get features in this phase (simplified)
phase_features = [f for f in self.progress['features']
if f in self.progress['features']]
if not phase_features:
return 0
total_progress = sum(self.progress['features'].get(f, {}).get('progress', 0)
for f in phase_features)
phase_progress = total_progress / len(phase_features)
self.progress['phases'][phase_id] = {
'progress': phase_progress,
'last_updated': datetime.now().isoformat()
}
return phase_progress
def calculate_metrics(self):
"""Calculate velocity and other metrics"""
# Calculate completion rate
total_tasks = len(self.progress['tasks'])
completed_tasks = sum(1 for t in self.progress['tasks'].values()
if t.get('status') == 'completed')
if total_tasks > 0:
self.progress['metrics']['completion_rate'] = (completed_tasks / total_tasks) * 100
# Calculate velocity (tasks per day)
if completed_tasks > 0:
start_date = datetime.fromisoformat(self.progress['start_date'])
days_elapsed = (datetime.now() - start_date).days or 1
daily_velocity = completed_tasks / days_elapsed
self.progress['metrics']['velocity'].append({
'date': datetime.now().isoformat(),
'value': daily_velocity
})
# Estimate completion
remaining_tasks = total_tasks - completed_tasks
if daily_velocity > 0:
days_to_complete = remaining_tasks / daily_velocity
estimated_completion = datetime.now() + timedelta(days=days_to_complete)
self.progress['metrics']['estimated_completion'] = estimated_completion.isoformat()
def generate_report(self):
"""Generate progress report"""
print("=== Enhancement Progress Report ===")
print(f"Started: {self.progress['start_date']}")
print(f"Completion Rate: {self.progress['metrics']['completion_rate']:.1f}%")
if self.progress['metrics']['estimated_completion']:
print(f"Estimated Completion: {self.progress['metrics']['estimated_completion']}")
print("\\nPhase Progress:")
for phase_id, phase_data in self.progress['phases'].items():
print(f" - {phase_id}: {phase_data['progress']:.1f}%")
print("\\nFeature Progress:")
for feature_id, feature_data in self.progress['features'].items():
print(f" - {feature_id}: {feature_data['progress']:.1f}% "
f"({feature_data['completed_tasks']}/{feature_data['total_tasks']} tasks)")
# Save progress
self.save_progress()
def save_progress(self):
"""Save progress data"""
with open(self.progress_file, 'w') as f:
json.dump(self.progress, f, indent=2)
def check_git_activity(self):
"""Analyze git commits for progress indicators"""
try:
# Get recent commits
result = subprocess.run(
['git', 'log', '--oneline', '--since=1.day', '--grep=feat:'],
capture_output=True,
text=True
)
commits = result.stdout.strip().split('\\n') if result.stdout else []
print(f"\\nRecent feature commits: {len(commits)}")
for commit in commits[:5]:
print(f" - {commit}")
except:
print("Unable to check git activity")
def main():
tracker = ProgressTracker()
# Get current context
task_id = os.getenv('CURRENT_TASK_ID', '')
feature_id = os.getenv('CURRENT_FEATURE_ID', '')
phase_id = os.getenv('CURRENT_PHASE_ID', '')
status = os.getenv('TASK_STATUS', '')
# Update progress based on context
if task_id and status:
tracker.update_task_status(task_id, status)
print(f"Updated task {task_id} to {status}")
if feature_id:
progress = tracker.update_feature_progress(feature_id)
print(f"Feature {feature_id} progress: {progress:.1f}%")
if phase_id:
progress = tracker.update_phase_progress(phase_id)
print(f"Phase {phase_id} progress: {progress:.1f}%")
# Calculate metrics
tracker.calculate_metrics()
# Check git activity
tracker.check_git_activity()
# Generate report
tracker.generate_report()
if __name__ == "__main__":
main()
`;
}
function generatePhaseCompletionHook(_enhancement) {
return `#!/usr/bin/env python3
"""
Phase Completion Hook
Validates phase completion criteria before allowing transition
"""
import os
import sys
import json
import subprocess
from datetime import datetime
from pathlib import Path
class PhaseCompletionValidator:
def __init__(self, phase_id):
self.phase_id = phase_id
self.results = {
'phase_id': phase_id,
'timestamp': datetime.now().isoformat(),
'checks': {},
'can_proceed': False,
'blockers': []
}
def load_phase_config(self):
"""Load phase configuration"""
# In real implementation, would load from actual config
return {
'name': f'Phase {self.phase_id}',
'features': self._get_phase_features(),
'validation_criteria': [
'All features implemented',
'All tests passing',
'Documentation updated',
'Code review completed'
],
'required_approvals': ['tech_lead', 'product_owner']
}
def _get_phase_features(self):
# Simplified - would get from config
return ['feature-1', 'feature-2']
def validate_features_complete(self, features):
"""Check if all phase features are complete"""
print(f"Validating {len(features)} features...")
incomplete_features = []
for feature_id in features:
# Check feature validation status
validation_file = f'.feature-validation-{feature_id}.json'
if os.path.exists(validation_file):
with open(validation_file, 'r') as f:
validation = json.load(f)
if validation.get('failed', 0) > 0:
incomplete_features.append(feature_id)
else:
incomplete_features.append(feature_id)
if incomplete_features:
self.results['checks']['features'] = f'FAILED: {len(incomplete_features)} incomplete'
self.results['blockers'].append(f"Incomplete features: {', '.join(incomplete_features)}")
return False
else:
self.results['checks']['features'] = 'PASSED: All features complete'
return True
def validate_tests(self):
"""Ensure all tests are passing"""
print("Validating test suite...")
try:
result = subprocess.run(
['npm', 'test'],
capture_output=True,
text=True
)
if result.returncode == 0:
self.results['checks']['tests'] = 'PASSED'
return True
else:
self.results['checks']['tests'] = 'FAILED'
self.results['blockers'].append("Test suite has failures")
return False
except Exception as e:
self.results['checks']['tests'] = f'ERROR: {str(e)}'
self.results['blockers'].append("Unable to run tests")
return False
def validate_documentation(self):
"""Check documentation is updated"""
print("Validating documentation...")
docs_updated = False
required_docs = [
'README.md',
'CHANGELOG.md',
f'docs/phases/{self.phase_id}.md'
]
missing_docs = []
for doc in required_docs:
if not os.path.exists(doc):
missing_docs.append(doc)
if missing_docs:
self.results['checks']['documentation'] = 'WARNING: Missing documentation'
# Not a blocker, just a warning
return True
else:
self.results['checks']['documentation'] = 'PASSED'
return True
def validate_code_quality(self):
"""Check code quality metrics"""
print("Validating code quality...")
quality_checks = {
'linting': self._check_linting(),
'coverage': self._check_coverage(),
'security': self._check_security()
}
all_passed = all(check for check in quality_checks.values())
if all_passed:
self.results['checks']['code_quality'] = 'PASSED'
else:
self.results['checks']['code_quality'] = 'FAILED'
self.results['blockers'].append("Code quality standards not met")
return all_passed
def _check_linting(self):
try:
result = subprocess.run(['npm', 'run', 'lint'],
capture_output=True)
return result.returncode == 0
except:
return False
def _check_coverage(self):
# Check if coverage meets threshold
try:
result = subprocess.run(['npm', 'run', 'coverage'],
capture_output=True, text=True)
# Simple check - would parse actual coverage
return 'Coverage threshold' not in result.stderr
except:
return True # Don't block on coverage
def _check_security(self):
try:
result = subprocess.run(['npm', 'audit', '--audit-level=high'],
capture_output=True)
return result.returncode == 0
except:
return True # Don't block on audit
def check_approvals(self, required_approvals):
"""Check if required approvals are obtained"""
print("Checking approvals...")
# In real implementation, would check actual approval system
approvals_file = f'.phase-{self.phase_id}-approvals.json'
if os.path.exists(approvals_file):
with open(approvals_file, 'r') as f:
approvals = json.load(f)
missing = [a for a in required_approvals if a not in approvals]
if missing:
self.results['checks']['approvals'] = f'PENDING: {", ".join(missing)}'
self.results['blockers'].append(f"Missing approvals: {', '.join(missing)}")
return False
else:
self.results['checks']['approvals'] = 'PASSED'
return True
else:
self.results['checks']['approvals'] = 'PENDING: No approvals found'
self.results['blockers'].append("No approvals recorded")
return False
def generate_report(self):
"""Generate completion report"""
print("\\n=== Phase Completion Report ===")
print(f"Phase: {self.phase_id}")
print(f"Status: {'READY TO PROCEED' if self.results['can_proceed'] else 'BLOCKED'}")
print("\\nValidation Results:")
for check, result in self.results['checks'].items():
status_icon = '✅' if 'PASSED' in result else '❌' if 'FAILED' in result else '⚠️'
print(f" {status_icon} {check}: {result}")
if self.results['blockers']:
print("\\nBlockers:")
for blocker in self.results['blockers']:
print(f" - {blocker}")
# Save report
report_file = f'.phase-{self.phase_id}-completion.json'
with open(report_file, 'w') as f:
json.dump(self.results, f, indent=2)
return self.results['can_proceed']
def main():
phase_id = os.getenv('ENHANCEMENT_PHASE_ID', sys.argv[1] if len(sys.argv) > 1 else '')
if not phase_id:
print("ERROR: No phase ID provided")
sys.exit(1)
validator = PhaseCompletionValidator(phase_id)
config = validator.load_phase_config()
# Run all validations
all_checks_passed = True
all_checks_passed &= validator.validate_features_complete(config['features'])
all_checks_passed &= validator.validate_tests()
all_checks_passed &= validator.validate_documentation()
all_checks_passed &= validator.validate_code_quality()
all_checks_passed &= validator.check_approvals(config['required_approvals'])
validator.results['can_proceed'] = all_checks_passed
# Generate report
can_proceed = validator.generate_report()
if not can_proceed:
print("\\n❌ Phase cannot be completed yet!")
print("Please resolve all blockers before proceeding.")
sys.exit(1)
else:
print("\\n✅ Phase completion validated!")
print("Ready to proceed to next phase.")
if __name__ == "__main__":
main()
`;
}
//# sourceMappingURL=enhancementHooks.js.map