agentic-qe
Version:
Agentic Quality Engineering Fleet System - AI-driven quality management platform
280 lines (274 loc) โข 12.4 kB
JavaScript
;
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 });
exports.FleetRestartCommand = void 0;
const chalk_1 = __importDefault(require("chalk"));
const fs = __importStar(require("fs-extra"));
class FleetRestartCommand {
static async execute(options) {
// Check if fleet is initialized
if (!await fs.pathExists('.agentic-qe/config/fleet.json')) {
throw new Error('Fleet not initialized. Run: aqe fleet init');
}
console.log(chalk_1.default.blue.bold('\n๐ Fleet Restart\n'));
const fleetConfig = await fs.readJson('.agentic-qe/config/fleet.json');
// Determine restart mode
const mode = options.force ? 'force' : 'graceful';
if (options.force) {
console.log(chalk_1.default.yellow('โ ๏ธ Force restart requested - agents will be stopped immediately'));
}
else {
console.log(chalk_1.default.blue('๐ Graceful restart - waiting for running tasks to complete'));
}
// Pre-restart backup
await this.createRestartBackup(fleetConfig);
// Update fleet status
await this.updateFleetStatus('restarting');
// Stop agents gracefully or forcefully
if (options.graceful) {
await this.gracefulStop();
}
else if (options.force) {
await this.forceStop();
}
// Clear runtime data
await this.clearRuntimeData();
// Restart agents
await this.restartAgents(fleetConfig);
// Update fleet status
await this.updateFleetStatus('running');
// Verify restart success
const restartSuccess = await this.verifyRestart();
if (!restartSuccess && options.rollback) {
console.log(chalk_1.default.red('โ Restart verification failed - rolling back...'));
await this.rollbackRestart();
throw new Error('Fleet restart failed and was rolled back');
}
console.log(chalk_1.default.green('\nโ
Fleet restarted successfully'));
// Store restart in coordination
await this.storeRestartOperation(mode, restartSuccess);
}
static async createRestartBackup(fleetConfig) {
console.log(chalk_1.default.blue('๐พ Creating pre-restart backup...'));
const backupDir = `.agentic-qe/backups/restart-${Date.now()}`;
await fs.ensureDir(backupDir);
// Backup critical files
const filesToBackup = [
'.agentic-qe/config/fleet.json',
'.agentic-qe/config/agents.json',
'.agentic-qe/data/registry.json'
];
for (const file of filesToBackup) {
if (await fs.pathExists(file)) {
const fileName = file.split('/').pop();
await fs.copy(file, `${backupDir}/${fileName}`);
}
}
console.log(chalk_1.default.gray(` Backup saved: ${backupDir}`));
}
static async updateFleetStatus(status) {
const fleetConfig = await fs.readJson('.agentic-qe/config/fleet.json');
fleetConfig.status = status;
fleetConfig.lastStatusUpdate = new Date().toISOString();
await fs.writeJson('.agentic-qe/config/fleet.json', fleetConfig, { spaces: 2 });
// Update registry
if (await fs.pathExists('.agentic-qe/data/registry.json')) {
const registry = await fs.readJson('.agentic-qe/data/registry.json');
registry.fleet = registry.fleet || {};
registry.fleet.status = status;
await fs.writeJson('.agentic-qe/data/registry.json', registry, { spaces: 2 });
}
}
static async gracefulStop() {
console.log(chalk_1.default.blue('๐ Stopping agents gracefully...'));
// Load registry
if (await fs.pathExists('.agentic-qe/data/registry.json')) {
const registry = await fs.readJson('.agentic-qe/data/registry.json');
const runningTasks = registry.tasks?.filter((t) => t.status === 'running') || [];
if (runningTasks.length > 0) {
console.log(chalk_1.default.yellow(` Waiting for ${runningTasks.length} running tasks to complete...`));
// In production, this would actually wait for tasks
// Simulate waiting
await new Promise(resolve => setTimeout(resolve, 2000));
}
// Update agent statuses
if (registry.agents) {
registry.agents.forEach((agent) => {
agent.status = 'stopped';
agent.stoppedAt = new Date().toISOString();
});
await fs.writeJson('.agentic-qe/data/registry.json', registry, { spaces: 2 });
}
}
console.log(chalk_1.default.gray(' All agents stopped gracefully'));
}
static async forceStop() {
console.log(chalk_1.default.yellow('โ ๏ธ Force stopping all agents...'));
// Load registry and force stop
if (await fs.pathExists('.agentic-qe/data/registry.json')) {
const registry = await fs.readJson('.agentic-qe/data/registry.json');
if (registry.agents) {
registry.agents.forEach((agent) => {
agent.status = 'stopped';
agent.forceStopped = true;
agent.stoppedAt = new Date().toISOString();
});
// Mark running tasks as interrupted
if (registry.tasks) {
registry.tasks.forEach((task) => {
if (task.status === 'running') {
task.status = 'interrupted';
task.interruptedAt = new Date().toISOString();
}
});
}
await fs.writeJson('.agentic-qe/data/registry.json', registry, { spaces: 2 });
}
}
console.log(chalk_1.default.gray(' All agents force stopped'));
}
static async clearRuntimeData() {
console.log(chalk_1.default.blue('๐งน Clearing runtime data...'));
// Clear temporary execution data
const tempDirs = [
'.agentic-qe/tmp',
'.agentic-qe/cache'
];
for (const dir of tempDirs) {
if (await fs.pathExists(dir)) {
await fs.remove(dir);
await fs.ensureDir(dir);
}
}
console.log(chalk_1.default.gray(' Runtime data cleared'));
}
static async restartAgents(fleetConfig) {
console.log(chalk_1.default.blue('๐ Restarting agents...'));
// Generate restart script
const restartScript = `#!/bin/bash
# Fleet Restart Script
echo "Restarting Agentic QE Fleet..."
# Pre-restart coordination
npx claude-flow@alpha hooks notify --message "Fleet restart initiated"
# Reinitialize agents
echo "Reinitializing ${fleetConfig.maxAgents} agents..."
# Restore coordination
npx claude-flow@alpha hooks session-restore --session-id "fleet-restart"
# Post-restart validation
echo "Validating agent status..."
npx claude-flow@alpha hooks notify --message "Fleet restart completed"
echo "Fleet restarted successfully!"
`;
await fs.ensureDir('.agentic-qe/scripts');
await fs.writeFile('.agentic-qe/scripts/restart-fleet.sh', restartScript);
await fs.chmod('.agentic-qe/scripts/restart-fleet.sh', '755');
// Update registry with restarted agents
if (await fs.pathExists('.agentic-qe/data/registry.json')) {
const registry = await fs.readJson('.agentic-qe/data/registry.json');
if (registry.agents) {
registry.agents.forEach((agent) => {
agent.status = 'active';
agent.restartedAt = new Date().toISOString();
agent.restartCount = (agent.restartCount || 0) + 1;
});
await fs.writeJson('.agentic-qe/data/registry.json', registry, { spaces: 2 });
}
}
console.log(chalk_1.default.gray(` ${fleetConfig.maxAgents} agents restarted`));
}
static async verifyRestart() {
console.log(chalk_1.default.blue('โ
Verifying restart...'));
// Check if fleet configuration is intact
if (!await fs.pathExists('.agentic-qe/config/fleet.json')) {
console.log(chalk_1.default.red(' โ Fleet configuration missing'));
return false;
}
// Check if agents are active
if (await fs.pathExists('.agentic-qe/data/registry.json')) {
const registry = await fs.readJson('.agentic-qe/data/registry.json');
const activeAgents = registry.agents?.filter((a) => a.status === 'active').length || 0;
if (activeAgents === 0) {
console.log(chalk_1.default.red(' โ No active agents after restart'));
return false;
}
console.log(chalk_1.default.green(` โ
${activeAgents} agents active`));
}
return true;
}
static async rollbackRestart() {
console.log(chalk_1.default.yellow('๐ Rolling back restart...'));
// Find latest backup
const backupsDir = '.agentic-qe/backups';
if (await fs.pathExists(backupsDir)) {
const backups = await fs.readdir(backupsDir);
const restartBackups = backups
.filter(b => b.startsWith('restart-'))
.sort()
.reverse();
if (restartBackups.length > 0) {
const latestBackup = `${backupsDir}/${restartBackups[0]}`;
// Restore files
const files = await fs.readdir(latestBackup);
for (const file of files) {
const source = `${latestBackup}/${file}`;
let dest = '';
if (file === 'fleet.json') {
dest = '.agentic-qe/config/fleet.json';
}
else if (file === 'agents.json') {
dest = '.agentic-qe/config/agents.json';
}
else if (file === 'registry.json') {
dest = '.agentic-qe/data/registry.json';
}
if (dest) {
await fs.copy(source, dest, { overwrite: true });
}
}
console.log(chalk_1.default.green(' โ
Rollback completed'));
}
}
}
static async storeRestartOperation(mode, success) {
try {
const { execSync } = require('child_process');
const data = JSON.stringify({
mode,
success,
timestamp: new Date().toISOString()
});
const command = `npx claude-flow@alpha memory store --key "aqe/swarm/fleet-cli-commands/restart" --value '${data}'`;
execSync(command, { stdio: 'ignore', timeout: 5000 });
}
catch (error) {
// Silently handle coordination errors
}
}
}
exports.FleetRestartCommand = FleetRestartCommand;
//# sourceMappingURL=restart.js.map