vibe-coder-mcp
Version:
Production-ready MCP server with complete agent integration, multi-transport support, and comprehensive development automation tools for AI-assisted workflows.
608 lines (607 loc) • 23 kB
JavaScript
import { ProjectStorage } from './project-storage.js';
import { TaskStorage } from './task-storage.js';
import { DependencyStorage } from './dependency-storage.js';
import { UnifiedStorageEngine, createDefaultStorageConfig } from '../unified-storage-engine.js';
import { getVibeTaskManagerConfig, getVibeTaskManagerOutputDir } from '../../utils/config-loader.js';
import logger from '../../../../logger.js';
export class StorageManager {
static instance;
unifiedEngine;
projectStorage;
taskStorage;
dependencyStorage;
dataDirectory;
initialized = false;
useUnifiedEngine = true;
constructor(dataDirectory) {
this.dataDirectory = dataDirectory || getVibeTaskManagerOutputDir();
const config = {
...createDefaultStorageConfig(),
dataDirectory: this.dataDirectory,
cache: {
enabled: true,
maxSize: 1000,
ttlSeconds: 3600,
compressionEnabled: false,
persistToDisk: true
},
backup: {
enabled: true,
intervalMinutes: 60,
maxBackups: 10,
compressionEnabled: true,
encryptionEnabled: false,
remoteBackupEnabled: false
},
monitoring: {
enableMetrics: true,
metricsInterval: 30,
enableAuditLog: true,
enablePerformanceTracking: true
}
};
this.unifiedEngine = UnifiedStorageEngine.getInstance(config);
this.projectStorage = new ProjectStorage(this.dataDirectory);
this.taskStorage = new TaskStorage(this.dataDirectory);
this.dependencyStorage = new DependencyStorage(this.dataDirectory);
}
static getInstance(dataDirectory) {
if (!StorageManager.instance) {
StorageManager.instance = new StorageManager(dataDirectory);
}
return StorageManager.instance;
}
async initialize() {
if (this.initialized) {
return {
success: true,
metadata: {
filePath: this.dataDirectory,
operation: 'initialize',
timestamp: new Date()
}
};
}
try {
logger.info({ dataDirectory: this.dataDirectory }, 'Initializing storage manager');
if (this.useUnifiedEngine) {
const initResult = await this.unifiedEngine.initialize();
if (!initResult.success) {
logger.error({ error: initResult.error }, 'Failed to initialize unified storage engine');
return {
success: false,
error: `Failed to initialize unified storage engine: ${initResult.error.message}`,
metadata: {
filePath: this.dataDirectory,
operation: 'initialize',
timestamp: new Date()
}
};
}
logger.info('StorageManager initialized with UnifiedStorageEngine');
}
else {
const config = await getVibeTaskManagerConfig();
if (config?.taskManager?.dataDirectory) {
this.dataDirectory = config.taskManager.dataDirectory;
this.projectStorage = new ProjectStorage(this.dataDirectory);
this.taskStorage = new TaskStorage(this.dataDirectory);
this.dependencyStorage = new DependencyStorage(this.dataDirectory);
}
const projectInitResult = await this.projectStorage.initialize();
if (!projectInitResult.success) {
return {
success: false,
error: `Failed to initialize project storage: ${projectInitResult.error}`,
metadata: projectInitResult.metadata
};
}
const taskInitResult = await this.taskStorage.initialize();
if (!taskInitResult.success) {
return {
success: false,
error: `Failed to initialize task storage: ${taskInitResult.error}`,
metadata: taskInitResult.metadata
};
}
const dependencyInitResult = await this.dependencyStorage.initialize();
if (!dependencyInitResult.success) {
return {
success: false,
error: `Failed to initialize dependency storage: ${dependencyInitResult.error}`,
metadata: dependencyInitResult.metadata
};
}
logger.info('StorageManager initialized with legacy storage');
}
this.initialized = true;
logger.info({ dataDirectory: this.dataDirectory }, 'Storage manager initialized successfully');
return {
success: true,
metadata: {
filePath: this.dataDirectory,
operation: 'initialize',
timestamp: new Date()
}
};
}
catch (error) {
logger.error({ err: error, dataDirectory: this.dataDirectory }, 'Failed to initialize storage manager');
return {
success: false,
error: error instanceof Error ? error.message : String(error),
metadata: {
filePath: this.dataDirectory,
operation: 'initialize',
timestamp: new Date()
}
};
}
}
async getStorageStats() {
try {
await this.ensureInitialized();
const projectsResult = await this.projectStorage.listProjects();
const tasksResult = await this.taskStorage.listTasks();
const dependenciesResult = await this.dependencyStorage.listDependencies();
const stats = {
projects: projectsResult.success ? projectsResult.data.length : 0,
tasks: tasksResult.success ? tasksResult.data.length : 0,
dependencies: dependenciesResult.success ? dependenciesResult.data.length : 0,
dataDirectory: this.dataDirectory,
initialized: this.initialized
};
return {
success: true,
data: stats,
metadata: {
filePath: this.dataDirectory,
operation: 'get_storage_stats',
timestamp: new Date()
}
};
}
catch (error) {
logger.error({ err: error }, 'Failed to get storage statistics');
return {
success: false,
error: error instanceof Error ? error.message : String(error),
metadata: {
filePath: this.dataDirectory,
operation: 'get_storage_stats',
timestamp: new Date()
}
};
}
}
async ensureInitialized() {
if (!this.initialized) {
const initResult = await this.initialize();
if (!initResult.success) {
throw new Error(`Failed to initialize storage: ${initResult.error}`);
}
}
}
async createProject(project) {
await this.ensureInitialized();
if (this.useUnifiedEngine) {
const result = await this.unifiedEngine.createProject(project);
if (result.success) {
return {
success: true,
data: result.data,
metadata: {
filePath: 'unified-storage-engine',
operation: 'createProject',
timestamp: new Date()
}
};
}
else {
return {
success: false,
error: result.error.message,
metadata: {
filePath: 'unified-storage-engine',
operation: 'createProject',
timestamp: new Date()
}
};
}
}
return this.projectStorage.createProject(project);
}
async getProject(projectId) {
await this.ensureInitialized();
if (this.useUnifiedEngine) {
const result = await this.unifiedEngine.getProject(projectId);
if (result.success) {
return {
success: true,
data: result.data,
metadata: {
filePath: 'unified-storage-engine',
operation: 'getProject',
timestamp: new Date()
}
};
}
else {
return {
success: false,
error: result.error.message,
metadata: {
filePath: 'unified-storage-engine',
operation: 'getProject',
timestamp: new Date()
}
};
}
}
return this.projectStorage.getProject(projectId);
}
async updateProject(projectId, updates) {
await this.ensureInitialized();
if (this.useUnifiedEngine) {
const result = await this.unifiedEngine.updateProject(projectId, updates);
if (result.success) {
return {
success: true,
data: result.data,
metadata: {
filePath: 'unified-storage-engine',
operation: 'updateProject',
timestamp: new Date()
}
};
}
else {
return {
success: false,
error: result.error.message,
metadata: {
filePath: 'unified-storage-engine',
operation: 'updateProject',
timestamp: new Date()
}
};
}
}
return this.projectStorage.updateProject(projectId, updates);
}
async deleteProject(projectId) {
await this.ensureInitialized();
if (this.useUnifiedEngine) {
const result = await this.unifiedEngine.deleteProject(projectId);
if (result.success) {
return {
success: true,
metadata: {
filePath: 'unified-storage-engine',
operation: 'deleteProject',
timestamp: new Date()
}
};
}
else {
return {
success: false,
error: result.error.message,
metadata: {
filePath: 'unified-storage-engine',
operation: 'deleteProject',
timestamp: new Date()
}
};
}
}
const tasksResult = await this.taskStorage.listTasks(projectId);
if (tasksResult.success) {
for (const task of tasksResult.data) {
await this.taskStorage.deleteTask(task.id);
}
}
const dependenciesResult = await this.dependencyStorage.listDependencies(projectId);
if (dependenciesResult.success) {
for (const dependency of dependenciesResult.data) {
await this.dependencyStorage.deleteDependency(dependency.id);
}
}
await this.dependencyStorage.deleteDependencyGraph(projectId);
return this.projectStorage.deleteProject(projectId);
}
async listProjects() {
await this.ensureInitialized();
if (this.useUnifiedEngine) {
const result = await this.unifiedEngine.listProjects();
if (result.success) {
return {
success: true,
data: result.data,
metadata: {
filePath: 'unified-storage-engine',
operation: 'listProjects',
timestamp: new Date()
}
};
}
else {
return {
success: false,
error: result.error.message,
metadata: {
filePath: 'unified-storage-engine',
operation: 'listProjects',
timestamp: new Date()
}
};
}
}
return this.projectStorage.listProjects();
}
async projectExists(projectId) {
await this.ensureInitialized();
if (this.useUnifiedEngine) {
return this.unifiedEngine.projectExists(projectId);
}
return this.projectStorage.projectExists(projectId);
}
async getProjectsByStatus(status) {
await this.ensureInitialized();
return this.projectStorage.getProjectsByStatus(status);
}
async searchProjects(query) {
await this.ensureInitialized();
return this.projectStorage.searchProjects(query);
}
async createTask(task) {
await this.ensureInitialized();
if (this.useUnifiedEngine) {
const result = await this.unifiedEngine.createTask(task);
if (result.success) {
return {
success: true,
data: result.data,
metadata: {
filePath: 'unified-storage-engine',
operation: 'createTask',
timestamp: new Date()
}
};
}
else {
return {
success: false,
error: result.error.message,
metadata: {
filePath: 'unified-storage-engine',
operation: 'createTask',
timestamp: new Date()
}
};
}
}
return this.taskStorage.createTask(task);
}
async getTask(taskId) {
await this.ensureInitialized();
if (this.useUnifiedEngine) {
const result = await this.unifiedEngine.getTask(taskId);
if (result.success) {
return {
success: true,
data: result.data,
metadata: {
filePath: 'unified-storage-engine',
operation: 'getTask',
timestamp: new Date()
}
};
}
else {
return {
success: false,
error: result.error.message,
metadata: {
filePath: 'unified-storage-engine',
operation: 'getTask',
timestamp: new Date()
}
};
}
}
return this.taskStorage.getTask(taskId);
}
async updateTask(taskId, updates) {
await this.ensureInitialized();
if (this.useUnifiedEngine) {
const result = await this.unifiedEngine.updateTask(taskId, updates);
if (result.success) {
return {
success: true,
data: result.data,
metadata: {
filePath: 'unified-storage-engine',
operation: 'updateTask',
timestamp: new Date()
}
};
}
else {
return {
success: false,
error: result.error.message,
metadata: {
filePath: 'unified-storage-engine',
operation: 'updateTask',
timestamp: new Date()
}
};
}
}
return this.taskStorage.updateTask(taskId, updates);
}
async deleteTask(taskId) {
await this.ensureInitialized();
if (this.useUnifiedEngine) {
const result = await this.unifiedEngine.deleteTask(taskId);
if (result.success) {
return {
success: true,
metadata: {
filePath: 'unified-storage-engine',
operation: 'deleteTask',
timestamp: new Date()
}
};
}
else {
return {
success: false,
error: result.error.message,
metadata: {
filePath: 'unified-storage-engine',
operation: 'deleteTask',
timestamp: new Date()
}
};
}
}
const dependenciesResult = await this.dependencyStorage.getDependenciesForTask(taskId);
if (dependenciesResult.success) {
for (const dependency of dependenciesResult.data) {
await this.dependencyStorage.deleteDependency(dependency.id);
}
}
const dependentsResult = await this.dependencyStorage.getDependentsForTask(taskId);
if (dependentsResult.success) {
for (const dependent of dependentsResult.data) {
await this.dependencyStorage.deleteDependency(dependent.id);
}
}
return this.taskStorage.deleteTask(taskId);
}
async listTasks(projectId, epicId) {
await this.ensureInitialized();
if (this.useUnifiedEngine) {
const result = await this.unifiedEngine.listTasks(projectId);
if (result.success) {
return {
success: true,
data: result.data,
metadata: {
filePath: 'unified-storage-engine',
operation: 'listTasks',
timestamp: new Date()
}
};
}
else {
return {
success: false,
error: result.error.message,
metadata: {
filePath: 'unified-storage-engine',
operation: 'listTasks',
timestamp: new Date()
}
};
}
}
return this.taskStorage.listTasks(projectId, epicId);
}
async getTasksByStatus(status, projectId) {
await this.ensureInitialized();
return this.taskStorage.getTasksByStatus(status, projectId);
}
async getTasksByPriority(priority, projectId) {
await this.ensureInitialized();
return this.taskStorage.getTasksByPriority(priority, projectId);
}
async searchTasks(query, projectId) {
await this.ensureInitialized();
return this.taskStorage.searchTasks(query, projectId);
}
async taskExists(taskId) {
await this.ensureInitialized();
return this.taskStorage.taskExists(taskId);
}
async createEpic(epic) {
await this.ensureInitialized();
return this.taskStorage.createEpic(epic);
}
async getEpic(epicId) {
await this.ensureInitialized();
return this.taskStorage.getEpic(epicId);
}
async updateEpic(epicId, updates) {
await this.ensureInitialized();
return this.taskStorage.updateEpic(epicId, updates);
}
async deleteEpic(epicId) {
await this.ensureInitialized();
return this.taskStorage.deleteEpic(epicId);
}
async listEpics(projectId) {
await this.ensureInitialized();
return this.taskStorage.listEpics(projectId);
}
async epicExists(epicId) {
await this.ensureInitialized();
return this.taskStorage.epicExists(epicId);
}
async createDependency(dependency) {
await this.ensureInitialized();
return this.dependencyStorage.createDependency(dependency);
}
async getDependency(dependencyId) {
await this.ensureInitialized();
return this.dependencyStorage.getDependency(dependencyId);
}
async updateDependency(dependencyId, updates) {
await this.ensureInitialized();
return this.dependencyStorage.updateDependency(dependencyId, updates);
}
async deleteDependency(dependencyId) {
await this.ensureInitialized();
return this.dependencyStorage.deleteDependency(dependencyId);
}
async listDependencies(projectId) {
await this.ensureInitialized();
return this.dependencyStorage.listDependencies(projectId);
}
async getDependenciesForTask(taskId) {
await this.ensureInitialized();
return this.dependencyStorage.getDependenciesForTask(taskId);
}
async getDependentsForTask(taskId) {
await this.ensureInitialized();
return this.dependencyStorage.getDependentsForTask(taskId);
}
async dependencyExists(dependencyId) {
await this.ensureInitialized();
return this.dependencyStorage.dependencyExists(dependencyId);
}
async saveDependencyGraph(projectId, graph) {
await this.ensureInitialized();
return this.dependencyStorage.saveDependencyGraph(projectId, graph);
}
async loadDependencyGraph(projectId) {
await this.ensureInitialized();
return this.dependencyStorage.loadDependencyGraph(projectId);
}
async deleteDependencyGraph(projectId) {
await this.ensureInitialized();
return this.dependencyStorage.deleteDependencyGraph(projectId);
}
}
export async function getStorageManager() {
const config = await getVibeTaskManagerConfig();
const dataDirectory = config?.taskManager?.dataDirectory;
const storageManager = StorageManager.getInstance(dataDirectory);
const initResult = await storageManager.initialize();
if (!initResult.success) {
throw new Error(`Failed to initialize storage manager: ${initResult.error}`);
}
return storageManager;
}