claude-flow-tbowman01
Version:
Enterprise-grade AI agent orchestration with ruv-swarm integration (Alpha Release)
319 lines • 11.9 kB
JavaScript
/**
* Compatible Terminal UI - Works without raw mode
* Designed for environments that don't support stdin raw mode
*/
import readline from 'readline';
import chalk from 'chalk';
export class CompatibleUI {
processes = [];
running = false;
rl;
constructor() {
this.rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
terminal: false, // Don't require raw mode
});
}
async start() {
this.running = true;
// Initial render
this.render();
// Setup command loop
while (this.running) {
const command = await this.promptCommand();
await this.handleCommand(command);
}
}
stop() {
this.running = false;
this.rl.close();
console.clear();
}
updateProcesses(processes) {
this.processes = processes;
if (this.running) {
this.render();
}
}
async promptCommand() {
return new Promise((resolve) => {
this.rl.question('\nCommand: ', (answer) => {
resolve(answer.trim());
});
});
}
async handleCommand(input) {
switch (input.toLowerCase()) {
case 'q':
case 'quit':
case 'exit':
await this.handleExit();
break;
case 'r':
case 'refresh':
this.render();
break;
case 'h':
case 'help':
case '?':
this.showHelp();
break;
case 's':
case 'status':
this.showStatus();
break;
case 'l':
case 'list':
this.showProcessList();
break;
default:
// Check if it's a number (process selection)
const num = parseInt(input);
if (!isNaN(num) && num >= 1 && num <= this.processes.length) {
await this.showProcessDetails(this.processes[num - 1]);
}
else {
console.log(chalk.yellow('Invalid command. Type "h" for help.'));
}
break;
}
}
render() {
console.clear();
const stats = this.getSystemStats();
// Header
console.log(chalk.cyan.bold('🧠 Claude-Flow System Monitor'));
console.log(chalk.gray('─'.repeat(60)));
// System stats
console.log(chalk.white('System Status:'), chalk.green(`${stats.runningProcesses}/${stats.totalProcesses} running`));
if (stats.errorProcesses > 0) {
console.log(chalk.red(`⚠️ ${stats.errorProcesses} processes with errors`));
}
console.log();
// Process list
console.log(chalk.white.bold('Processes:'));
console.log(chalk.gray('─'.repeat(60)));
if (this.processes.length === 0) {
console.log(chalk.gray('No processes configured'));
}
else {
this.processes.forEach((process, index) => {
const num = `[${index + 1}]`.padEnd(4);
const status = this.getStatusDisplay(process.status);
const name = process.name.padEnd(25);
console.log(`${chalk.gray(num)} ${status} ${chalk.white(name)}`);
if (process.metrics?.lastError) {
console.log(chalk.red(` Error: ${process.metrics.lastError}`));
}
});
}
// Footer
console.log(chalk.gray('─'.repeat(60)));
console.log(chalk.gray('Commands: [1-9] Process details [s] Status [l] List [r] Refresh [h] Help [q] Quit'));
}
showStatus() {
const stats = this.getSystemStats();
console.log();
console.log(chalk.cyan.bold('📊 System Status Details'));
console.log(chalk.gray('─'.repeat(40)));
console.log(chalk.white('Total Processes:'), stats.totalProcesses);
console.log(chalk.white('Running:'), chalk.green(stats.runningProcesses));
console.log(chalk.white('Stopped:'), chalk.gray(stats.totalProcesses - stats.runningProcesses - stats.errorProcesses));
console.log(chalk.white('Errors:'), chalk.red(stats.errorProcesses));
console.log(chalk.white('System Load:'), this.getSystemLoad());
console.log(chalk.white('Uptime:'), this.getSystemUptime());
}
showProcessList() {
console.log();
console.log(chalk.cyan.bold('📋 Process List'));
console.log(chalk.gray('─'.repeat(60)));
if (this.processes.length === 0) {
console.log(chalk.gray('No processes configured'));
return;
}
this.processes.forEach((process, index) => {
console.log(`${chalk.gray(`[${index + 1}]`)} ${this.getStatusDisplay(process.status)} ${chalk.white.bold(process.name)}`);
console.log(chalk.gray(` Type: ${process.type}`));
if (process.pid) {
console.log(chalk.gray(` PID: ${process.pid}`));
}
if (process.startTime) {
const uptime = Date.now() - process.startTime;
console.log(chalk.gray(` Uptime: ${this.formatUptime(uptime)}`));
}
if (process.metrics) {
if (process.metrics.cpu !== undefined) {
console.log(chalk.gray(` CPU: ${process.metrics.cpu.toFixed(1)}%`));
}
if (process.metrics.memory !== undefined) {
console.log(chalk.gray(` Memory: ${process.metrics.memory.toFixed(0)} MB`));
}
}
console.log();
});
}
async showProcessDetails(process) {
console.log();
console.log(chalk.cyan.bold(`📋 Process Details: ${process.name}`));
console.log(chalk.gray('─'.repeat(60)));
console.log(chalk.white('ID:'), process.id);
console.log(chalk.white('Type:'), process.type);
console.log(chalk.white('Status:'), this.getStatusDisplay(process.status), process.status);
if (process.pid) {
console.log(chalk.white('PID:'), process.pid);
}
if (process.startTime) {
const uptime = Date.now() - process.startTime;
console.log(chalk.white('Uptime:'), this.formatUptime(uptime));
}
if (process.metrics) {
console.log();
console.log(chalk.white.bold('Metrics:'));
if (process.metrics.cpu !== undefined) {
console.log(chalk.white('CPU:'), `${process.metrics.cpu.toFixed(1)}%`);
}
if (process.metrics.memory !== undefined) {
console.log(chalk.white('Memory:'), `${process.metrics.memory.toFixed(0)} MB`);
}
if (process.metrics.restarts !== undefined) {
console.log(chalk.white('Restarts:'), process.metrics.restarts);
}
if (process.metrics.lastError) {
console.log(chalk.red('Last Error:'), process.metrics.lastError);
}
}
}
getStatusDisplay(status) {
switch (status) {
case 'running':
return chalk.green('●');
case 'stopped':
return chalk.gray('○');
case 'starting':
return chalk.yellow('◐');
case 'stopping':
return chalk.yellow('◑');
case 'error':
return chalk.red('✗');
case 'crashed':
return chalk.red('☠');
default:
return chalk.gray('?');
}
}
getSystemStats() {
return {
totalProcesses: this.processes.length,
runningProcesses: this.processes.filter((p) => p.status === 'running').length,
errorProcesses: this.processes.filter((p) => p.status === 'error' || p.status === 'crashed')
.length,
};
}
getSystemLoad() {
// Simulate system load
return '0.45, 0.52, 0.48';
}
getSystemUptime() {
const uptime = process.uptime() * 1000;
return this.formatUptime(uptime);
}
formatUptime(ms) {
const seconds = Math.floor(ms / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
if (days > 0) {
return `${days}d ${hours % 24}h`;
}
else if (hours > 0) {
return `${hours}h ${minutes % 60}m`;
}
else if (minutes > 0) {
return `${minutes}m ${seconds % 60}s`;
}
else {
return `${seconds}s`;
}
}
showHelp() {
console.log();
console.log(chalk.cyan.bold('🧠 Claude-Flow System Monitor - Help'));
console.log(chalk.gray('─'.repeat(60)));
console.log();
console.log(chalk.white.bold('Commands:'));
console.log(' 1-9 - Show process details by number');
console.log(' s - Show system status');
console.log(' l - List all processes');
console.log(' r - Refresh display');
console.log(' h/? - Show this help');
console.log(' q - Quit');
console.log();
console.log(chalk.white.bold('Features:'));
console.log(' • Non-interactive mode (works in any terminal)');
console.log(' • Real-time process monitoring');
console.log(' • System statistics');
console.log(' • Compatible with VS Code, CI/CD, containers');
}
async handleExit() {
const runningProcesses = this.processes.filter((p) => p.status === 'running');
if (runningProcesses.length > 0) {
console.log();
console.log(chalk.yellow(`⚠️ ${runningProcesses.length} processes are still running.`));
console.log('These processes will continue running in the background.');
console.log('Use the main CLI to stop them if needed.');
}
this.stop();
}
}
// Factory function to create UI instances
export function createCompatibleUI() {
return new CompatibleUI();
}
// Check if raw mode is supported
export function isRawModeSupported() {
try {
return process.stdin.isTTY && typeof process.stdin.setRawMode === 'function';
}
catch {
return false;
}
}
// Fallback UI launcher that chooses the best available UI
export async function launchUI() {
const ui = createCompatibleUI();
// Mock some example processes for demonstration
const mockProcesses = [
{
id: 'orchestrator',
name: 'Orchestrator Engine',
status: 'running',
type: 'core',
pid: 12345,
startTime: Date.now() - 30000,
metrics: { cpu: 2.1, memory: 45.2, restarts: 0 },
},
{
id: 'memory-manager',
name: 'Memory Manager',
status: 'running',
type: 'service',
pid: 12346,
startTime: Date.now() - 25000,
metrics: { cpu: 0.8, memory: 12.5, restarts: 0 },
},
{
id: 'mcp-server',
name: 'MCP Server',
status: 'stopped',
type: 'server',
metrics: { restarts: 1 },
},
];
ui.updateProcesses(mockProcesses);
console.log(chalk.green('✅ Starting Claude-Flow UI (compatible mode)'));
console.log(chalk.gray('Note: Using compatible UI mode for broader terminal support'));
console.log();
await ui.start();
}
//# sourceMappingURL=compatible-ui.js.map