claude-flow-tbowman01
Version:
Enterprise-grade AI agent orchestration with ruv-swarm integration (Alpha Release)
177 lines (151 loc) • 4.8 kB
text/typescript
/**
* JSON-based persistence layer for Claude-Flow
*/
import { join } from 'path';
import { mkdir, access, readFile, writeFile } from 'fs/promises';
export interface PersistedAgent {
id: string;
type: string;
name: string;
status: string;
capabilities: string[];
systemPrompt: string;
maxConcurrentTasks: number;
priority: number;
createdAt: number;
}
export interface PersistedTask {
id: string;
type: string;
description: string;
status: string;
priority: number;
dependencies: string[];
metadata: Record<string, unknown>;
assignedAgent?: string;
progress: number;
error?: string;
createdAt: number;
completedAt?: number;
}
interface PersistenceData {
agents: PersistedAgent[];
tasks: PersistedTask[];
lastUpdated: number;
}
export class JsonPersistenceManager {
private dataPath: string;
private data: PersistenceData;
constructor(dataDir: string = './memory') {
this.dataPath = join(dataDir, 'claude-flow-data.json');
this.data = {
agents: [],
tasks: [],
lastUpdated: Date.now(),
};
}
async initialize(): Promise<void> {
// Ensure directory exists
await mkdir(join(this.dataPath, '..'), { recursive: true });
// Load existing data if available
try {
await access(this.dataPath);
const content = await readFile(this.dataPath, 'utf-8');
this.data = JSON.parse(content);
} catch (error) {
// File doesn't exist or can't be read, keep default empty data
console.error('Failed to load persistence data:', error);
}
}
private async save(): Promise<void> {
this.data.lastUpdated = Date.now();
await writeFile(this.dataPath, JSON.stringify(this.data, null, 2));
}
// Agent operations
async saveAgent(agent: PersistedAgent): Promise<void> {
// Remove existing agent if updating
this.data.agents = this.data.agents.filter((a) => a.id !== agent.id);
this.data.agents.push(agent);
await this.save();
}
async getAgent(id: string): Promise<PersistedAgent | null> {
return this.data.agents.find((a) => a.id === id) || null;
}
async getActiveAgents(): Promise<PersistedAgent[]> {
return this.data.agents.filter((a) => a.status === 'active' || a.status === 'idle');
}
async getAllAgents(): Promise<PersistedAgent[]> {
return this.data.agents;
}
async updateAgentStatus(id: string, status: string): Promise<void> {
const agent = this.data.agents.find((a) => a.id === id);
if (agent) {
agent.status = status;
await this.save();
}
}
// Task operations
async saveTask(task: PersistedTask): Promise<void> {
// Remove existing task if updating
this.data.tasks = this.data.tasks.filter((t) => t.id !== task.id);
this.data.tasks.push(task);
await this.save();
}
async getTask(id: string): Promise<PersistedTask | null> {
return this.data.tasks.find((t) => t.id === id) || null;
}
async getActiveTasks(): Promise<PersistedTask[]> {
return this.data.tasks.filter(
(t) => t.status === 'pending' || t.status === 'in_progress' || t.status === 'assigned',
);
}
async getAllTasks(): Promise<PersistedTask[]> {
return this.data.tasks;
}
async updateTaskStatus(id: string, status: string, assignedAgent?: string): Promise<void> {
const task = this.data.tasks.find((t) => t.id === id);
if (task) {
task.status = status;
if (assignedAgent !== undefined) {
task.assignedAgent = assignedAgent;
}
if (status === 'completed') {
task.completedAt = Date.now();
}
await this.save();
}
}
async updateTaskProgress(id: string, progress: number): Promise<void> {
const task = this.data.tasks.find((t) => t.id === id);
if (task) {
task.progress = progress;
await this.save();
}
}
// Statistics
async getStats(): Promise<{
totalAgents: number;
activeAgents: number;
totalTasks: number;
pendingTasks: number;
completedTasks: number;
}> {
const activeAgents = this.data.agents.filter(
(a) => a.status === 'active' || a.status === 'idle',
).length;
const pendingTasks = this.data.tasks.filter(
(t) => t.status === 'pending' || t.status === 'in_progress' || t.status === 'assigned',
).length;
const completedTasks = this.data.tasks.filter((t) => t.status === 'completed').length;
return {
totalAgents: this.data.agents.length,
activeAgents,
totalTasks: this.data.tasks.length,
pendingTasks,
completedTasks,
};
}
close(): void {
// No-op for JSON persistence
}
}