All files / agent/src main.ts

0% Statements 0/89
0% Branches 0/1
0% Functions 0/1
0% Lines 0/89

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89                                                                                                                                                                                 
#!/usr/bin/env node

/**
 * BuildHive Agent - Main Entry Point
 * 
 * Main entry point for the BuildHive agent that coordinates with the platform
 * to execute CI jobs in isolated Docker containers.
 * 
 * Requirements: 1.1, 1.2, 1.5, 1.6, 4.1, 4.2, 4.3, 4.4, 4.5
 */

import { BuildHiveAgent } from './agent.js';
import { loadConfig } from './config/index.js';
import { createLogger } from './utils/logger.js';
import { checkStartupVersion } from './autoUpdater.js';

const logger = createLogger('main');

/**
 * Main function to start the BuildHive agent
 */
async function main(): Promise<void> {
  try {
    logger.info('Starting BuildHive Agent...');

    // Load configuration
    const config = await loadConfig();
    logger.info(`Loaded configuration for agent: ${config.name}`);

    // Check for updates before starting (Task 2.1.3)
    // Reads version from package.json; auto-update only if config opts in
    const { createRequire } = await import('module');
    const require = createRequire(import.meta.url);
    const pkg = require('../package.json') as { version: string };
    await checkStartupVersion({
      localVersion: pkg.version,
      autoUpdate: config.enableAutoUpdates,
    });

    // Create and start agent with capability detection
    const agent = await BuildHiveAgent.create(config);
    
    // Handle graceful shutdown
    const shutdown = async (signal: string) => {
      logger.info(`Received ${signal}, shutting down gracefully...`);
      try {
        await agent.stop();
        logger.info('Agent stopped successfully');
        process.exit(0);
      } catch (error) {
        logger.error('Error during shutdown:', error);
        process.exit(1);
      }
    };

    process.on('SIGINT', () => shutdown('SIGINT'));
    process.on('SIGTERM', () => shutdown('SIGTERM'));
    process.on('SIGQUIT', () => shutdown('SIGQUIT'));

    // Handle uncaught exceptions
    process.on('uncaughtException', (error) => {
      logger.error('Uncaught exception:', error);
      shutdown('uncaughtException').catch(() => process.exit(1));
    });

    process.on('unhandledRejection', (reason, promise) => {
      logger.error('Unhandled rejection at:', promise, 'reason:', reason);
      shutdown('unhandledRejection').catch(() => process.exit(1));
    });

    // Start the agent
    await agent.start();
    logger.info('BuildHive Agent started successfully');

  } catch (error) {
    logger.error('Failed to start BuildHive Agent:', error);
    process.exit(1);
  }
}

// Run main function if this file is executed directly
if (import.meta.url === `file://${process.argv[1]}`) {
  main().catch((error) => {
    console.error('Fatal error:', error);
    process.exit(1);
  });
}

export { main };