vibe-coder-mcp
Version:
Production-ready MCP server with complete agent integration, multi-transport support, and comprehensive development automation tools for AI-assisted workflows.
176 lines (175 loc) • 7.03 kB
JavaScript
import { ImportCycleBreaker } from '../utils/import-cycle-breaker.js';
import logger from '../logger.js';
export class DependencyContainer {
static instance;
static isInitializing = false;
dependencies = {};
initializationPromises = new Map();
static getInstance() {
if (DependencyContainer.isInitializing) {
logger.warn('Circular initialization detected in DependencyContainer, using safe fallback');
return DependencyContainer.createSafeFallback();
}
if (!DependencyContainer.instance) {
DependencyContainer.isInitializing = true;
try {
DependencyContainer.instance = new DependencyContainer();
}
finally {
DependencyContainer.isInitializing = false;
}
}
return DependencyContainer.instance;
}
static createSafeFallback() {
const fallback = Object.create(DependencyContainer.prototype);
fallback.dependencies = {};
fallback.initializationPromises = new Map();
fallback.getAgentRegistry = async () => null;
fallback.getAgentTaskQueue = async () => null;
fallback.getAgentResponseProcessor = async () => null;
fallback.getAgentIntegrationBridge = async () => null;
return fallback;
}
async getAgentRegistry() {
if (this.dependencies.agentRegistry) {
return this.dependencies.agentRegistry;
}
if (this.initializationPromises.has('agentRegistry')) {
return this.initializationPromises.get('agentRegistry');
}
const initPromise = this.initializeAgentRegistry();
this.initializationPromises.set('agentRegistry', initPromise);
try {
const registry = await initPromise;
this.dependencies.agentRegistry = registry;
return registry;
}
finally {
this.initializationPromises.delete('agentRegistry');
}
}
async initializeAgentRegistry() {
try {
const registryModule = await ImportCycleBreaker.safeImport('../tools/agent-registry/index.js');
if (registryModule?.AgentRegistry) {
return registryModule.AgentRegistry.getInstance();
}
logger.warn('AgentRegistry not available due to circular dependency');
return null;
}
catch (error) {
logger.error('Failed to initialize AgentRegistry:', error);
return null;
}
}
async getAgentTaskQueue() {
if (this.dependencies.agentTaskQueue) {
return this.dependencies.agentTaskQueue;
}
if (this.initializationPromises.has('agentTaskQueue')) {
return this.initializationPromises.get('agentTaskQueue');
}
const initPromise = this.initializeAgentTaskQueue();
this.initializationPromises.set('agentTaskQueue', initPromise);
try {
const taskQueue = await initPromise;
this.dependencies.agentTaskQueue = taskQueue;
return taskQueue;
}
finally {
this.initializationPromises.delete('agentTaskQueue');
}
}
async initializeAgentTaskQueue() {
try {
const taskQueueModule = await ImportCycleBreaker.safeImport('../tools/agent-tasks/index.js');
if (taskQueueModule?.AgentTaskQueue) {
return taskQueueModule.AgentTaskQueue.getInstance();
}
logger.warn('AgentTaskQueue not available due to circular dependency');
return null;
}
catch (error) {
logger.error('Failed to initialize AgentTaskQueue:', error);
return null;
}
}
async getAgentResponseProcessor() {
if (this.dependencies.agentResponseProcessor) {
return this.dependencies.agentResponseProcessor;
}
if (this.initializationPromises.has('agentResponseProcessor')) {
return this.initializationPromises.get('agentResponseProcessor');
}
const initPromise = this.initializeAgentResponseProcessor();
this.initializationPromises.set('agentResponseProcessor', initPromise);
try {
const responseProcessor = await initPromise;
this.dependencies.agentResponseProcessor = responseProcessor;
return responseProcessor;
}
finally {
this.initializationPromises.delete('agentResponseProcessor');
}
}
async initializeAgentResponseProcessor() {
try {
const responseModule = await ImportCycleBreaker.safeImport('../tools/agent-response/index.js');
if (responseModule?.AgentResponseProcessor) {
return responseModule.AgentResponseProcessor.getInstance();
}
logger.warn('AgentResponseProcessor not available due to circular dependency');
return null;
}
catch (error) {
logger.error('Failed to initialize AgentResponseProcessor:', error);
return null;
}
}
async getAgentIntegrationBridge() {
if (this.dependencies.agentIntegrationBridge) {
return this.dependencies.agentIntegrationBridge;
}
if (this.initializationPromises.has('agentIntegrationBridge')) {
return this.initializationPromises.get('agentIntegrationBridge');
}
const initPromise = this.initializeAgentIntegrationBridge();
this.initializationPromises.set('agentIntegrationBridge', initPromise);
try {
const bridge = await initPromise;
this.dependencies.agentIntegrationBridge = bridge;
return bridge;
}
finally {
this.initializationPromises.delete('agentIntegrationBridge');
}
}
async initializeAgentIntegrationBridge() {
try {
const bridgeModule = await ImportCycleBreaker.safeImport('../tools/vibe-task-manager/services/agent-integration-bridge.js');
if (bridgeModule?.AgentIntegrationBridge) {
return bridgeModule.AgentIntegrationBridge.getInstance();
}
logger.warn('AgentIntegrationBridge not available due to circular dependency');
return null;
}
catch (error) {
logger.error('Failed to initialize AgentIntegrationBridge:', error);
return null;
}
}
clearCache() {
this.dependencies = {};
this.initializationPromises.clear();
}
getDependencyStatus() {
return {
agentRegistry: !!this.dependencies.agentRegistry,
agentTaskQueue: !!this.dependencies.agentTaskQueue,
agentResponseProcessor: !!this.dependencies.agentResponseProcessor,
agentIntegrationBridge: !!this.dependencies.agentIntegrationBridge
};
}
}
export const dependencyContainer = DependencyContainer.getInstance();