agentic-qe
Version:
Agentic Quality Engineering Fleet System - AI-driven quality management platform
485 lines ⢠17.5 kB
JavaScript
;
/**
* CLI - Command Line Interface for the Agentic QE Fleet
*
* Provides a comprehensive CLI for managing the fleet, agents, and tasks
* with interactive commands and status monitoring.
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const commander_1 = require("commander");
const chalk_1 = __importDefault(require("chalk"));
const inquirer_1 = __importDefault(require("inquirer"));
const FleetManager_1 = require("../core/FleetManager");
const Config_1 = require("../utils/Config");
const Logger_1 = require("../utils/Logger");
const index_js_1 = require("./commands/workflow/index.js");
const configCommands = __importStar(require("./commands/config/index.js"));
const program = new commander_1.Command();
const logger = Logger_1.Logger.getInstance();
// Global fleet manager instance
let fleetManager = null;
program
.name('agentic-qe')
.description('Agentic Quality Engineering Fleet - Autonomous testing and quality assurance')
.version('1.0.0');
/**
* Initialize fleet
*/
program
.command('init')
.description('Initialize the AQE Fleet')
.option('-c, --config <path>', 'Configuration file path')
.action(async (options) => {
try {
console.log(chalk_1.default.blue('š Initializing Agentic QE Fleet...'));
const config = await Config_1.Config.load(options.config);
fleetManager = new FleetManager_1.FleetManager(config);
await fleetManager.initialize();
console.log(chalk_1.default.green('ā
Fleet initialized successfully'));
}
catch (error) {
console.error(chalk_1.default.red('ā Failed to initialize fleet:'), error);
process.exit(1);
}
});
/**
* Start fleet
*/
program
.command('start')
.description('Start the AQE Fleet')
.option('-d, --daemon', 'Run as daemon')
.action(async (options) => {
try {
if (!fleetManager) {
console.log(chalk_1.default.yellow('Fleet not initialized. Initializing...'));
const config = await Config_1.Config.load();
fleetManager = new FleetManager_1.FleetManager(config);
await fleetManager.initialize();
}
console.log(chalk_1.default.blue('š Starting AQE Fleet...'));
await fleetManager.start();
console.log(chalk_1.default.green('ā
Fleet started successfully'));
if (!options.daemon) {
// Interactive mode
await runInteractiveMode();
}
}
catch (error) {
console.error(chalk_1.default.red('ā Failed to start fleet:'), error);
process.exit(1);
}
});
/**
* Fleet status
*/
program
.command('status')
.description('Show fleet status')
.option('-d, --detailed', 'Show detailed status')
.action(async (options) => {
try {
if (!fleetManager) {
console.log(chalk_1.default.yellow('Fleet not running'));
return;
}
const status = fleetManager.getStatus();
console.log(chalk_1.default.blue('\nš Fleet Status:'));
console.log(`Fleet ID: ${status.id}`);
console.log(`Status: ${getStatusColor(status.status)}`);
console.log(`Active Agents: ${chalk_1.default.cyan(status.activeAgents)}/${chalk_1.default.cyan(status.totalAgents)}`);
console.log(`Running Tasks: ${chalk_1.default.yellow(status.runningTasks)}`);
console.log(`Completed Tasks: ${chalk_1.default.green(status.completedTasks)}`);
console.log(`Failed Tasks: ${chalk_1.default.red(status.failedTasks)}`);
console.log(`Uptime: ${chalk_1.default.magenta(formatUptime(status.uptime))}`);
}
catch (error) {
console.error(chalk_1.default.red('ā Failed to get status:'), error);
process.exit(1);
}
});
/**
* Interactive mode
*/
async function runInteractiveMode() {
console.log(chalk_1.default.green('\nš® Entering interactive mode. Press Ctrl+C to exit.\n'));
while (true) {
try {
const { action } = await inquirer_1.default.prompt([
{
type: 'list',
name: 'action',
message: 'What would you like to do?',
choices: [
'Show fleet status',
'List agents',
'Submit task',
'Spawn agent',
'Exit'
]
}
]);
switch (action) {
case 'Show fleet status':
await showStatus();
break;
case 'Exit':
console.log(chalk_1.default.blue('š Goodbye!'));
await fleetManager?.stop();
process.exit(0);
}
}
catch (error) {
console.error(chalk_1.default.red('Error in interactive mode:'), error);
break;
}
}
}
async function showStatus() {
if (!fleetManager)
return;
const status = fleetManager.getStatus();
console.log(chalk_1.default.blue('\nš Fleet Status:'));
console.log(`Active Agents: ${chalk_1.default.cyan(status.activeAgents)}/${chalk_1.default.cyan(status.totalAgents)}`);
console.log(`Tasks: ${chalk_1.default.yellow(status.runningTasks)} running, ${chalk_1.default.green(status.completedTasks)} completed`);
console.log(`Uptime: ${chalk_1.default.magenta(formatUptime(status.uptime))}\n`);
}
function getStatusColor(status) {
const colors = {
running: chalk_1.default.green,
active: chalk_1.default.green,
idle: chalk_1.default.yellow,
busy: chalk_1.default.blue,
completed: chalk_1.default.green,
failed: chalk_1.default.red,
error: chalk_1.default.red,
stopped: chalk_1.default.gray
};
return (colors[status.toLowerCase()] || chalk_1.default.white)(status);
}
function formatUptime(ms) {
const seconds = Math.floor(ms / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
if (hours > 0)
return `${hours}h ${minutes % 60}m`;
if (minutes > 0)
return `${minutes}m ${seconds % 60}s`;
return `${seconds}s`;
}
/**
* Workflow commands
*/
const workflowCommand = program
.command('workflow')
.description('Manage QE workflows');
workflowCommand
.command('list')
.description('List all workflows')
.option('-s, --status <status>', 'Filter by status (running, paused, completed, failed, cancelled)')
.option('-n, --name <pattern>', 'Filter by name pattern')
.option('-l, --limit <number>', 'Limit number of results', parseInt)
.option('--sort <field>', 'Sort by field (startTime, name, status)', 'startTime')
.option('-f, --format <format>', 'Output format (json, table)', 'table')
.option('-d, --detailed', 'Show detailed information')
.action(async (options) => {
try {
console.log(chalk_1.default.blue('š Listing workflows...\n'));
const result = await (0, index_js_1.listWorkflows)(options);
(0, index_js_1.displayWorkflows)(result);
}
catch (error) {
console.error(chalk_1.default.red('ā Failed to list workflows:'), error);
process.exit(1);
}
});
workflowCommand
.command('pause')
.description('Pause a running workflow')
.argument('<workflow-id>', 'Workflow ID to pause')
.option('-g, --graceful', 'Graceful pause (wait for current step)', true)
.option('-i, --immediate', 'Immediate pause')
.option('-r, --reason <reason>', 'Reason for pausing')
.option('-t, --timeout <ms>', 'Timeout for graceful pause', parseInt, 30000)
.action(async (workflowId, options) => {
try {
console.log(chalk_1.default.blue(`āøļø Pausing workflow ${workflowId}...\n`));
const result = await (0, index_js_1.pauseWorkflow)({
workflowId,
graceful: options.graceful && !options.immediate,
immediate: options.immediate,
reason: options.reason,
timeout: options.timeout
});
(0, index_js_1.displayPauseResult)(result);
}
catch (error) {
console.error(chalk_1.default.red('ā Failed to pause workflow:'), error);
process.exit(1);
}
});
workflowCommand
.command('cancel')
.description('Cancel a workflow')
.argument('<workflow-id>', 'Workflow ID to cancel')
.option('-g, --graceful', 'Graceful cancellation (wait for current step)', true)
.option('-f, --force', 'Force immediate cancellation')
.option('-c, --confirm', 'Confirm forced cancellation', false)
.option('-r, --reason <reason>', 'Reason for cancellation')
.option('--cleanup', 'Clean up workflow resources', true)
.option('--preserve-results', 'Preserve partial results')
.option('--clean-memory', 'Clean up workflow memory')
.option('--retry', 'Retry on failure', false)
.action(async (workflowId, options) => {
try {
// Confirmation prompt for force cancel
if (options.force && !options.confirm) {
const { confirmed } = await inquirer_1.default.prompt([
{
type: 'confirm',
name: 'confirmed',
message: chalk_1.default.yellow('ā ļø Force cancel will immediately stop all workflow operations. Continue?'),
default: false
}
]);
if (!confirmed) {
console.log(chalk_1.default.gray('Cancellation aborted.'));
return;
}
options.confirm = true;
}
console.log(chalk_1.default.blue(`š Cancelling workflow ${workflowId}...\n`));
const result = await (0, index_js_1.cancelWorkflow)({
workflowId,
graceful: options.graceful && !options.force,
force: options.force,
confirm: options.confirm,
reason: options.reason,
cleanup: options.cleanup,
preserveResults: options.preserveResults,
cleanMemory: options.cleanMemory,
retryOnFailure: options.retry
});
(0, index_js_1.displayCancelResult)(result);
}
catch (error) {
console.error(chalk_1.default.red('ā Failed to cancel workflow:'), error);
process.exit(1);
}
});
/**
* Config commands
*/
const configCommand = program
.command('config')
.description('Manage AQE configuration');
configCommand
.command('init')
.description('Initialize configuration file')
.option('-o, --output <path>', 'Output file path', '.aqe/config.json')
.action(async (options) => {
try {
await configCommands.configInit(options);
}
catch (error) {
console.error(chalk_1.default.red('ā Config init failed:'), error);
process.exit(1);
}
});
configCommand
.command('validate')
.description('Validate configuration file')
.option('-f, --file <path>', 'Config file path', '.aqe/config.json')
.action(async (options) => {
try {
await configCommands.configValidate(options);
}
catch (error) {
console.error(chalk_1.default.red('ā Config validation failed:'), error);
process.exit(1);
}
});
configCommand
.command('get')
.description('Get configuration value')
.argument('<key>', 'Configuration key (dot notation supported)')
.option('-f, --file <path>', 'Config file path', '.aqe/config.json')
.option('--json', 'Output as JSON')
.action(async (key, options) => {
try {
await configCommands.configGet({ key, config: options.file });
}
catch (error) {
console.error(chalk_1.default.red('ā Config get failed:'), error);
process.exit(1);
}
});
configCommand
.command('set')
.description('Set configuration value')
.argument('<key>', 'Configuration key (dot notation supported)')
.argument('<value>', 'Value to set')
.option('-f, --file <path>', 'Config file path', '.aqe/config.json')
.action(async (key, value, options) => {
try {
await configCommands.configSet({ key, value, config: options.file });
}
catch (error) {
console.error(chalk_1.default.red('ā Config set failed:'), error);
process.exit(1);
}
});
configCommand
.command('list')
.description('List all configuration values')
.option('-f, --file <path>', 'Config file path', '.aqe/config.json')
.option('--json', 'Output as JSON')
.action(async (options) => {
try {
await configCommands.configList(options);
}
catch (error) {
console.error(chalk_1.default.red('ā Config list failed:'), error);
process.exit(1);
}
});
configCommand
.command('reset')
.description('Reset configuration to defaults')
.option('-f, --file <path>', 'Config file path', '.aqe/config.json')
.option('--force', 'Skip confirmation prompt')
.action(async (options) => {
try {
await configCommands.configReset(options);
}
catch (error) {
console.error(chalk_1.default.red('ā Config reset failed:'), error);
process.exit(1);
}
});
/**
* Debug commands
*/
const debugCommand = program
.command('debug')
.description('Debug and troubleshoot AQE fleet');
debugCommand
.command('agent')
.description('Debug specific agent')
.argument('<agent-id>', 'Agent ID to debug')
.option('-v, --verbose', 'Verbose output')
.action(async (agentId, options) => {
try {
console.log(chalk_1.default.blue(`š Debugging agent ${agentId}...`));
// Implementation would be in debug/agent.ts
}
catch (error) {
console.error(chalk_1.default.red('ā Agent debug failed:'), error);
process.exit(1);
}
});
debugCommand
.command('diagnostics')
.description('Run comprehensive diagnostics')
.option('--full', 'Run full diagnostic suite')
.action(async (options) => {
try {
console.log(chalk_1.default.blue('š Running diagnostics...'));
// Implementation would be in debug/diagnostics.ts
}
catch (error) {
console.error(chalk_1.default.red('ā Diagnostics failed:'), error);
process.exit(1);
}
});
debugCommand
.command('health-check')
.description('Check system health')
.option('--export-report', 'Export health report')
.action(async (options) => {
try {
console.log(chalk_1.default.blue('š Running health check...'));
// Implementation would be in debug/health-check.ts
}
catch (error) {
console.error(chalk_1.default.red('ā Health check failed:'), error);
process.exit(1);
}
});
debugCommand
.command('troubleshoot')
.description('Troubleshoot specific issue')
.argument('<issue>', 'Issue to troubleshoot')
.action(async (issue, options) => {
try {
console.log(chalk_1.default.blue(`š§ Troubleshooting ${issue}...`));
// Implementation would be in debug/troubleshoot.ts
}
catch (error) {
console.error(chalk_1.default.red('ā Troubleshooting failed:'), error);
process.exit(1);
}
});
/**
* Memory commands
*/
const memoryCommand = program
.command('memory')
.description('Manage AQE memory and coordination state');
memoryCommand
.command('stats')
.description('Show memory statistics')
.action(async (options) => {
try {
console.log(chalk_1.default.blue('š Memory Statistics...'));
// Implementation would be in memory/stats.ts
}
catch (error) {
console.error(chalk_1.default.red('ā Memory stats failed:'), error);
process.exit(1);
}
});
memoryCommand
.command('compact')
.description('Compact memory database')
.option('--aggressive', 'Aggressive compaction')
.action(async (options) => {
try {
console.log(chalk_1.default.blue('šļø Compacting memory...'));
// Implementation would be in memory/compact.ts
}
catch (error) {
console.error(chalk_1.default.red('ā Memory compaction failed:'), error);
process.exit(1);
}
});
// Parse command line arguments
program.parse();
//# sourceMappingURL=index.js.map