mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-22 03:04:03 +00:00
336 lines
11 KiB
JavaScript
Executable File
336 lines
11 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
/**
|
|
* AI Helper Script
|
|
*
|
|
* This script is designed to help AI assistants run commands and immediately see their output
|
|
* without getting stuck waiting for long-running processes to complete.
|
|
*
|
|
* It runs a command in the background, captures the initial output, and returns control to the terminal.
|
|
*
|
|
* Usage:
|
|
* node scripts/ai-helper.js [command] [options]
|
|
*
|
|
* Commands:
|
|
* start-server Start the server in the background
|
|
* check-logs Check the most recent logs
|
|
* check-cluster Check cluster-related logs
|
|
* check-status Check if the server is running
|
|
* stop-server Stop the server
|
|
* verify-config Verify the current environment configuration
|
|
*
|
|
* Options:
|
|
* --env=<env> Environment (prod, dev, or dev:no-cluster, default: prod)
|
|
* --lines=<number> Number of log lines to show (default: 20)
|
|
* --help Show this help message
|
|
*
|
|
* Examples:
|
|
* node scripts/ai-helper.js start-server --env=prod
|
|
* node scripts/ai-helper.js check-logs --lines=50
|
|
* node scripts/ai-helper.js check-cluster
|
|
* node scripts/ai-helper.js verify-config
|
|
*/
|
|
|
|
const { execSync, spawn } = require('child_process');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
// Parse command line arguments
|
|
const args = process.argv.slice(2);
|
|
const command = args[0];
|
|
const options = {
|
|
env: getArgValue(args, '--env') || 'prod',
|
|
lines: parseInt(getArgValue(args, '--lines') || '20', 10),
|
|
help: args.includes('--help') || args.includes('-h')
|
|
};
|
|
|
|
// Show help if requested or no command provided
|
|
if (options.help || !command) {
|
|
console.log(fs.readFileSync(__filename, 'utf8')
|
|
.split('\n')
|
|
.filter(line => line.startsWith(' *'))
|
|
.map(line => line.substring(3))
|
|
.join('\n'));
|
|
process.exit(0);
|
|
}
|
|
|
|
// Validate environment
|
|
if (!['prod', 'prod:no-cluster', 'dev', 'dev:no-cluster'].includes(options.env)) {
|
|
console.error(`Error: Unknown environment "${options.env}". Use "prod", "prod:no-cluster", "dev", or "dev:no-cluster".`);
|
|
process.exit(1);
|
|
}
|
|
|
|
// Ensure logs directory exists
|
|
if (!fs.existsSync('logs')) {
|
|
fs.mkdirSync('logs');
|
|
}
|
|
|
|
// Create a unique log file for this run
|
|
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
|
const logFile = `logs/ai-helper-${timestamp}.log`;
|
|
|
|
// Execute the requested command
|
|
switch (command) {
|
|
case 'start-server':
|
|
startServer(options.env);
|
|
break;
|
|
case 'check-logs':
|
|
checkLogs(options.lines);
|
|
break;
|
|
case 'check-cluster':
|
|
checkClusterLogs(options.lines);
|
|
break;
|
|
case 'check-status':
|
|
checkStatus();
|
|
break;
|
|
case 'stop-server':
|
|
stopServer();
|
|
break;
|
|
case 'verify-config':
|
|
verifyConfig();
|
|
break;
|
|
default:
|
|
console.error(`Unknown command: ${command}`);
|
|
console.log('Run with --help to see available commands');
|
|
process.exit(1);
|
|
}
|
|
|
|
// Helper function to get argument value
|
|
function getArgValue(args, name) {
|
|
const arg = args.find(a => a.startsWith(`${name}=`));
|
|
return arg ? arg.split('=')[1] : null;
|
|
}
|
|
|
|
// Start the server in the background
|
|
function startServer(env) {
|
|
console.log(`Starting server in ${env} mode...`);
|
|
|
|
try {
|
|
// First, configure the environment
|
|
execSync(`node scripts/configure-env.js ${env}`, { stdio: 'inherit' });
|
|
|
|
// Build the application if needed
|
|
if (env === 'prod') {
|
|
console.log('Building the application...');
|
|
execSync('npm run build', { stdio: 'inherit' });
|
|
}
|
|
|
|
// Start the server in the background
|
|
const serverProcess = spawn('node', [
|
|
env === 'prod' ? 'dist/server.js' : 'scripts/start.js',
|
|
env === 'prod' ? '' : 'dev:mock'
|
|
].filter(Boolean), {
|
|
detached: true,
|
|
stdio: ['ignore', fs.openSync(logFile, 'w'), fs.openSync(logFile, 'w')]
|
|
});
|
|
|
|
// Don't wait for the server to exit
|
|
serverProcess.unref();
|
|
|
|
console.log(`Server started with PID ${serverProcess.pid}`);
|
|
console.log(`Logs are being written to ${logFile}`);
|
|
|
|
// Wait a moment for the server to start
|
|
setTimeout(() => {
|
|
// Show the initial logs
|
|
console.log('\nInitial server logs:');
|
|
try {
|
|
const initialLogs = execSync(`tail -n 20 ${logFile}`).toString();
|
|
console.log(initialLogs || 'No logs yet');
|
|
} catch (error) {
|
|
console.log('No logs available yet');
|
|
}
|
|
|
|
console.log('\nTo check logs later, run:');
|
|
console.log(` node scripts/ai-helper.js check-logs`);
|
|
console.log('To stop the server, run:');
|
|
console.log(` node scripts/ai-helper.js stop-server`);
|
|
|
|
// For development mode, remind the user to access the application on port 7654
|
|
if (env !== 'prod') {
|
|
console.log('\nAccess the application at:');
|
|
console.log(' http://localhost:7654');
|
|
}
|
|
}, 2000);
|
|
} catch (error) {
|
|
console.error('Error starting server:', error.message);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
// Check the most recent logs
|
|
function checkLogs(lines) {
|
|
console.log(`Checking the most recent logs (${lines} lines)...`);
|
|
|
|
try {
|
|
// Find the most recent log file
|
|
const logDir = path.resolve(process.cwd(), 'logs');
|
|
const logFiles = fs.readdirSync(logDir)
|
|
.filter(file => file.endsWith('.log'))
|
|
.map(file => ({
|
|
name: file,
|
|
time: fs.statSync(path.join(logDir, file)).mtime.getTime()
|
|
}))
|
|
.sort((a, b) => b.time - a.time);
|
|
|
|
if (logFiles.length === 0) {
|
|
console.log('No log files found');
|
|
return;
|
|
}
|
|
|
|
const recentLogFile = path.join(logDir, logFiles[0].name);
|
|
console.log(`Most recent log file: ${recentLogFile}`);
|
|
|
|
// Show the logs
|
|
const logs = execSync(`tail -n ${lines} ${recentLogFile}`).toString();
|
|
console.log('\nRecent logs:');
|
|
console.log(logs || 'No logs found');
|
|
} catch (error) {
|
|
console.error('Error checking logs:', error.message);
|
|
}
|
|
}
|
|
|
|
// Check cluster-related logs
|
|
function checkClusterLogs(lines) {
|
|
console.log('Checking cluster-related logs...');
|
|
|
|
try {
|
|
// Find the most recent log file
|
|
const logDir = path.resolve(process.cwd(), 'logs');
|
|
const logFiles = fs.readdirSync(logDir)
|
|
.filter(file => file.endsWith('.log'))
|
|
.map(file => ({
|
|
name: file,
|
|
time: fs.statSync(path.join(logDir, file)).mtime.getTime()
|
|
}))
|
|
.sort((a, b) => b.time - a.time);
|
|
|
|
if (logFiles.length === 0) {
|
|
console.log('No log files found');
|
|
return;
|
|
}
|
|
|
|
const recentLogFile = path.join(logDir, logFiles[0].name);
|
|
console.log(`Searching in: ${recentLogFile}`);
|
|
|
|
// Search for cluster-related logs
|
|
const grepCommand = `grep -i "cluster\\|clusterMode\\|autoDetectCluster" ${recentLogFile} | tail -n ${lines}`;
|
|
try {
|
|
const clusterLogs = execSync(grepCommand).toString();
|
|
console.log('\nCluster-related logs:');
|
|
console.log(clusterLogs || 'No cluster-related logs found');
|
|
} catch (error) {
|
|
// grep returns exit code 1 if no matches found
|
|
console.log('No cluster-related logs found');
|
|
}
|
|
} catch (error) {
|
|
console.error('Error checking cluster logs:', error.message);
|
|
}
|
|
}
|
|
|
|
// Check if the server is running
|
|
function checkStatus() {
|
|
console.log('Checking server status...');
|
|
|
|
try {
|
|
const psOutput = execSync('ps aux | grep "[n]ode.*server.js\\|[n]ode.*start.js"').toString();
|
|
console.log('\nRunning server processes:');
|
|
console.log(psOutput || 'No server processes found');
|
|
|
|
// Check if the frontend is responding
|
|
try {
|
|
console.log('\nChecking frontend on port 7654:');
|
|
// Just check if we get a 200 response, don't try to parse the HTML
|
|
const frontendResponse = execSync('curl -s -o /dev/null -w "%{http_code}" http://localhost:7654/').toString();
|
|
if (frontendResponse.trim() === '200') {
|
|
console.log('✅ Frontend is responding (HTTP 200)');
|
|
} else {
|
|
console.log(`❌ Frontend returned HTTP ${frontendResponse}`);
|
|
}
|
|
} catch (error) {
|
|
console.log('❌ Frontend is not responding');
|
|
}
|
|
|
|
// Check if the mock server is responding (in dev mode)
|
|
try {
|
|
console.log('\nChecking mock server on port 7656:');
|
|
const mockResponse = execSync('curl -s -o /dev/null -w "%{http_code}" http://localhost:7656/').toString();
|
|
if (mockResponse.trim() === '200') {
|
|
console.log('✅ Mock server is responding (HTTP 200)');
|
|
} else {
|
|
console.log(`❌ Mock server returned HTTP ${mockResponse}`);
|
|
}
|
|
} catch (error) {
|
|
console.log('❌ Mock server is not responding (this is normal in production mode)');
|
|
}
|
|
|
|
// Check if the API is responding
|
|
try {
|
|
console.log('\nChecking API on port 7654 (via frontend proxy):');
|
|
const apiResponse = execSync('curl -s http://localhost:7654/api/nodes | head -n 5').toString();
|
|
if (apiResponse && apiResponse.includes('nodes')) {
|
|
console.log('✅ API is responding via frontend proxy');
|
|
console.log('First few lines of API response:');
|
|
console.log(apiResponse);
|
|
} else {
|
|
console.log('❌ API response via frontend proxy is invalid');
|
|
console.log(apiResponse);
|
|
}
|
|
} catch (error) {
|
|
console.log('❌ API is not responding via frontend proxy');
|
|
|
|
// Try direct API access on port 7656 (for development mode)
|
|
try {
|
|
console.log('\nTrying direct API access on port 7656:');
|
|
const directApiResponse = execSync('curl -s http://localhost:7656/api/nodes | head -n 5').toString();
|
|
console.log(directApiResponse);
|
|
console.log('✅ API is responding directly on port 7656');
|
|
} catch (error) {
|
|
console.log('❌ API is not responding on port 7656 either');
|
|
}
|
|
}
|
|
|
|
console.log('\nServer information:');
|
|
console.log('- The frontend is running on port 7654 (accessible in browser)');
|
|
console.log('- The backend API is running on port 7656 (internal only)');
|
|
console.log('- The mock data server is running on port 7656 (in development mode)');
|
|
|
|
} catch (error) {
|
|
console.log('No server processes found');
|
|
}
|
|
}
|
|
|
|
// Stop the server
|
|
function stopServer() {
|
|
console.log('Stopping server processes...');
|
|
|
|
try {
|
|
// Kill processes by pattern
|
|
execSync('pkill -f "node.*server.js\\|node.*start.js\\|vite"');
|
|
console.log('Server processes stopped by pattern');
|
|
} catch (error) {
|
|
console.log('No matching processes found to stop by pattern');
|
|
}
|
|
|
|
try {
|
|
// Kill processes by port
|
|
execSync('npx kill-port 7654 7656 3000');
|
|
console.log('Processes on ports 7654, 7656, and 3000 stopped');
|
|
} catch (error) {
|
|
console.log('No processes found on ports 7654, 7656, or 3000');
|
|
}
|
|
|
|
console.log('All server processes have been stopped');
|
|
}
|
|
|
|
// Verify the current environment configuration
|
|
function verifyConfig() {
|
|
console.log('Verifying environment configuration...');
|
|
|
|
try {
|
|
execSync('node scripts/verify-cluster-config.js', { stdio: 'inherit' });
|
|
} catch (error) {
|
|
console.error('Error verifying configuration:', error.message);
|
|
process.exit(1);
|
|
}
|
|
}
|