Move src/ → apps/server/ and packages/web/ → apps/web/ to adopt standard monorepo conventions (apps/ for runnable apps, packages/ for reusable libraries). Update all config files, shared package imports, test fixtures, and documentation to reflect new paths. Key fixes: - Update workspace config to ["apps/*", "packages/*"] - Update tsconfig.json rootDir/include for apps/server/ - Add apps/web/** to vitest exclude list - Update drizzle.config.ts schema path - Fix ensure-schema.ts migration path detection (3 levels up in dev, 2 levels up in dist) - Fix tests/integration/cli-server.test.ts import paths - Update packages/shared imports to apps/server/ paths - Update all docs/ files with new paths
267 lines
8.6 KiB
TypeScript
267 lines
8.6 KiB
TypeScript
/**
|
|
* Dependency Container
|
|
*
|
|
* Factory functions for creating the full dependency graph.
|
|
* Keeps startServer() thin and makes repo wiring reusable by the test harness.
|
|
*/
|
|
|
|
import type { DrizzleDatabase } from './db/index.js';
|
|
import {
|
|
createDatabase,
|
|
ensureSchema,
|
|
DrizzleInitiativeRepository,
|
|
DrizzlePhaseRepository,
|
|
DrizzleTaskRepository,
|
|
DrizzleMessageRepository,
|
|
DrizzleAgentRepository,
|
|
DrizzlePageRepository,
|
|
DrizzleProjectRepository,
|
|
DrizzleAccountRepository,
|
|
DrizzleChangeSetRepository,
|
|
DrizzleLogChunkRepository,
|
|
DrizzleConversationRepository,
|
|
} from './db/index.js';
|
|
import type { InitiativeRepository } from './db/repositories/initiative-repository.js';
|
|
import type { PhaseRepository } from './db/repositories/phase-repository.js';
|
|
import type { TaskRepository } from './db/repositories/task-repository.js';
|
|
import type { MessageRepository } from './db/repositories/message-repository.js';
|
|
import type { AgentRepository } from './db/repositories/agent-repository.js';
|
|
import type { PageRepository } from './db/repositories/page-repository.js';
|
|
import type { ProjectRepository } from './db/repositories/project-repository.js';
|
|
import type { AccountRepository } from './db/repositories/account-repository.js';
|
|
import type { ChangeSetRepository } from './db/repositories/change-set-repository.js';
|
|
import type { LogChunkRepository } from './db/repositories/log-chunk-repository.js';
|
|
import type { ConversationRepository } from './db/repositories/conversation-repository.js';
|
|
import type { EventBus } from './events/index.js';
|
|
import { createEventBus } from './events/index.js';
|
|
import { ProcessManager, ProcessRegistry } from './process/index.js';
|
|
import { LogManager } from './logging/index.js';
|
|
import { MultiProviderAgentManager } from './agent/index.js';
|
|
import { DefaultAccountCredentialManager } from './agent/credentials/index.js';
|
|
import type { AccountCredentialManager } from './agent/credentials/types.js';
|
|
import { DefaultDispatchManager } from './dispatch/manager.js';
|
|
import { DefaultPhaseDispatchManager } from './dispatch/phase-manager.js';
|
|
import type { DispatchManager, PhaseDispatchManager } from './dispatch/types.js';
|
|
import { SimpleGitBranchManager } from './git/simple-git-branch-manager.js';
|
|
import type { BranchManager } from './git/branch-manager.js';
|
|
import { ExecutionOrchestrator } from './execution/orchestrator.js';
|
|
import { DefaultConflictResolutionService } from './coordination/conflict-resolution-service.js';
|
|
import { PreviewManager } from './preview/index.js';
|
|
import { findWorkspaceRoot } from './config/index.js';
|
|
import { createModuleLogger } from './logger/index.js';
|
|
import type { ServerContextDeps } from './server/index.js';
|
|
|
|
// =============================================================================
|
|
// Repositories
|
|
// =============================================================================
|
|
|
|
/**
|
|
* All 11 repository ports.
|
|
*/
|
|
export interface Repositories {
|
|
initiativeRepository: InitiativeRepository;
|
|
phaseRepository: PhaseRepository;
|
|
taskRepository: TaskRepository;
|
|
messageRepository: MessageRepository;
|
|
agentRepository: AgentRepository;
|
|
pageRepository: PageRepository;
|
|
projectRepository: ProjectRepository;
|
|
accountRepository: AccountRepository;
|
|
changeSetRepository: ChangeSetRepository;
|
|
logChunkRepository: LogChunkRepository;
|
|
conversationRepository: ConversationRepository;
|
|
}
|
|
|
|
/**
|
|
* Create all 11 Drizzle repository adapters from a database instance.
|
|
* Reusable by both the production server and the test harness.
|
|
*/
|
|
export function createRepositories(db: DrizzleDatabase): Repositories {
|
|
return {
|
|
initiativeRepository: new DrizzleInitiativeRepository(db),
|
|
phaseRepository: new DrizzlePhaseRepository(db),
|
|
taskRepository: new DrizzleTaskRepository(db),
|
|
messageRepository: new DrizzleMessageRepository(db),
|
|
agentRepository: new DrizzleAgentRepository(db),
|
|
pageRepository: new DrizzlePageRepository(db),
|
|
projectRepository: new DrizzleProjectRepository(db),
|
|
accountRepository: new DrizzleAccountRepository(db),
|
|
changeSetRepository: new DrizzleChangeSetRepository(db),
|
|
logChunkRepository: new DrizzleLogChunkRepository(db),
|
|
conversationRepository: new DrizzleConversationRepository(db),
|
|
};
|
|
}
|
|
|
|
// =============================================================================
|
|
// Container
|
|
// =============================================================================
|
|
|
|
/**
|
|
* Full dependency graph for the coordination server.
|
|
*/
|
|
export interface Container extends Repositories {
|
|
db: DrizzleDatabase;
|
|
eventBus: EventBus;
|
|
processManager: ProcessManager;
|
|
logManager: LogManager;
|
|
workspaceRoot: string;
|
|
credentialManager: AccountCredentialManager;
|
|
agentManager: MultiProviderAgentManager;
|
|
dispatchManager: DispatchManager;
|
|
phaseDispatchManager: PhaseDispatchManager;
|
|
branchManager: BranchManager;
|
|
executionOrchestrator: ExecutionOrchestrator;
|
|
previewManager: PreviewManager;
|
|
|
|
/** Extract the subset of deps that CoordinationServer needs. */
|
|
toContextDeps(): ServerContextDeps;
|
|
}
|
|
|
|
/**
|
|
* Options for container creation.
|
|
*/
|
|
export interface ContainerOptions {
|
|
debug?: boolean;
|
|
}
|
|
|
|
/**
|
|
* Create the full dependency container.
|
|
*
|
|
* Wires: ProcessRegistry → EventBus → ProcessManager → LogManager →
|
|
* Database → Repositories → CredentialManager → AgentManager.
|
|
* Runs ensureSchema() and reconcileAfterRestart() before returning.
|
|
*/
|
|
export async function createContainer(options?: ContainerOptions): Promise<Container> {
|
|
const log = createModuleLogger('container');
|
|
|
|
// Infrastructure
|
|
const registry = new ProcessRegistry();
|
|
const eventBus = createEventBus();
|
|
const processManager = new ProcessManager(registry, eventBus);
|
|
const logManager = new LogManager();
|
|
|
|
// Database
|
|
const db = createDatabase();
|
|
ensureSchema(db);
|
|
log.info('database initialized');
|
|
|
|
// Repositories
|
|
const repos = createRepositories(db);
|
|
log.info('repositories created');
|
|
|
|
// Workspace root
|
|
const workspaceRoot = findWorkspaceRoot(process.cwd()) ?? process.cwd();
|
|
log.info({ workspaceRoot }, 'workspace root resolved');
|
|
|
|
// Credential manager
|
|
const credentialManager = new DefaultAccountCredentialManager(eventBus);
|
|
log.info('credential manager created');
|
|
|
|
// Agent manager
|
|
const agentManager = new MultiProviderAgentManager(
|
|
repos.agentRepository,
|
|
workspaceRoot,
|
|
repos.projectRepository,
|
|
repos.accountRepository,
|
|
eventBus,
|
|
credentialManager,
|
|
repos.changeSetRepository,
|
|
repos.phaseRepository,
|
|
repos.taskRepository,
|
|
repos.pageRepository,
|
|
repos.logChunkRepository,
|
|
options?.debug ?? false,
|
|
);
|
|
log.info('agent manager created');
|
|
|
|
// Reconcile agent state from any previous server session
|
|
await agentManager.reconcileAfterRestart();
|
|
log.info('agent reconciliation complete');
|
|
|
|
// Branch manager
|
|
const branchManager = new SimpleGitBranchManager();
|
|
log.info('branch manager created');
|
|
|
|
// Dispatch managers
|
|
const dispatchManager = new DefaultDispatchManager(
|
|
repos.taskRepository,
|
|
repos.messageRepository,
|
|
agentManager,
|
|
eventBus,
|
|
repos.initiativeRepository,
|
|
repos.phaseRepository,
|
|
);
|
|
const phaseDispatchManager = new DefaultPhaseDispatchManager(
|
|
repos.phaseRepository,
|
|
repos.taskRepository,
|
|
dispatchManager,
|
|
eventBus,
|
|
repos.initiativeRepository,
|
|
repos.projectRepository,
|
|
branchManager,
|
|
workspaceRoot,
|
|
);
|
|
log.info('dispatch managers created');
|
|
|
|
// Conflict resolution service (for orchestrator)
|
|
const conflictResolutionService = new DefaultConflictResolutionService(
|
|
repos.taskRepository,
|
|
repos.agentRepository,
|
|
repos.messageRepository,
|
|
eventBus,
|
|
);
|
|
|
|
// Execution orchestrator
|
|
const executionOrchestrator = new ExecutionOrchestrator(
|
|
branchManager,
|
|
repos.phaseRepository,
|
|
repos.taskRepository,
|
|
repos.initiativeRepository,
|
|
repos.projectRepository,
|
|
phaseDispatchManager,
|
|
conflictResolutionService,
|
|
eventBus,
|
|
workspaceRoot,
|
|
);
|
|
executionOrchestrator.start();
|
|
log.info('execution orchestrator started');
|
|
|
|
// Preview manager
|
|
const previewManager = new PreviewManager(
|
|
repos.projectRepository,
|
|
eventBus,
|
|
workspaceRoot,
|
|
);
|
|
log.info('preview manager created');
|
|
|
|
return {
|
|
db,
|
|
eventBus,
|
|
processManager,
|
|
logManager,
|
|
workspaceRoot,
|
|
credentialManager,
|
|
agentManager,
|
|
dispatchManager,
|
|
phaseDispatchManager,
|
|
branchManager,
|
|
executionOrchestrator,
|
|
previewManager,
|
|
...repos,
|
|
|
|
toContextDeps(): ServerContextDeps {
|
|
return {
|
|
agentManager,
|
|
credentialManager,
|
|
dispatchManager,
|
|
phaseDispatchManager,
|
|
branchManager,
|
|
executionOrchestrator,
|
|
previewManager,
|
|
workspaceRoot,
|
|
...repos,
|
|
};
|
|
},
|
|
};
|
|
}
|