jay-code
Version:
Streamlined AI CLI orchestration engine with mathematical rigor and enterprise-grade reliability
242 lines (201 loc) • 7.44 kB
text/typescript
/**
* Jay-Code CLI: Streamlined AI orchestration with mathematical rigor
*/
import { JayCodeOrchestrator, TaskRequest, ExecutionContext } from '../models/orchestrator.js';
export interface CLIOptions {
task?: string;
requirements?: string[];
priority?: number;
config?: string;
verbose?: boolean;
output?: string;
}
export class JayCodeCLI {
private orchestrator: JayCodeOrchestrator;
constructor(configPath?: string) {
this.orchestrator = new JayCodeOrchestrator(configPath);
this.setupEventHandlers();
}
private setupEventHandlers(): void {
this.orchestrator.on('task-started', (data) => {
if (process.env.VERBOSE) console.log(`Task started: ${data.taskId}`);
});
this.orchestrator.on('task-completed', (data) => {
console.log(`✓ Task completed: ${data.taskId}`);
});
this.orchestrator.on('task-failed', (data) => {
console.error(`✗ Task failed: ${data.taskId} - ${data.error}`);
});
this.orchestrator.on('model-fallback', (data) => {
console.warn(`⚠ Model fallback activated: ${data.reason}`);
});
}
async executeTask(options: CLIOptions): Promise<void> {
if (!options.task) {
throw new Error('Task description is required');
}
const taskRequest: TaskRequest = {
id: `cli_${Date.now()}`,
description: options.task,
requirements: options.requirements || [],
priority: options.priority || 1,
context: { source: 'cli', timestamp: new Date() }
};
const executionContext: ExecutionContext = {
sessionId: `session_${Date.now()}`,
userId: process.env.USER || 'anonymous',
timestamp: new Date(),
environment: 'development'
};
try {
const result = await this.orchestrator.executeTask(taskRequest, executionContext);
if (result.success) {
console.log('\n=== Jay-Code Execution Results ===');
console.log(`Task: ${taskRequest.description}`);
console.log(`Duration: ${result.metrics.totalDuration}ms`);
if (result.qaReport) {
console.log(`Quality Score: ${result.qaReport.analysis.overallScore.toFixed(2)}`);
console.log(`QA Status: ${result.qaReport.passed ? 'PASSED' : 'FAILED'}`);
}
if (options.output && result.generatedCode) {
const fs = await import('fs');
await fs.promises.writeFile(options.output, result.generatedCode);
console.log(`Code saved to: ${options.output}`);
} else if (result.generatedCode) {
console.log('\n=== Generated Code ===');
console.log(result.generatedCode);
}
if (result.warnings.length > 0) {
console.log('\n=== Warnings ===');
result.warnings.forEach(w => console.warn(`⚠ ${w}`));
}
} else {
console.error('\n=== Execution Failed ===');
result.errors.forEach(e => console.error(`✗ ${e}`));
process.exit(1);
}
} catch (error) {
console.error(`Fatal error: ${error.message}`);
process.exit(1);
}
}
async healthCheck(): Promise<void> {
try {
const health = await this.orchestrator.healthCheck();
console.log('\n=== Jay-Code Health Status ===');
console.log(`Overall Status: ${health.status.toUpperCase()}`);
console.log('Components:');
Object.entries(health.components).forEach(([component, status]) => {
const icon = status ? '✓' : '✗';
console.log(` ${icon} ${component}: ${status ? 'healthy' : 'failed'}`);
});
console.log(`Active Tasks: ${health.metrics.activeTasks}`);
console.log(`Uptime: ${Math.round(health.metrics.uptime)}s`);
if (health.status !== 'healthy') {
process.exit(1);
}
} catch (error) {
console.error(`Health check failed: ${error.message}`);
process.exit(1);
}
}
async getMetrics(): Promise<void> {
try {
const metrics = this.orchestrator.getMetrics();
console.log('\n=== Jay-Code Metrics ===');
console.log(JSON.stringify(metrics, null, 2));
} catch (error) {
console.error(`Failed to get metrics: ${error.message}`);
process.exit(1);
}
}
}
// CLI Command Processing
export async function main(): Promise<void> {
const args = process.argv.slice(2);
const command = args[0];
if (!command) {
console.log(`
Jay-Code: Streamlined AI CLI orchestration engine
Usage:
jay-code init
jay-code generate "task description" [options]
jay-code health
jay-code metrics
jay-code --help
Options:
--requirements Comma-separated requirements
--priority Task priority (1-10)
--config Path to configuration file
--output Output file for generated code
--verbose Enable verbose logging
Examples:
jay-code init # Initialize session and analyze project
jay-code init
jay-code generate "Create a TypeScript function to validate email addresses"
jay-code init
jay-code generate "Build a REST API for user management" --requirements "Express.js,TypeScript,validation"
jay-code health
`);
return;
}
const cli = new JayCodeCLI();
switch (command) {
case "init":
await cli.initialize();
break;
case 'generate':
const task = args[1];
const requirementsFlag = args.indexOf('--requirements');
const priorityFlag = args.indexOf('--priority');
const outputFlag = args.indexOf('--output');
const verboseFlag = args.indexOf('--verbose');
const options: CLIOptions = {
task,
requirements: requirementsFlag >= 0 ? args[requirementsFlag + 1]?.split(',') : [],
priority: priorityFlag >= 0 ? parseInt(args[priorityFlag + 1]) : 1,
output: outputFlag >= 0 ? args[outputFlag + 1] : undefined,
verbose: verboseFlag >= 0
};
if (options.verbose) process.env.VERBOSE = 'true';
await cli.executeTask(options);
break;
case 'health':
await cli.healthCheck();
break;
case 'metrics':
await cli.getMetrics();
break;
case '--help':
console.log('Help text already shown above');
break;
default:
console.error(`Unknown command: ${command}`);
console.error('Use "jay-code --help" for usage information');
process.exit(1);
}
}
if (import.meta.url === `file://${process.argv[1]}`) {
main().catch(error => {
console.error('Fatal error:', error);
process.exit(1);
});
}
async initialize(): Promise<void> {
const { JayInitializationSystem } = await import('../core/jay-initialization.js');
console.log('Jay-Code Session Initialization');
console.log('Loading development philosophy and analyzing project...');
try {
const initSystem = new JayInitializationSystem();
const masterDocument = await initSystem.initialize();
console.log('\nSession initialized successfully!');
console.log(`Project: ${masterDocument.projectContext.projectName}`);
console.log(`Complexity: ${masterDocument.architecturalAnalysis.sophisticationLevel}`);
console.log(`Files analyzed: ${masterDocument.codebaseMapping.totalFiles}`);
console.log(`Master document: ${masterDocument.id}`);
} catch (error) {
console.error('Initialization failed:', error.message);
throw error;
}
}